fbpx
Roadmap de Arquitetura – Um exemplo real

As vezes sou questionado sobre meus desenhos de arquitetura e porque criar tantas abstrações, tanta configuração e tantas dependências e frameworks de terceiros, alguns que só eu e um tibetano conhecemos. No post Como definir Arquitetura de Software, cito quais são os pensamentos primários necessários para se desenhar um arquitetura, mas vamos aplicar isso a um contexto real para exemplificar.

Tudo começa com minha chegada na atual empresa, onde encontrei um cenário extremamente complexo e difícil de se trabalhar.

  • Umas 8 bases de dados (não é exagero), entre SQL Server e MySQL, cada uma seguindo dois ou mais padrões antagônicos (sim, na mesma base), diversos padrões nomenclatura. As bases não possuíam um responsável. Eram “da empresa”, não havia um dono.  O acoplamento do modelo de dados era entre database/tecnologia
    • Esse banco é da galera de PHP
    • Já esse aqui era da galera de .NET,
    • Esse outro é da galera de JAVA.
    • Na prática muitos dados só faziam sentido se mesclados entre databases, entre tecnologias. Era comum precisar consultar 3 ou 4 bases para ter uma entidade completa, quando falávamos de mídia.
  • Alto acoplamento entre as diversas aplicações e suas bases de dados.
  • Acesso a dados
    • Um parque de aplicações baseadas em .net framework 2.0, usando ADO.NET puro para escrever o acesso a dados: Manualmente.
    • Uma quantidade infinita de código de acesso a dados realizando N+1 Anti-Pattern por causa da forma como o acesso a dados era escrito.
  • Gerência de configuração inexistente,
    • Havia um SVN, mas mal era usado para versionar de código.
    • Dezenas de pequenas aplicações resultantes de copy and paste de projetos inteiros.
    • Forks de uma aplicação inicial que realizava um processo batch de importação de conteúdo, extremamente importantes para o business.
    • Muitas delas só rodavam na IDE, em modo debug pois um dev trocava algumas strings e executava em modo supervisionado.
    • Isso não era ao acaso, ou exceção, era a forma como processávamos dados de produção no dia-a-dia.
    • Nenhuma gestão de releases.
    • Centenas (não é exagero) de micro-aplicações responsáveis por micro-tarefas,
      • sem documentação
      • sem identificação
      • Algumas também sem os fontes.
      • Enquanto de um lado havia uma massa de projetos que nunca haviam sido versionados antes, existia também diversos projetos que mesmo sendo versionados, não eram mais atualizados. O código ficava entre máquina do dev e servidor de produção. As vezes nem servidor de produção, porque muitas tarefas de produção eram realizadas a partir da máquina do dev.
  • Todo o conhecimento tecnológico dependia exclusivamente da memória do time ou daqueles que passaram pela equipe e ainda estavam na empresa.

Dá para ver que há muito a se trabalhar nesse lugar. Né?! Ok, assim começamos.

Step 1 – Gerência de Configuração

Primeiro passo foi definir um fluxo geral de gerência de configuração e para isso foram definidas algumas regras:

Nova regra: A partir de então 100% do que fazíamos de novo deveria ser versionado.

Nova regra: 100% do que conhecemos também precisa ser versionado.

Quando eu digo 100% do que conhecemos: É porque havia um conjunto de aplicações, que não sabiam onde estavam rodando, quem controlava, quem agendava, não sabíamos quem estava de posse dos fontes, qual servidor ou equipe era responsável. Sabíamos que algo era executado, mas não sabíamos por quem e onde. Não sabíamos que alguém gerenciava aquilo ou se estava largado.

A operação da empresa dependia de algumas dessas aplicações mágicas.

Agora com algum alívio, por não ter mais medo de que HD’s queimados me tirassem o sono, poderíamos partir para a identificação e melhoria da vida das pessoas.

Step 2 – Identificação do cenário atual

