Estou desenvolvendo um aplicativo que será usado para abrir e fechar válvulas em um ambiente industrial e pensei em algo simples como este: -
public static void ValveController
{
public static void OpenValve(string valveName)
{
// Implementation to open the valve
}
public static void CloseValve(string valveName)
{
// Implementation to close the valve
}
}
(A implementação gravaria alguns bytes de dados na porta serial para controlar a válvula - um "endereço" derivado do nome da válvula e um "1" ou "0" para abrir ou fechar a válvula).
Outro desenvolvedor perguntou se deveríamos criar uma classe separada para cada válvula física, da qual existem dezenas. Concordo que seria melhor escrever código como PlasmaValve.Open()
antes ValveController.OpenValve("plasma")
, mas isso é um exagero?
Além disso, eu estava imaginando a melhor forma de lidar com o design com alguns requisitos futuros hipotéticos em mente: -
- Somos solicitados a apoiar um novo tipo de válvula que exija valores diferentes para abrir e fechar (não 0 e 1).
- Somos solicitados a apoiar uma válvula que pode ser ajustada para qualquer posição de 0 a 100, em vez de simplesmente "aberta" ou "fechada".
Normalmente eu usaria herança para esse tipo de coisa, mas recentemente comecei a entender "composição sobre herança" e me pergunto se há uma solução mais simples usando composição?
fonte
Respostas:
Se cada instância do objeto válvula executasse o mesmo código que este ValveController, parece que várias instâncias de uma única classe seriam o caminho certo a seguir. Nesse caso, apenas configure qual válvula controla (e como) no construtor do objeto da válvula.
No entanto, se cada controle de válvula precisar de um código diferente para ser executado, e o atual ValveController estiver executando uma declaração de chave gigante que faz coisas diferentes dependendo do tipo de válvula, você reimplementou mal o polimorfismo. Nesse caso, reescreva-o em várias classes com uma base comum (se isso fizer sentido) e deixe o princípio de responsabilidade única ser o seu guia de design.
fonte
Minha queixa principal é usar strings para o parâmetro de identificação da válvula.
Pelo menos, crie uma
Valve
classe que possua umgetAddress
na forma que a implementação subjacente precisa e passe-a para a,ValveController
assegurando que você não possa criar válvulas inexistentes. Dessa forma, você não precisará lidar com cadeias de caracteres erradas em cada método de abrir e fechar.Depende de você criar métodos de conveniência que chamam de abertura e fechamento
ValveController
, mas, para ser honesto, manteria toda a comunicação com a porta serial (incluindo a codificação) em uma única classe que outras classes chamarão quando necessário. Isso significa que, quando você precisar migrar para um novo controlador, precisará modificar apenas uma classe.Se você gosta de testar, também deve criar
ValveController
um singleton para poder zombar dele (ou criar uma máquina de treinamento para os operadores).fonte