Quando inicio um novo projeto, muitas vezes começo imediatamente a pensar nos detalhes da implementação. "Onde vou colocar o DataBaseHandler? Como devo usá-lo? As classes que desejam usá-lo estendem-se a partir de uma superclasse Abstract ...? Devo usar uma interface? Que nível de abstração vou usar na minha classe que contém métodos para enviar solicitações e analisar dados? "
Acabo parando por um longo tempo porque quero codificar a extensibilidade e a reutilização. Mas acho quase impossível deixar de pensar em como implementar perfeitamente.
E então, se eu tentar apenas dizer "dane-se, basta fazê-lo!", Bati rapidamente em uma parede de tijolos porque meu código não está organizado, misturei níveis de abstração etc.
Quais são algumas técnicas / métodos que você tem para iniciar um novo projeto enquanto também configura uma estrutura lógica / modular que será bem dimensionada?
- - EDITAR - -
Bem, esse já é o tipo de pergunta difícil de ser respondida, mas queria obter mais feedback, veja se há algum consenso. O TDD parece muito legal e, francamente, eu pretendo acelerar o uso do JUnit, etc. Ao mesmo tempo, o que os fãs do TDD pensam sobre o fato de que um ponto legítimo em relação ao TDD é a solução? questões particulares, é que o TDD não parece realmente abordar a questão do design. Certamente, eu concordo que o TDD me ajudará a definir o que eu quero fazer e, em seguida, poderei trabalhar gradualmente no how, mas existem muitos padrões / estruturas gerais de design diferentes que podem passar pelo teste de unidade. É isso mesmo: ele testa UNIDADES únicas. Acho que estou um pouco confuso ... não sei. Talvez eu'
Obrigado!
Respostas:
Eu recomendo usar o Test-Driven-Development , é preciso algum tempo para me acostumar, especialmente quando se trabalha com um bom IDE como o eclipse, mas as vantagens são grandes.
Basicamente, o que você faz é escrever os testes no seu código antes de escrever o próprio código. Portanto, você é forçado a analisar seu código do ponto de vista de como ele será usado, o que significa que suas interfaces evoluem à medida que os cenários são implementados.
Outra característica é que você implementa em pedaços muito pequenos (eles aumentam quanto mais experiente você é na técnica e na programação), o que força você a se concentrar em um problema muito pequeno e bem definido a cada vez.
E também, desde que você primeiro escreveu um teste e só depois o implementou, você tem um teste com falha à sua frente. Portanto, se você é como a maioria dos programadores, não se deixa levar por análises malucas porque pensa: "Preciso fazer esse teste funcionar".
Um pequeno exemplo de java:
digamos que eu queira desenvolver um programa que leia e grave uma mensagem de um banco de dados.
Então, eu começo com a primeira ação bem definida, preciso de um banco de dados:
ok, então aqui vejo que preciso implementar a classe DbConnector.getDB para que ele retorne o banco de dados, até então esse teste falha. Eu vou fazer isso ...
Não adiciono a próxima coisa que quero fazer, carregue a mensagem do banco de dados:
Agora, adicionei outro pequeno recurso ao banco de dados que é buscar uma mensagem. Implemento isso. Depois de concluído, continuo com um recurso de cada vez até chegar a algo assim:
Pode parecer um exemplo muito simples, mas isso também funciona para tarefas mais complexas. Sei que consome muito tempo a princípio, mas quando você se acostuma, percebe que, na verdade, é muito mais eficiente. Por um lado, você evita a paralisia por análise e, por outro, obtém um código muito mais robusto, que geralmente possui menos bugs e passa por menos iterações.
fonte
Isso acontece comigo, então eu adquiri o hábito de aceitar (e abraçar) uma mentalidade de refatoração contínua. Faço a coisa mais simples que poderia funcionar, depois limpo, organizo, desacopro, testo e continuo.
Isso não quer dizer que não haja muito planejamento em andamento, mas acontece muito rapidamente e com mais frequência como rabiscos em pedaços ou na minha cabeça. No geral, às vezes eu chamo esse pequeno processo de micro-iteração, porque eles levam de 5 a 20 minutos cada e, por experiência, leva de 2 a 3 para terminar o que estou trabalhando (dependendo do que estou fazendo, obviamente).
Como uma observação lateral: eu ensinei várias pessoas em diferentes formas de escrita (relatórios, ensaios e redação técnica em geral) e é da mesma maneira que eu as faço escrever coisas para superar o bloqueio de escritor. "Apenas deixe escapar algo sobre o assunto que vier à mente na página. Então, faremos sentido, separaremos tudo em parágrafos e verificaremos o fluxo. Se necessário, vamos reescrevê-lo".
fonte
Algumas coisas que podem funcionar:
fonte
Para muitas decisões de design, pode ajudar a fazer um "pico", que é um esforço de pesquisa curto e com tempo limitado, no qual você pode explorar algumas opções de arquitetura ou design, codificando para um protótipo descartável. Por exemplo, você pode explorar o uso de alguma biblioteca de código aberto ou como você organizará suas classes e interfaces. A chave é mantê-lo curto para que você possa tentar outra abordagem se a primeira não for satisfatória e, com sorte, você ganhará conhecimento suficiente no exercício para tomar melhores decisões de arquitetura ou provar o conceito. O exercício propriamente dito envolve codificação imediata, o que ajuda a sair do "bloco dos escritores" sem necessariamente se comprometer com o "dar pronto" muito cedo.
Depois disso, é benéfico usar a abordagem TDD ou BDD que Asaf mencionou para avançar com a implementação do projeto.
fonte
Você não vai precisar , então não pense muito no começo.
Invista mais tempo para definir, entender o objetivo e o problema.
"Extensibilidade e reutilização" é o resultado natural do ciclo de vida de programas de software bem escritos.
fonte
Suponho que estamos analisando um projeto de tamanho médio.
Eu começaria indo na prancheta. Você deve ter seus requisitos funcionais e não funcionais prontos antes de fazer isso. Você primeiro criaria a arquitetura do software, ou seja, examinaria todos os padrões de arquitetura que atendam aos seus requisitos.
Depois de decidir como a sua arquitetura se parece, você deve entrar no design de baixo nível, ver todas as entidades, classes e funcionalidades . Aqui, você novamente tentará identificar os padrões de design que se encaixam. No processo, você saberá quais são as suas classes base e as interfaces necessárias.
Você poderá criar a estrutura e executar alguns testes rápidos para verificar se isso satisfaz todos os seus requisitos não funcionais
Eu iria então com o Test Driven Development como o @Asaf sugeriu.
Lembre-se, apesar de gastar um bom tempo em design e arquitetura, esteja sempre disposto a revisitar a arquitetura, se necessário.
fonte
Eu acho que essa é uma ótima pergunta e nada funcionará para todos. Eu acho que essa paralisia é um subproduto natural de se tornar cada vez mais competente em seu campo. Dito isto, aqui estão algumas coisas que eu ajudo, mas não resolve o problema:
Coloque seu projeto original de lado e trabalhe na versão fugaz. Esta é a versão em que você diz a si mesmo: a. O código não deveria ser bonito. De fato, diga a si mesmo que grandes refatorações e reformatações não são permitidas. Seja absolutamente desorganizado e liberte-se dos vínculos da boa codificação. b. Apenas tem que funcionar. c. É sempre surpreendente para mim o que aprendi sobre o espaço problemático quando expulso todas as outras preocupações. Também acabo com pequenos detalhes que geralmente me ajudam a obter o design certo de uma maneira mais esclarecida.
Separe um período de tamanho decente em que você estiver no projeto, apenas sem um computador. Tente conceituar o que realmente está tentando realizar e procure aquele zen mágico que transcende a loucura OO / Design Pattern.
fonte
Dê uma expressão concreta aos seus pensamentos: escreva / digite-os, desenhe-os ou o que for. Isso o ajudará a revisitar seus pensamentos quando necessário; impedirá você de andar em círculos; ajuda você a pensar com mais clareza.
Sempre que me vejo indo a lugar algum e a qualquer lugar pensando em alguma coisa, eu as digito e isso me ajuda a pensar com clareza.
fonte
Normalmente começo do zero, crio o protótipo mais simples possível e coloco algo em execução. Use o protótipo para fazer a engenharia reversa dos casos de teste do caminho feliz, os casos de teste para conduzir as interfaces e, em seguida, pense nos contratos pré / pós para ajudar a construir a cobertura do teste.
Não se preocupe com abstração, otimização ou verificação até que o problema seja totalmente compreendido.
fonte