Um dos processos da minha equipe, que considero dos mais importantes da empresa é a ingestão de conteúdo, por ele recebíamos milhares de XML’s e mídias(WAV, AVI) todos os dias, são diversos formatos e padrões de integração, o que nos demandava uma quantidade razoável de storage, alguns petabytes. Esse processo era composto por diversas micro-aplicações, onde cada uma era um fork de um projeto. Nesse novo projeto tínhamos um desenvolvedor gerindo esse código, uma loucura para uma pessoa só. Óbvio que daria merda em algum momento. Fiz o trabalho de entender o cenário de negócio e compreender quais são os gaps do processo atual. Entre eles estão:

  • Alta segmentação das versões da base de código, cada uma com ligeiras mudanças para atender ligeiras diferenças entre parceiros.
  • Alta complexidade em cada uma das aplicações que possuíam formatos de XML diferentes.
  • Baixa completude no processamento do conteúdo recebido (boa parte das aplicações, ou precisava de tapas na hora de processar, ou só processava parte do XML que recebíamos)
  • Alta complexidade na gestão do processo
  • Falta de visibilidade do estágio de processamento e até mesmo de etapas do processo
  • Nenhuma escalabilidade
  • Paralelismo Moleculá (o moleco lá tentava paralelizar com braço esquerdo e direito) #piadoca
  • Equipe tecnicamente desatualizada, que vivia uma Era inteira apagando incêndios
  • Equipe reduzidíssima

Step 3 – Desumanizando e despersonificando o processo de ingestão de conteúdo

Como o dia-a-dia dependia de tarefas manuais, como consultar arquivos que estavam no disco em 16 storages, fazia sentido pensar em meios de eliminar o fator humano dessa equação. O fator humano aqui era o conhecimento sobre a probabilidade de encontrar um arquivo em específico, no último storage usado pelo FTP para receber conteúdo.

Eu não poderia depender da memória de um humano para tomar alguma decisão, eu precisava de dados em um ou vários bancos que pudessem ser processados para produzir outras atividades. É o princípio do processo de automação.

3.1 Unificar o formato de processamento

Durante discussões com a equipe sobre os formatos de XML que recebemos, vimos que muitos parceiros, e o mercado fonográfico em si, estava convergindo para um padrão chamado DDEX. Esse standard serve para qualquer integração de mídia imaginável (programas, músicas, vídeos, ringtones, wallpapers etc). Apostar nesse formato foi uma escolha ousada, mas trouxe muito resultado. Como o padrão é extremamente amplo e aberto, servindo a diversas finalidades, há campos demais para dados de menos. O resultado é a possibilidade de interpretação particular de cada parceiro sobre cada uma das áreas do XML.

São 8 formas diferentes de se tirar um conteúdo do ar (remover o direito de comercializar ou reproduzir uma música/vídeo em um determinado país, tempo, ou outras condições) de forma implícita ou explícita entre outras variações bem peculiares.

Apesar dessa complexidade, unificar o modelo de processamento nesse formato nos trouxe a segurança para criar uma única aplicação para processar esse conteúdo, então conseguimos ter uma visão unificada do processo, automático e escalável.

Como disse, embora a maior parte do mercado estivesse convergindo para o DDEX, ainda havia uma parcela significativa do mercado usando XML’s proprietários. Em muitos casos nós éramos vezes menor que o parceiro. Nos momentos em que éramos maiores, estávamos diante de parceiros que usavam freelancers para criar suas integrações. Isso significava de forma prática, que quem já não trabalhasse com DDEX, continuaria enviando seu formato proprietário, e era nosso papel lidar com isso.

Isso sempre esteve claro, e para lidar com isso, o processo de importação tinha a capacidade de determinar o formato original daquela integração. E nós mesmos cuidávamos dos templates XSLT para transformar formatos proprietários em DDEX.

Gerou um esforço a mais, que foi perfeitamente justificável em função da unificação do pipeline de ingestão de conteúdo.

3.2 Transformar consulta em disco em query em um database

Primeiro pensei em um database SQL para armazenar o conteúdo do XML, modelando tabela-a-tabela, mas quando estávamos próximos de modelar 100 tabelas, e não estávamos sequer na metade do mapeamento, pedi que parassem a atividade para que pudesse repensar. Já haviam empenhado algum esforço nessa mesma iniciativa alguns meses antes, mas ignorei. Julguei que o erro era meu por não estar 100% focado na atividade. Acreditei que com alguém focado no problema e com alguma supervisão técnica seria possível: Não. não era! Subestimei o padrão “dos infernos”. Era surreal, se modelássemos, seriam pelo menos 300 tabelas para gerir. Era necessário encontrar uma alternativa.

