Estamos desenvolvendo um aplicativo com requisitos ligeiramente diferentes para cada mercado comercial (países e estados) do qual ele está disponível. Parece uma situação comum, mas não consigo encontrar um bom artigo sobre a estruturação de códigos / módulos para esse cenário.
É um aplicativo C # e estamos debatendo entre os padrões Estratégia versus Modelo, mas há também a consideração da estrutura de pastas e das convenções de nomenclatura. Parece que um projeto separado para cada estado se tornaria incontrolável rapidamente (por exemplo, 5 serviços principais X 50 projetos personalizados do estado) = 250 projetos !!) Talvez 1 projeto personalizado por serviço que lide com especializações organizadas em subpastas por estado?
8
Respostas:
Tenha um único aplicativo e crie a solução de configuração apropriada.
JacquesB sugere isso, mas quero afirmar com mais força. Você deve fazer isso por configuração, em vez de desenvolver mais de 50 versões da base de código. Qualquer outra coisa será insanamente incontrolável.
Se houver requisitos complexos que não possam ser manipulados por parâmetros de configuração simples, projete uma solução de configuração mais complexa.
Sua configuração pode até ter uma linguagem de script simples que define os requisitos lógicos. Está bem. A chave é que a "configuração" deve estar bem separada da base de código do aplicativo.
Caso contrário, coisas como identificar e corrigir bugs serão uma bagunça. Com a versão normal, além das versões específicas do código do idioma, você terá centenas de versões no campo. E você não será capaz de dizer com facilidade se um bug está relacionado ao código específico da localidade ou ao código base.
Comece a pensar em casos extremos agora.
Essa é uma situação em que há um alto risco de fazer suposições ruins que serão incrivelmente caras. Como "Cada usuário do aplicativo só precisará operar em um local". Isso é verdade? Certifique-se de pensar muito sobre esses problemas o mais cedo possível.
fonte
Realmente depende do que é diferente. É algo que pode ser expresso puramente pela configuração (por exemplo, taxas de imposto) ou você realmente precisa de uma lógica de código separada para cada estado? Quanto mais você puder lidar exclusivamente com a configuração, melhor!
Você provavelmente não precisa de código separado por estado. Por exemplo, você menciona que alguns mercados emitem reembolsos enquanto outros substituem. Ainda são apenas dois caminhos de código que você precisa testar. Em seguida, você pode ter uma configuração indicando qual caminho deve ser usado para qual estado. Isso é muito melhor do que ter um código separado para cada estado. Você ainda precisa testar apenas dois caminhos de código com mais de 50.
Se você sentir necessidade de escrever um código individual para cada um dos 50 estados, provavelmente está fazendo algo errado. Definitivamente, você não deve ter projetos separados por estado, ou mesmo ter "50 diferentes" de qualquer coisa, exceto as seções de configurações.
fonte
Eu tive alguma experiência prática com esses projetos e posso pelo menos oferecer algumas diretrizes gerais.
JacquesB está absolutamente certo de que a configuração é sua melhor amiga. Se você coloca essa configuração em arquivos ou em tabelas de banco de dados, é uma opção estilística (embora eu esteja inclinado a arquivos de configuração, pois uma vez que você cria um serviço, estou disposto a apostar que isso não mudará muito).
Espere um código que pareça muito mais indireto do que você provavelmente está acostumado. Haverá muitos lugares onde, em vez de dizer "Faça isso a seguir", você estará dizendo "Peça à configuração o que devemos fazer a seguir e depois faça isso". O que pode ser uma dor de cabeça no desenvolvimento, mas você vai se acostumar.
Eu recomendaria uma estrutura de "Esses são os elementos comuns que todo mundo provavelmente deseja, e esses são os elementos personalizados, desenhados à mão para estados individuais". Para esse fim, identificar corretamente essa funcionalidade padrão será uma grande parte de quão fácil / terrível o código é trabalhar no futuro. Esteja preparado para fazer alguma refatoração quando descobrir que mais coisas do que você pensava precisam ser configuráveis.
Sempre verifique se as mensagens de erro provenientes dos elementos personalizados identificam exatamente de onde elas vieram. O grande número de caminhos de execução diferentes significa que a depuração será péssima, não importa o quê; qualquer coisa que você possa fazer para reduzir a quantidade de caça aos ovos de páscoa valerá a pena.
Invista tempo para criar um bom conjunto de testes automatizados. Um conjunto de testes automatizado MUITO bom. Essa é sempre uma boa prática, mas, para você, pode significar literalmente a diferença entre sucesso e fracasso. Novamente, é a enorme variedade de caminhos de execução; quaisquer modificações no código comum o deixarão vulnerável a bugs com efeito borboleta em ramos que você não esperava. Você precisa capturar esses bugs antes que eles atinjam a produção.
fonte
ourproject.calculations.tax
com o padrão eourproject.florida.calculations.tax
com os mods personalizados que a lei da Flórida impôs a você (se houver). Onde você coloca esse nome de mercado é um ponto de discussão, mas eu gostaria de facilitar a visualização de quais personalizações um determinado mercado está impondo a você.Embora a configuração possa ajudar a não resolver todos os seus problemas, ela pode criar novos.
De longe, a melhor maneira na minha experiência é criar uma solução de multilocação que possa lidar com todos ou com qualquer um dos estados (inquilinos)
Isso exigirá configuração. ou seja, porcentagem de imposto sobre vendas por estado, mas também código condicional LegalMethodOfCalculatingWorkingHoursA vs B
Se o seu aplicativo estiver hospedado / on-line, você poderá adotar uma abordagem de microsserviços ao código condicional, mas uma solução off-line terá que agrupar todos os módulos opcionais e selecionar entre eles
Você encontrará alguns módulos reutilizados em todos os estados, como impostos sobre vendas e outros legais, usados apenas em um único estado. Você também descobrirá que as leis mudam com o tempo. portanto, os módulos utilizados variam de acordo com o tempo em um único estado
Então, eu iria nomear por funcionalidade e não por estado.
fonte