Sou bastante novo nos princípios de design do SOLID . Entendo suas causas e benefícios, mas ainda não os aplico a um projeto menor que quero refatorar como um exercício prático para usar os princípios do SOLID. Sei que não há necessidade de alterar um aplicativo que funcione perfeitamente, mas quero refatorá-lo de qualquer maneira, para ganhar experiência em design para projetos futuros.
O aplicativo tem a seguinte tarefa (na verdade, muito mais do que isso, mas vamos simplificar): Ele deve ler um arquivo XML que contém definições de Tabela de banco de dados / coluna / exibição etc. e criar um arquivo SQL que pode ser usado para criar um esquema de banco de dados ORACLE.
(Observação: evite discutir por que eu preciso ou por que não uso o XSLT e assim por diante, há motivos, mas eles são fora de tópico.)
Para começar, escolhi apenas as tabelas e restrições. Se você ignorar colunas, poderá declarar da seguinte maneira:
Uma restrição faz parte de uma tabela (ou mais precisamente, parte de uma instrução CREATE TABLE) e uma restrição também pode fazer referência a outra tabela.
Primeiro, explicarei como é o aplicativo agora (sem aplicar o SOLID):
No momento, o aplicativo possui uma classe "Tabela" que contém uma lista de ponteiros para Restrições pertencentes à tabela e uma lista de ponteiros para Restrições que fazem referência a esta tabela. Sempre que uma conexão é estabelecida, a conexão reversa também é estabelecida. A tabela possui um método createStatement () que, por sua vez, chama a função createStatement () de cada restrição. O próprio método usará as conexões com a tabela do proprietário e a tabela referenciada para recuperar seus nomes.
Obviamente, isso não se aplica ao SOLID. Por exemplo, existem dependências circulares, que incharam o código em termos dos métodos "add" / "remove" necessários e alguns destruidores de objetos grandes.
Portanto, existem algumas perguntas:
- Devo resolver as dependências circulares usando a injeção de dependência? Nesse caso, suponho que a restrição deve receber a tabela do proprietário (e opcionalmente a referenciada) em seu construtor. Mas como eu poderia passar por cima da lista de restrições para uma única tabela?
- Se a classe Table armazena o estado de si mesmo (por exemplo, nome da tabela, comentário da tabela etc.) e os links para as restrições, essas são uma ou duas "responsabilidades", pensando no princípio de responsabilidade única?
- Caso o caso 2. esteja certo, devo apenas criar uma nova classe na camada lógica de negócios que gerencia os links? Nesse caso, 1. obviamente não seria mais relevante.
- Os métodos "createStatement" devem fazer parte das classes Tabela / Restrição ou devo removê-los também? Se sim, para onde? Uma classe de gerente por cada classe de armazenamento de dados (por exemplo, tabela, restrição, ...)? Ou melhor, criar uma classe de gerente por link (semelhante a 3.)?
Sempre que tento responder a uma dessas perguntas, me vejo correndo em círculos em algum lugar.
Obviamente, o problema fica muito mais complexo se você incluir colunas, índices e assim por diante, mas se vocês me ajudarem com a coisa simples Tabela / Restrição, talvez eu possa resolver o resto por conta própria.