Após a desistência de bases SQL, pensei em usar uma base XML, mas nada me agradou: nem bancos baseados em XML, nada.

Então pensando muito na possibilidade, optei por usar o MongoDB para realizar essa tarefa. Como MongoDB não suporta XML, geramos conjunto de classes com base no XSD, fazendo o parser direto de XML para .NET, que em seguida é persistido diretamente no MongoDB.

O resultado foi um sucesso:

  • extremamente eficiente
  • agora permitindo consultas nos dados do XML.
  • Indexável
  • Trocando uma consultas de horas por alguns millisegundos

Foi uma excelente decisão, poupando muito tempo e facilitando muito o trabalho. Pelo fato das classes terem sido geradas com base no XSD, as garantias de formato estão todas presentes, então tenho o melhor dos mundos!

3.3 – Eliminar consultas ao FileSystem

A falta de visibilidade dos pacotes (pacotes são entregas de 1 XML de metadados com suas N mídias, mp3, mp4 etc..) e a pulverização do FileSystem era problema do passado e do presente, um agravante e complicômetro para a automação do processo de ingestão.

Analisar diretórios de servidores de produção era tarefa diária. Entenda, eram pelo menos 16 storages, onde cada pacote poderia estar em qualquer um deles, ou simultaneamente em vários deles: Fragmentado.

O processo de gestão de espaço em disco era apontar o FTP para O MESMO path relativo EM OUTRO DISCO. Todos os 16 storages possuíam as mesmas estruturas de diretórios, e o endpoint do FTP hora apontava para qualquer um desses 16 storages, de acordo com a disponibilidade de discos.

Essa disponibilidade era produzida a partir da aquisição de novos discos, novos storages, descarte de conteúdo morto.

Gerir esse caos, era complicado, pois o acesso a disco é muito custoso. Nesses storages onde petabytes eram armazenados em poucas pastas, era surreal fazer qualquer busca ou leitura. Não havia eficiência na leitura desses discos, portanto, eu precisava de alguma representação desse file system, mais rápida e eficiente. Algo como um file system virtual que consolidasse o file system físico. Pois diversas análises precisam ser feitas com base na estrutura, nos nomes do arquivos, para que pudesse tomar uma decisão sistêmica. Na prática eu precisava consolidar os pacotes fragmentados, para que no final do processo, fosse eliminada a fragmentação.

PS: Quando esse processo entrou no ar, um efeito não planejado foi que quanto mais processávamos, mais espaço em disco sobrava. Isso porque quando um FTP era movido de disco, o fornecedor reenviava os arquivos que haviam sido recebidos pela metade. Isso gerava 2 envios, um quebrado e outro completo. Bastava meu algoritmo identificar qual era o completo e qual era o quebrado. Uma simples comparação de tamanho, e uma checkagem simples de execução seria o suficiente.

Criei uma base SQL para gerir o processo com uma visão semelhante à do File System (Diretórios, arquivos, tamanho), tudo, exceto o conteúdo do arquivo em si, permitindo com queries determinar exatamente o que cada disco possui. Agora não precisamos estar em contato direto com o File System, queries em um banco SQL mostravam toda a estrutura do File System. Um processo simples fazia a sincronização periodicamente. Uma característica legal é que por mais que o pessoal de infraestrutura cuidasse do FTP da mesma forma como sempre fizeram, meu trabalho poderia ser feito de forma coesa, reduzindo os impactos dessas decisões. Por outro lado, para o processamento das tarefas, havia uma escolha de prioridade entre os discos, isso permitia que eu mesmo não sofresse com as necessidades específicas de gerir storages tão grandes.

4 – Criando um monolito projetado para a escala

A ideia aqui era criar uma infraestrutura de arquitetura robusta que facilitasse e promovesse o refactoring contínuo. Ou seja. Eu queria acabar com a ideia de puxadinhos, e de não fazer a coisa certa. Era cultural. Não fazer aquilo que precisava ser feito porque alguma dependência obscura.

O bater de asas de uma borboleta no projeto PHP (loja de músicas) fazia uma importação inteira parar.

Isso não podia acontecer mais.

