Mais uma vez sobre a complexidade da arquitetura e o limiar de entrada

Neste artigo, abordarei a questão do limite para entrar em um projeto com uma arquitetura estabelecida e darei várias opções para responder a uma pergunta muito frequente: por que é tão difícil?


Essa pergunta geralmente surge entre os novatos que vêm ao projeto. Ou há situações em que o projeto entra em suporte e desenvolvimento em novas mãos, e o novo desenvolvedor também tem essa pergunta. E raramente, um deles está tentando descobrir as reais razões pelas quais isso acontece aqui e não o contrário. Isso pode levar a conseqüências tristes para os negócios, por exemplo, um novo desenvolvedor pode insistir em reescrever todo o aplicativo do zero.
Para minimizar esses riscos, em vez de perguntar por que é tão difícil? faça essas perguntas:


  • Quais requisitos para o processo de desenvolvimento foram definidos pelo arquiteto?
  • Qual é o resultado do processo de desenvolvimento necessário na saída?

Requisitos do processo de desenvolvimento


Primeiro, o desenvolvedor deve mergulhar no sistema do processo de desenvolvimento, ele deve fazer a seguinte pergunta:


  • Em que sistema o processo é construído?

Freqüentemente, no desenvolvimento personalizado, um projeto com requisitos inequívocos e um conjunto fixo de funcionalidades chega à entrada. Quão bem desenvolvidos eles podem ser - esse é o tópico de outro artigo. E o processo de desenvolvimento nesses projetos geralmente é construído de acordo com um sistema em cascata, porque envolve feedback direto dos usuários do produto - após o desenvolvimento de toda a funcionalidade do produto , enquanto que com um modelo iterativo, o feedback pode ser obtido após a primeira iteração. Para esses projetos, o arquiteto geralmente já possui uma arquitetura estabelecida que atende a certos requisitos para esse processo. Quais são os requisitos para esse processo de desenvolvimento estabelecidos pelo arquiteto?


1) O processo de desenvolvimento do pipeline deve ser o mais complexo possível para o desenvolvedor. E a rejeição do código que entra no repositório do projeto deve ocorrer ao máximo automaticamente e, se possível, sem a participação do próprio arquiteto.


I.e. um pipeline específico deve ser configurado no processo. O código que passou por todo esse pipeline é considerado satisfatório. Isso é muito importante porque um bom arquiteto precisa salvar seus desenvolvedores da dor de cabeça e da responsabilidade de não trabalhar na montagem depois que o código entrar no repositório. Se não houver esse pipeline , seus desenvolvedores sofrerão estresse constante. Se o código entrou no repositório e o pipeline o aceitou, e esse código interrompeu o assembly ou danificou a funcionalidade que já estava funcionando - isso já é um problema do pipeline .


Portanto, nesse pipeline, você deve usar:


  • Muitos analisadores de código estático
  • Testes automatizados e testes de conformidade da pirâmide
  • Cálculo automático de cobertura de código por testes
  • A porta de entrada para a qualidade do código (Quality gates). Para todos os tipos de métricas: porcentagem de cobertura de código com testes, porcentagem de duplicação de código, odores de código, segurança, bugs, etc.
  • revisão de código cruzado
  • etc

Todos esses pontos juntos levam à pergunta do desenvolvedor: por que é tão difícil?


Por exemplo, tente escrever testes para este código:


class SomeService( private val restApi: SomeApi // SomeApi -  ,   ,      ) { fun doSomething(): Single<SomeResult> = restApi.loadSomething() .map { /*-   */ } } 

Você precisará executar esses testes em um dispositivo Android real ou em um emulador. E isso levará imediatamente a um rebaixamento significativo no segundo requisito para o processo de desenvolvimento:


2) Os elementos automatizados do pipeline e o processo de desenvolvimento devem ser executados o mais rápido possível


Se seus desenvolvedores tiverem que esperar muito tempo para que os testes sejam concluídos - este é o problema do seu pipeline e se a arquitetura não permitir acelerar esse processo - este é o problema da sua arquitetura


Vamos reescrever o exemplo:


 interface SomeApi { fun loadSomething(): Single<NetworkResult> } class NetworkSomeApi : SomeApi { override fun loadSomething(): Single<NetworkResult> { /*,    */ } } class SomeService( private val restApi: SomeApi // SomeApi -  ,       ) { /*CODE*/ } 

Vimos que a complexidade do código aumentou, mas do ponto de vista do processo de desenvolvimento - tornamos a arquitetura mais flexível, agora não precisamos executar testes de lógica de negócios para o bloco de map no emulador ou no dispositivo, apenas executá-los em testes rápidos. Isso reduzirá o número de testes de integração que precisam ser executados em um ambiente lento.


O padrão de design escolhido pelo arquiteto pode reduzir o número de caros testes de integração. Não seja preguiçoso e lide com os padrões populares hoje em dia: MVP , MVVM , MVI .


Vamos falar um pouco mais sobre a navegação no aplicativo. Também queremos poder testá-lo e testá-lo em testes rápidos. Novamente, obtemos uma "complicação" da arquitetura, porque precisamos ocultar o sistema de navegação no aplicativo por trás da abstração.


E também queremos poder conectar os componentes do nosso sistema usando o DI, criar gráficos de dependência e verificar sua correção no estágio de compilação do projeto, e não no tempo de execução. Então Dagger 2 e seus monstruosos componentes e subcomponentes com módulos aparecem no palco, o que já confunde o pobre iniciante no final.


E esses momentos não óbvios de "complicação" da arquitetura para iniciantes se acumulam bastante. Naturalmente, sem entender os processos de desenvolvimento e os requisitos para esses processos, eles têm a mesma pergunta - por que é tão difícil?


Resultado do Processo de Desenvolvimento


Para avaliar o sucesso do processo de desenvolvimento interno e, indiretamente, a arquitetura do projeto, é necessário analisar seu resultado. Como regra, o resultado é um produto (um aplicativo, se estamos falando sobre desenvolvimento móvel). E as métricas de sucesso do produto são diferentes para todos: o cliente tem as mesmas métricas, o desenvolvedor tem suas próprias métricas, o usuário do produto tem suas próprias.


No mínimo, você, como arquiteto que cria o pipeline para o processo de desenvolvimento, deve considerar ao avaliar a eficácia do processo de desenvolvimento das métricas e métricas de negócios da sua empresa.


Este é um processo contínuo: desenvolvimento -> coleta de métricas -> análise do resultado -> realização das modificações necessárias no processo de desenvolvimento.


pipeline modification


Assim, o resultado afeta a formação do processo de desenvolvimento e o processo de desenvolvimento já afeta a mudança na arquitetura do projeto. I.e. a idéia importante que quero transmitir é que a arquitetura é secundária, o resultado primário e o processo de desenvolvimento .


Conclusão


Em conclusão, digamos novamente:


  • sem entender os processos de desenvolvimento e os requisitos para esses processos, o desenvolvedor cria um sentimento sobre a arquitetura complicada do projeto;
  • a arquitetura é secundária, resultado primário e processo de desenvolvimento;

Sem entender essas coisas, um desenvolvedor pode querer pegar e reescrever tudo do zero. Na minha opinião, isso se justifica apenas quando o processo e o resultado do desenvolvimento não satisfazem completamente o cliente desse desenvolvimento.


Para iniciantes, aconselho que você inicie um projeto com um pipeline de desenvolvimento refinado. O limiar de entrada em tais projetos é alto, mas, ao passar por isso, você abordará seriamente o entendimento de como os processos de desenvolvimento são construídos.

Source: https://habr.com/ru/post/pt482534/


All Articles