4.1 Geração de Código

O Oragon Architecture foi fundamental para a criação desse modelo. Com ele geramos código de acesso a dados, para todas as bases necessárias, gerando código e configuração para NHibernate e FluentNHibernate. Como sempre: seguindo CQS, trabalhando com MySQL e SQL Server side-by-side, com múltiplos databases, hora em contexto transacional, hora somente read-only.

Agora, a ausência de um owner de cada database, não representa mais um problema tão grande assim. O banco muda, mas periodicamente geramos código a partir do banco, e é comum ver coisas mudando. O que nos afetar, diretamente e for incompatível, gera uma quebra no build: automaticamente, aumentando a segurança e resiliência na solução. Da mesma forma que geramos código com uma grande riqueza de detalhes, estamos aptos a regerar os bancos a qualquer momento, e identificar o que mudou estruturalmente no banco, bastando analisar nosso mapping com a ajuda de históricos do scm.

A briga por mudar a forma como consumiam banco era uma batalha perdida. A empresa trabalhava há anos daquela forma. Meu time era o Backoffice, ou seja, eu não era exatamente a galinha dos ovos de ouro da empresa. Quem encantava o Carlos Slim (ou seu filho, não lembro) era a loja de músicas que cuidadosamente era nutrida de features para agradar seu futuro dono.

Tudo era mais fácil do que fazer essa mudança.

4.2 AOP

Sob o framework de AOP do Spring.Net, o Oragon Architecture implementa uma série de aspectos que torna viável trabalhar com Redis, MongoDB, MySQL, DB2 e SQL Server de forma transparente e simples. Um único template é necessário para todos os bancos SQL citados. Para os NoSQL’s, não havia como gerar código, mas os aspectos (AOP) ainda eram úteis por definir a conectividade da mesma forma para todas as soluções. Do ponto de vista do código, nenhum OpenSession ou Connect é visível, apenas precisa-se marcar os métodos com os atributos corretos para que a infraestrutura cuide de todo o resto. Outro ganho direto é a resolução de connection leaks.

O descuido humano não atrapalhava mais. Agora de fato, se está funcionando, está certo, porque a arquitetura garante que só funciona se estiver certo.

4.3 Agendamento

Ainda falando do Spring.Net, jobs agendados foram criados com Quartz.Net para iniciar operações de negócio agendadas, como emissão de relatórios que anteriormente eram criados manualmente periodicamente entre outras operações recorrentes agendadas. A sincronização do File System com o banco SQL que citei acima, também era agendada aqui.

4.4 Mensageria e Exception Handling

Para escalar a solução, um pipeline foi criado em cima do RabbitMQ para processar todo o fluxo de trabalho das importações, desde a gestão (monitoramento) do file system, até a ingestão propriamente dita. Nesse modelo o Oragon fornecia as abstrações para que você só implemente as operações necessárias em cada passo do pipeline, sem que seu código saiba sequer que faz parte de um. Assim basta programar uma operação de negócio e plugar no pipeline, caso haja erro no processamento, lance suas exceptions e o próprio orquestrador (Oragon) se encarregará de colocar a mensagem na fila de erro, para que a mensagem não seja reprocessada infinitamente, com o mesmo status de erro. Geralmente os erros são de duas naturezas, ou o cliente errou no contrato ou o código encontrou uma situação não prevista, há um terceiro cenário, pouco comum que é uma falha em validação de negócio. Para essa temos um fluxo de tratamento diferenciado.

Em todos os casos, as exceptions são logadas, automaticamente, pelos aspectos Oragon Architecture, em filas RabbitMQ, isso com ajuda do pacote Spring.NET AMQP, posteriormente são armazenadas no Sentry sem causar gargalos na aplicação. Mais tarde, após inúmeros problemas, substituímos o Sentry por ElasticSearch.

4.5 Worker Process

Agora, estávamos aptos a iniciar diversos hosts de processos, para consumir uma infinidade de filas, segmentando cada operação por parceiro se assim nos interessasse (e interessava muito). Conseguimos trabalhar com diversos processos em diversas máquinas, escalando até quanto o hardware e os databases suportassem.

A arquitetura, cheia de abstrações viabilizou tomar as decisões que envolviam estratégia de deploy o mais tarde possível. Sem mudança no código.

Apenas com configurações.

Esse é o ganho trazido por uma aplicação extremamente configurável. Mas não há almoço grátis. As configurações são tão relevantes quanto o código e eram extensas. No código, não precisamos ver sequer um try-catch, e não há nada de errado nisso. Os Aspectos eram responsáveis por pela gestão e tratamento das mensagens. As operações transacionais, são geridas pelos aspectos e eles são responsáveis pelo rollback em caso de erro. As configurações eram muito mutáveis e maleáveis, mas eram de extrema importância para o fluxo (havia uma relação de dependência aqui).

Enfim, toda escolha, uma renúncia.

4.6 Continous Integration e Continuous Deploy

Para o processo de build e deploy, eu havia configurado o Jenkins, mas agora estava apanhando um bocado do TeamCity. A intenção era migrar do Jenkins para o TeamCity. Eu não me recordo se esse movimento foi concluído ou abortado.

Esse foi o roadmap do meu primeiro ano de trabalho alí. É realmente muito excitante trabalhar com essas tecnologias, não pelas tecnologias em si. Mas pela capacidade de resolver grandes problemas de forma profissional. Conseguir atender e endereçar todas essas demandas é incrível.

No final desse ano de trabalho a maior dificuldade estava no Negócio. Compreender e estabilizar as expectativas quanto ao business, que no caso de um processo de importação de metadados, é preencher as devidas tabelas, garantindo retro-compatibilidade com um parque de aplicações complexo e infinito.

Resumo

Bom, novamente, os frameworks utilizados foram utilizados para sanar necessidades reais.

Spring.Net para IoC, DI e AOP

Oragon Architecture para AOP (implementação)

Quartz.Net para Agendamentos

TopShelf para Serviços Windows (joguei um monte de código fonte fora, depois que achei esse framework)

T4 para os templates de geração de código

Spring AMQP para abstrações com RabbitMQ

Jenkins para Integração Contínua

MongoDB para armazenar XML convertido em BSON.

Nhibernate e FluentNHibernate para acesso a dados.

Redis para Lock Distribuído

RabbitMQ para controlar e distribuir processamento com resiliência.

Lembre-se das premissas:

Equipe:

Equipe reduzida.

Contexto:

GAP técnico, falta de Gerência de Configuração, e segmentação do código. Falta de padronização de recebimento de conteúdo e dificuldade de gestão de código, plataforma e manutenção.

Enfim, Arquitetura

A correlação entre as diversas peças que irão compor a solução, cada uma oferecendo uma feature de negócio.

Espero que tenha gostado!

[03/04/2018] – Revisão do Texto para melhorar a explicação sobre algumas necessidades.

[12/07/2022] – Adição de novas informações úteis para entendimento do momento. Revisão do tempo verbal adotado no texto.

O Cloud Native .NET é meu principal projeto.

Onde empenho energia para ajudar, acompanhar, direcionar Desenvolvedores, Líderes Técnicos e jovens Arquitetos na jornada Cloud Native.

Conduzo entregando a maior e mais completa stack de tecnologias do mercado.

Ao trabalhar com desenvolvedores experientes, eu consigo usar seu aprendizado com .NET, banco de dados, e arquitetura para encurtar a jornada.

Ao restringir à desenvolvedores .NET eu consigo usar do contexto de tecnologias e problemas do seu dia-a-dia, coisas que você conhece hoje, como WCF, WebForms, IIS e MVC, por exemplo, para mostrar a comparação entre o que você conhece e o que está sendo apresentado.

É assim que construímos fundamentos sólidos, digerindo a complexidade com didática, tornando o complexo, simples.

É assim que conseguimos tornar uma jornada densa, em um pacote de ~4 meses.

Eu não acredito que um desenvolvedor possa entender uma tecnologia sem compreender seus fundamentos. Ele no máximo consegue ser produtivo, mas isso não faz desse desenvolvedor um bom tomador de decisões técnicas.

É preciso entender os fundamentos para conseguir tomar boas decisões.

5 Comentários

  1. Ricardo

    Olá Luiz! Tudo bem?

    Lendo o texto fiquei com uma duvida, você cita no texto “…Equipe tecnicamente desatualizada, que vivia uma era inteira apagando incêndios…” e “…GAP técnico…”.
    Neste cenário que aqui expôs, foi necessário alterar o time técnico em questão? Digo, você teve que treinar o pessoal ou ouve a dança das cadeiras com relação aos cargos?

    Obrigado!

    Responder
    • Luiz Carlos Faria

      Ótima Pergunta Ricardo. Existem 2 tipos de profissionais, os que jogam o jogo e os que burlam as regras. Quem joga o jogo, entende o que está mudando e ok, segue o jogo, tentam fazer, não jogam contra. Mas quem burla as regras tende a responder para clientes externos da seguinte forma: “Ahh, se eu fizer sem isso, sem aquilo, sem aquilo outro, eu faço mais rápido”. Enfim, quer uma confirmação para fazer algo da forma não combinada. Sem arquitetura, provavelmente sem testes, enfim.

      Embora eu não tenha demitido, esse segundo perfil eu acredito que não agregue, que seja mais nocivo do que benéfico, hoje eu teria demitido.

      Mas não o fiz. Eu simplesmente após tomar alguns bypasses desses eu simplesmente me envolvi diretamente ao ponto de não deixar o fluxo seguir sem uma avaliação da forma e como as coisas estavam sendo feitas. Se olhar a imagem, vai perceber que parte do processo é tirar autonomia do dev de colocar código em produção. E eu defendia com minha vida (na empresa, claro) que código fora do combinado não chegaria mais em produção, para evitar toda essa ingerência sobre o código técnico. Deu certo na maioria das vezes, mas não todas. Ok!

      Para ajudar, eu precisava contratar gente que estivesse mais próxima e mais a par da arquitetura que eu estava propondo, eu precisava de apoiadores, e para isso precisava trazer pra dentro quem conhecesse algumas tecnologias-chave, principalmente injeção de dependência, dependency injection. E não bastava conhecer mais ou menos, tinha de ter um certo nível de profundidade. Pode parecer bobo, mas a gente naquela época ia muito além de um simples register/resolver.

      Assim eu cuidei do processo de contratação de novos membros, e escolhi com cuidado perguntas que faria. Meu medo era contratar hater em vez de aliados, então nesse processo eu fiz questão de descartar quem era hater de algumas tecnologias específicas (NHibernate e Spring.NET) e principalmente quem nunca havia trabalhado com .NET + Open Source (bancos SQL, bancos NoSQL, Filas, etc). Essa galera que eu estava trazendo e trouxe 4 novos pelo menos, precisavam ter uma cabeça mais aberta. Eles me ajudariam a evangelizar os demais.

      Esse foi o combo, foi assim que com uma galera nova, motivada, conseguimos produzir comportamentos bons nos demais. Embora se tenha tido muita rejeição no início, consegui abstrair a complexidade de diversas tecnologias, assim viabilizando que mesmo quem não conhecia nada de RabbitMQ, pudesse trabalhar com, de forma transparente. Sem mudar ou implementar código específico, apenas algumas regras eram necessárias para se ter um consumidor apontando para um método, com toda a segurança necessária para esse tipo de processamento.

      Como estratégia para evitar aventuras, a só tinha de fato complexidade, na arquitetura, hoje é mais comum ser chamado de infraestrutura, mas eu ainda chamo esse tipo de projeto de projeto de arquitetura. Quem queria “inventar moda” tinha de fazer de forma genérica para que todos pudessem aproveitar a nova solução, não importa o âmbito.
      Fazia parte desse escopo trocar as implementações antigas (pela nova, recém criada), portanto, você teria de lidar com códigos que nunca viu antes. Só quem estava convicto do potencial de entregar algo melhor, tinha motivação para fazer a coisa certa. Quem queriam apenas fazer uma gambiarrazinha, fazer um testezinho com uma tecnologia, que acabaria chegando em produção, era automaticamente desencorajado.

      Essa abordagem evita muita gambiarra e gente reinventando uma roda quadrada. Eu nunca desencorajei a fazer no lugar central, na arquitetura, o requisito que eu adicionava a qualquer implementação nessa área era que não fosse dependente do negócio, precisava ser genérica, reaproveitável, e se fizesse a mesma coisa que uma versão anterior, deveria substituir a anterior. Fato que isso gerou soluções ótimas, principalmente uma de consumo de filas, que hoje me parece complexa demais, mas atende e continua atendendo, quase 6 anos depois.

      Responder
      • Ricardo Augusto Lamb

        Luiz,
        Muito obrigado pela resposta!
        Esclareceu muito, e ao mesmo tempo gerou mais dúvidas! rsrsrs
        Penso que neste processo todo, lidar com arquitetura, com códigos, com tecnologia como um todo e por fim este tipo de situação no time, você deve ter tido uma “gordura” de tempo muito boa para manobrar tudo isso! Ou estou errado, tudo isso aconteceu perfeitamente dentro do escopo de tempo?? (emoji de carinha pensando) 🙂

        Obrigado!!
        Abraços!

        Responder
        • Luiz Carlos Faria

          Quem controla o tempo e quem dá prazo é o time de tecnologia. Não é uma questão de ter gordura. Pra mim aquilo era necessário, eu preciso lidar com o problema de forma profissional e portanto, embutir esse custos nos projetos do dia-a-dia faz parte. Senão a conta chega um dia.

          Ninguém vai ligar se vc entregou mais rápido mas deixou um débito ou manteve outro débito.

          Quando você dá o prazo para uma atividade, você tem de dar o prazo para fazer tudo a respeito dela.
          Ceder às pressões do negócio, é, me perdoe o termo, burrice.
          Pois isso vai se voltar contra você mesmo.

          Senso de urgência é uma coisa que tentam repassar e propagar da presidência até o mais raso executor, no entanto se você trabalha sério, você consegue espaço para organizar isso. Se tudo é prioritário, então nada é prioridade. E esse era meu lema. Se tenho 10 atividades como mesmo nível de urgência e criticidade, eu posso escolher entre qualquer uma, é meu direito. Como gestor técnico e organizacional daquele time, eu tinha essa autonomia.

          Vamos supor, que pela perspectiva do cliente seja adicionar um campo em uma tela, no entanto, entendendo o problema, na verdade deva ser criada uma nova tabela, em vez de adicionar uma coluna em outra. Criar uma coluna tem algum impacto, mesmo que pequeno. Mas é infinitamente menor do que o impacto de criar uma tabela, ou quebrar uma tabela em 2. Se para atender à demanda você adicionar um mero campo, só pra atender a expectativa de prazo do teu cliente, você está cometendo um erro grave, você vai pagar a conta disso em algum momento ou ainda, sairá da empresa e outro pagará a conta por você. Mas nesse caso não há outro culpado, senão você!

          Meu papel ali era transformar aquela equipe, aquela área.
          E conduzi com sucesso no primeiro ano. No segundo ano, era hora de jogar poeira para baixo do tapete, e não sabia disso. Não estava claro para mim. Eu só fui podado.

          Mas ainda assim, executei ali um trabalho muito consistente, principalmente no que diz respeito à mindset. Fazer a coisa certa em vez de fazer a coisa mais conveniente. Consegui embutir e engordar prazos para atender à demandas de organização dos projetos, pena que não tive tempo para finalizar minha obra.

          Eu não conseguia mais não progredir. Minha ambição técnica era muito maior do que o espaço que eu tinha para trabalhar e um belo momento não deu mais para sustentar essa relação.

          Responder
          • Ricardo

            Luiz,

            Ótimos esclarecimentos!
            E parabéns pelo ótimo artigo!! Muito rico em detalhes, isso nos dá uma real noção de qual é o papel correto a ser desempenhado nestes momentos!
            Muito obrigado por compartilhar!!

            Abraços!

            Responder

Enviar um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *

Esse site utiliza o Akismet para reduzir spam. Aprenda como seus dados de comentários são processados.

Luiz Carlos Faria

Mensagem do Autor

Espero que goste desse post. Não deixe de comentar e falar o que achou.

Se acha que esse post pode ajudar alguém que você conheça, compartilhe!

 

Lives

Fique de olho nas lives

Fique de olho nas lives no meu canal do Youtube, no Canal .NET e nos Grupos do Facebook e Instagram.

Aceleradores

Existem diversas formas de viabilizar o suporte ao teu projeto. Seja com os treinamentos, consultoria, mentorias em grupo.