Como você projeta projetos orientados a objetos? [fechadas]

231

Estou trabalhando em um projeto grande (para mim), que terá muitas aulas e precisará ser extensível, mas não tenho certeza de como planejar meu programa e como as classes precisam interagir.

Fiz um curso de OOD há alguns semestres e aprendi muito com ele; como escrever UML e traduzir documentos de requisitos em objetos e classes. Também aprendemos diagramas de sequência, mas de alguma forma eu perdi a palestra ou algo assim, eles realmente não ficaram comigo.

Em projetos anteriores, tentei usar os métodos que aprendi no curso, mas geralmente termino com um código que, assim que posso dizer "sim, parece algo com o que eu tinha em mente", não tenho vontade de vasculhar a sujeira para adicionar Novas características.

Eu tenho uma cópia do Code Complete de Steve McConnell que eu sempre ouço é incrível, aqui e em outros lugares. Eu li o capítulo sobre design e não parecia ter as informações que estou procurando. Eu sei que ele diz que não é um processo de corte e secagem, que é principalmente baseado em heurísticas, mas não consigo pegar todas as informações dele e aplicá-las aos meus projetos.

Então, o que você faz durante a fase de design de alto nível (antes de começar a programar) para determinar quais são as classes de que você precisa (especialmente as que não são baseadas em nenhum 'objeto do mundo real') e como elas irão interagir umas com as outras ?

Especificamente, estou interessado em quais são os métodos que você usa? Qual é o processo que você segue que geralmente produz um design bom e limpo que representará de perto o produto final?

Victor
fonte
2
Eu pensei que o Code Complete era bastante útil sobre esse assunto - particularmente os capítulos 5.3 e 5.4 (que têm algumas sugestões mais concretas) e todo o capítulo 6. No entanto, na verdade, eu não fiz nenhum design de código para um projeto grande.
Paul D. Waite
1
Eu posso recomendar fazer um curso sobre design orientado a objetos em Java. Existe um excelente publicado em UDEMY udemy.com/mastering-object-oriented-design-in-java/… . Eu acho que isso certamente pode ajudá-lo. Outro grande recurso é tentar o problema orientado a objetos do ATM. Você pode pesquisar no google.
Horse Voice
Eu recomendo a todos que voltem a esta pergunta quando você estiver realmente fazendo o design. Há muito conteúdo aqui. Dessa forma, você pode movimentar sua memória enquanto faz o design real.
Kevin Wheeler

Respostas:

199

As etapas que eu uso para o design inicial (como chegar a um diagrama de classes) são:

  1. Levantamento de requisitos. Converse com o cliente e considere os casos de uso para definir qual funcionalidade o software deve ter.

  2. Componha uma narrativa dos casos de uso individuais.

  3. Percorra a narrativa e destaque substantivos (pessoa, local, coisa), como classes candidatas e verbos (ações), como métodos / comportamentos.

  4. Descarte substantivos duplicados e considere a funcionalidade comum.

  5. Crie um diagrama de classes. Se você é um desenvolvedor Java, o NetBeans 6.7 da Sun possui um módulo UML que permite diagramação, engenharia de ida e volta e é GRATUITO. O Eclipse (um IDE Java de código aberto) também possui uma estrutura de modelagem, mas não tenho experiência com ela. Você também pode experimentar o ArgoUML, uma ferramenta de código aberto.

  6. Aplique os princípios de OOD para organizar suas aulas (fatorar funcionalidades comuns, construir hierarquias etc.)

Scott Davies
fonte
6
Essa é realmente uma técnica útil, especialmente quando você não tem um controle real sobre o domínio do problema. No entanto, raramente produz uma arquitetura ideal.
NomeN 17/07/09
1
Eu posso recomendar fazer um curso sobre design orientado a objetos em Java. Existe um excelente publicado em UDEMY udemy.com/mastering-object-oriented-design-in-java/…. Eu acho que isso certamente pode ajudá-lo. Outro grande recurso é tentar o problema orientado a objetos do ATM. Você pode pesquisar no google.
Horse Voice
1
Onde você aprende isso? Você poderia fornecer uma fonte disso?
Kanagavelu Sugumar
68

Adicionando o que Scott Davies tinha a dizer:

  1. Certifique-se de que você sabe o que é o seu programa antes de começar. Qual é o seu programa? O que isso não fará? Que problema ele está tentando resolver?

  2. Seu primeiro conjunto de casos de uso não deve ser uma lista completa de tudo o que o programa fará eventualmente. Comece com o menor conjunto de casos de uso possíveis, que ainda captura a essência da finalidade do seu programa. Para este site, por exemplo, os principais casos de uso podem ser fazer login , fazer uma pergunta , responder a uma pergunta e visualizar perguntas e respostas . Nada sobre reputação, votação ou wiki da comunidade, apenas a essência do que você está procurando.

  3. Ao criar classes potenciais, não pense nelas apenas em termos de qual substantivo elas representam, mas de quais responsabilidades elas têm. Eu descobri que essa é a maior ajuda para descobrir como as classes se relacionam durante a execução do programa. É fácil criar relacionamentos como "um cachorro é um animal" ou "um filhote tem uma mãe". Geralmente é mais difícil descobrir relacionamentos que descrevem interações em tempo de execução entre objetos. Os algoritmos do seu programa são pelo menos tão importantes quanto os seus objetos e são muito mais fáceis de projetar se você tiver explicado qual é o trabalho de cada classe.

  4. Depois de obter esse conjunto mínimo de casos de uso e objetos, comece a codificar. Consiga algo que realmente corra o mais rápido possível, mesmo que não faça muito e provavelmente pareça uma porcaria. É um ponto de partida e forçará você a responder perguntas que você pode encobrir no papel.

  5. Agora volte e escolha mais casos de uso, escreva como eles funcionarão, modifique seu modelo de classe e escreva mais código. Assim como seu primeiro corte, faça o mínimo de cada vez que puder, acrescentando algo significativo. Enxague e repita.

Apenas meus dois centavos. Espero que seja útil.

Darryl
fonte
19

Quando tive a chance, normalmente uso o que chamo de "regra das três iterações".

Na primeira iteração (ou inicialização), desenvolvo o layout geral do aplicativo de acordo com os objetos de modelo, os algoritmos e o esperado ( realmente esperado, não talvezesperado) direções futuras. Não escrevo documentos de design, mas se for necessário coordenar várias pessoas, é claro que é necessário um esboço do procedimento, juntamente com uma análise das dependências e estimativa do tempo necessário. Tente manter essa fase no mínimo se, como eu, você preferir um método mais ágil. Há casos em que é necessária uma fase de design forte, principalmente quando tudo é conhecido e verdadeiro sobre a lógica do seu programa e se você planeja ter muitas interações entre os recursos do seu código. Nesse caso, os casos de uso ou histórias de usuário fornecidos são uma boa ideia de alto nível, principalmente para aplicativos de GUI. Para aplicativos de linha de comando e, em particular, bibliotecas, tente escrever "histórias do programa" nas quais você codifica contra a biblioteca que precisa desenvolver e verifique como fica.

Após essa primeira iteração, você entenderá melhor como as coisas interagem, descobriu os detalhes e os pontos difíceis, resolveu os problemas com um adesivo de fita adesiva. Você está pronto para usar essa experiência para melhorar, limpar, polir, dividir o que era muito grande, unir o que era muito fragmentado, definir e usar padrões de design, analisar gargalos de desempenho e problemas de segurança não triviais. Em geral, todas essas alterações terão um enorme impacto nos testes de unidade que você escreveu, mas não nos testes funcionais.

Ao concluir esta segunda iteração, você terá uma pequena jóia, bem testada, bem documentada e bem projetada. Agora você tem a experiência e o código para executar a terceira iteração, estenda. Você adicionará novos recursos e casos de uso para melhorar seu aplicativo. Você encontrará pontos difíceis e acabará inserindo uma quarta iteração, que é análoga à segunda. Enxague e repita.

Essa é minha abordagem geral ao design de software. É semelhante ao design espiral, com curtas iterações de três meses e elementos de desenvolvimento Agile, que permitem aprender os problemas e conhecer seu software e seu campo de aplicação. Obviamente, é uma questão de escalabilidade; portanto, se o aplicativo é tão grande para envolver centenas de desenvolvedores, as coisas são um pouco mais complexas do que isso, mas no final, acho que a ideia é sempre a mesma, divide et impera .

Então resumindo:

  1. Na iteração 1, você experimenta e aprende
  2. Na iteração dois, você limpa seu produto e o prepara para o futuro
  3. Na iteração três, você adiciona novos recursos e aprende mais
  4. ir para 2
Stefano Borini
fonte
16

A fonte mais interessante que conheço sobre isso é a Parte D da Construção de Software Orientada a Objetos, 2ª Edição de Bertrand Meyer.

Parte D: Metodologia orientada a objetos: aplicando bem o método

19: Na metodologia, 20: Padrão de projeto: sistemas interativos com vários painéis, 21: Estudo de caso de herança: "desfazer" em um sistema interativo, 22: Como encontrar as classes , 23: Princípios de design de classe, 24: Usando bem a herança , 25: Técnicas úteis, 26: Um senso de estilo, 27: Análise orientada a objetos, 28: O processo de construção de software, 29: Ensinando o método

Curiosamente, o capítulo 22. Como encontrar as aulas está disponível online.

Daniel Daranas
fonte
12

É frequentemente repetido, mas completamente verdadeiro - entenda seus dados.

Para OOP, suas aulas devem descrever informações importantes e como elas interagem.

Se você tiver um modelo mental que descreva bem o comportamento e a vida útil dos dados, será fácil explicar suas aulas.

Isso é simplesmente uma extensão de: Saiba exatamente o que você está tentando fazer.

Dave Gamble
fonte
12
O comportamento do objeto é mais importante que os dados. Este é um resultado direto do encapsulamento: o coração da programação orientada a objetos. A exposição de dados (de idiomas como C e Pascal) leva a sistemas de difícil manutenção (aprimoramento e depuração) simplesmente porque você nunca sabe que outro local no sistema altera os dados. OOP não é sobre dados; OOP é sobre comportamento. É uma distinção importante.
21450 Dave Jarvis
É uma distinção importante, mas não significa que o comportamento seja mais importante que os dados.
9788
Para OOD, geralmente começo do design do modelo após esclarecer os requisitos, o que me dá uma idéia básica de como as entidades devem ser organizadas e como o relacionamento entre elas. Ao mesmo tempo, tenho uma idéia básica sobre as operações que podem ocorrer em cada entidade. Após uma imagem preliminar dos modelos, podemos revisar os requisitos e verificar se estamos perdendo alguma coisa. E então será mais fácil voltar ao nível da classe e ao nível do controlador.
Joshua
10

Tente usar o desenvolvimento orientado pelo comportamento. Vai ser difícil quebrar seus velhos hábitos, mas descobri que o BDD é realmente a sua melhor aposta quando se trata de se desenvolver no mundo real.

http://behaviour-driven.org/

Eric, o Vermelho
fonte
1
+1 O uso de desenvolvimento orientado a teste / comportamento / domínio permite criar classes à medida que você evita a metodologia problemática de cascata de design inicial grande e problemática.
21409 Halvard
8

O problema com grandes projetos é que você não pode supervisionar todas as interações entre componentes. Portanto, é importante reduzir a complexidade do projeto. Os diagramas de classe e sequência são muito detalhados para esta fase do design.

Primeiro tente pensar em um nível de abstração mais alto. Pense nos principais componentes e em suas responsabilidades (sua interface com outros componentes), observe alguns padrões de arquitetura em busca de inspiração (não, não padrões de design, esses são níveis muito baixos! MVC e Multi-Tier são exemplos de padrões arquiteturais). Para projetos razoavelmente grandes, essa visão deve ter cerca de 3-5 componentes.

Somente então você amplia um determinado componente e tenta projetá-lo. Agora estamos no nível de padrões de design e diagramas de classes. Tente se concentrar nessa parte do projeto, se achar que precisa adicionar uma responsabilidade a um dos outros componentes, basta adicioná-lo à sua documentação / lista de tarefas. Não perca tempo pensando nas implicações, neste ponto, elas mudam muito rapidamente, revise quando o design for mais sólido.

Você não precisa projetar completamente cada componente neste momento, embora seja provavelmente bom ter um pedaço de código que implemente a interface de componentes não implementados e gere respostas simples, mas úteis. Dessa forma, você pode iniciar o desenvolvimento (e o design) de um componente por vez e testá-lo em um grau razoável.

Obviamente, quando novos componentes forem concluídos, você deve testar como (e se) eles se integram antes de prosseguir.

Em resumo: pegue o princípio OO e ocultação de informações e suba outro nível!


PS: Faça muitos esboços ao projetar, é como uma arquitetura real!

PPS: Tente abordar o assunto de diferentes ângulos, pense fora da caixa (embora a caixa possa ser o caminho a seguir), discutir com colegas pode ser muito útil para isso ... e você tem algo sobre o que conversar durante o almoço.

NomeN
fonte
7

A técnica que usei em projetos reais com razoável sucesso é o Responsible Driven Design, inspirado no livro de Wirfs-Brock.

Comece com as histórias de usuário de nível superior e, com os colegas, em um quadro branco, esboce as interações de alto nível que elas implicam. Isso dá a você a primeira idéia do que são os grandes módulos; e uma ou duas iterações de alto nível da placa CRC, como você deve ter estabilizado uma lista dos principais componentes, o que eles fazem e como eles interagem.

Em seguida, se alguma das responsabilidades for grande ou complexa, refine esses módulos até que você tenha coisas pequenas e simples o suficiente para serem objetos, executando as interações dentro do módulo para cada uma das principais operações identificadas pelas interações de nível superior .

Saber quando parar é uma questão de julgamento (que só vem com a experiência).

Steve Gilham
fonte
+1 para o quadro branco, coisa extraordinária: eu resolvo 80% dos problemas em frente ao quadro branco, apenas olhando para ele e pensando 'qual seria o melhor?'
usoban
7

Padrões de design

Padrões de design criacional

Singleton - garanta que apenas uma instância de uma classe seja criada e forneça um ponto de acesso global ao objeto.

Factory (versão simplificada do Factory Method) - Cria objetos sem expor a lógica da instanciação ao cliente e refere-se ao objeto recém-criado por meio de uma interface comum.

Método de fábrica - Define uma interface para criar objetos, mas permite que as subclasses decidam qual classe instanciar e se refere ao objeto recém-criado por meio de uma interface comum.

Abstract Factory - Oferece a interface para criar uma família de objetos relacionados, sem especificar explicitamente suas classes.

Construtor - define uma instância para criar um objeto, mas permite que as subclasses decidam qual classe instanciar e permite um controle mais refinado do processo de construção.

Protótipo - especifique os tipos de objetos a serem criados usando uma instância prototípica e crie novos objetos, copiando esse protótipo.

Padrões de Design Comportamental

Cadeia de Responsabilidade - Evita anexar o remetente de uma solicitação ao seu destinatário, dando assim a outros objetos a possibilidade de lidar com a solicitação também. - Os objetos se tornam partes de uma cadeia e a solicitação é enviada de um objeto para outro através da cadeia até que um dos objetos o manipule.

Comando - Encapsula uma solicitação em um objeto, Permite a parametrização de clientes com solicitações diferentes e Permite salvar as solicitações em uma fila.

Intérprete - Com base em um idioma, defina uma representação para sua gramática, juntamente com um intérprete que use a representação para interpretar sentenças no idioma / Mapear um domínio para um idioma, o idioma para uma gramática e a gramática para um design hierárquico orientado a objetos

Iterador - Forneça uma maneira de acessar os elementos de um objeto agregado seqüencialmente, sem expor sua representação subjacente.

Mediador - Defina um objeto que encapsula como um conjunto de objetos interage. O mediador promove o acoplamento frouxo, impedindo que os objetos se refiram explicitamente, e permite variar a interação deles independentemente.

Observador - Defina uma dependência de um para muitos entre objetos para que, quando um objeto mudar de estado, todos os seus dependentes sejam notificados e atualizados automaticamente.

Estratégia - Defina uma família de algoritmos, encapsule cada um e torne-os intercambiáveis. A estratégia permite que o algoritmo varie independentemente dos clientes que o utilizam.

Método de Modelo - Defina o esqueleto de um algoritmo em uma operação, adiando algumas etapas para as subclasses / O Método de Modelo permite que as subclasses redefinam certas etapas de um algoritmo sem permitir que elas alterem a estrutura do algoritmo.

Visitor - Representa uma operação a ser executada nos elementos de uma estrutura de objeto. O Visitor permite definir uma nova operação sem alterar as classes dos elementos nos quais opera.

Objeto nulo - forneça um objeto como substituto pela falta de um objeto de um determinado tipo. / O Padrão de Objeto Nulo fornece um comportamento inteligente de não fazer nada, ocultando os detalhes de seus colaboradores.

Padrões de projeto estrutural

Adaptador - Converta a interface de uma classe em outra interface que os clientes esperam. / Adapter permite que as classes trabalhem juntas, que não poderiam de outra forma por causa de interfaces incompatíveis.

Ponte - Componha objetos em estruturas de árvore para representar hierarquias de partes inteiras. / Composite permite que os clientes tratem objetos individuais e composições de objetos de maneira uniforme.

Composto - Componha objetos em estruturas de árvore para representar hierarquias de parte inteira. / Composite permite que os clientes tratem objetos individuais e composições de objetos de maneira uniforme.

Decorador - adicione responsabilidades adicionais dinamicamente a um objeto.

Flyweight - use o compartilhamento para oferecer suporte a um grande número de objetos que têm parte de seu estado interno em comum, onde a outra parte do estado pode variar.

Memento - capture o estado interno de um objeto sem violar o encapsulamento e, assim, forneça um meio para restaurar o objeto no estado inicial quando necessário.

Proxy - forneça um "Espaço reservado" para um objeto para controlar referências a ele.

Sauron
fonte
2
Padrões são úteis para algumas pessoas. Eu acho que precisa de uma experiência considerável para ver os padrões nos requisitos. E você provavelmente precisará documentá-los. Estou inclinado a pensar que os padrões nada mais são do que bibliotecas de componentes abstratos.
CyberFonic
5

Eu recomendo que você use o BlueJ e também o ActiveWriter para aprender e também desenvolver um bom entendimento sobre os objetos. O livro recomendado também é um bom recurso.

Da Wikipedia :

texto alternativo

O BlueJ é um ambiente de desenvolvimento integrado para a linguagem de programação Java, desenvolvido principalmente para fins educacionais, mas também adequado para o desenvolvimento de software em pequena escala.

Além disso, ele usa UML e, para mim, foi um bom recurso para compreender várias coisas sobre modelagem de objetos.

texto alternativo http://www.ryanknu.com/ryan/bluej.png

O ActiveWriter é uma ferramenta para modelar entidades e relações, também gera código e é fácil fazer alterações. Você economizará tempo e o desenvolvimento ágil é muito adequado.

texto alternativo
(fonte: altinoren.com )

Nelson Miranda
fonte
1
Eu usei J azul ... é definitivamente útil, mas como isso me ajuda a criar classes e suas relações?
Victor
1
Eu acho que me deixou claro ver toda a imagem de como identificar as classes e como relacioná-las visualmente. Nos meus primeiros passos, experimentei como era a representação do código dos objetos e como entender o pensamento nos objetos. Lembro-me de quando dediquei tempo para descobrir o "é um" e "tem um" e a UML foi uma excelente ajuda. Desde então, uso essas ferramentas visuais para projetar meus objetos e, quando descobri o ActiveWriter, fiquei muito satisfeito porque o BlueJ não possui geração de código e essa ferramenta possui, apenas para reforçar meu argumento, acho que visualmente você tem uma abordagem mais ampla de uma solução.
1913 Nelson Miranda
4

Primeiro de tudo - o design deve vir da sua alma. Você deve sentir isso por todas as suas fibras. Eu costumo andar por dois ou três meses antes de começar a fazer qualquer coisa, apenas andando pelas ruas (realmente). E pensando. Caminhar é uma boa meditação, você sabe. Então, permite que você se concentre bem.

Segundo - use OOP e classes apenas onde existe uma hierarquia de objetos naturais. Não 'estrague' isso artificialmente. Se não existir uma hierarquia estrita (como na maioria dos aplicativos de negócios) - vá para processual / funcional ou, pelo menos, use objetos apenas como contêineres de dados com acessadores isolados.

E a última - tente ler o seguinte: O Algoritmo do Pensamento Criativo

Thevs
fonte
4

Apenas citando http://www.fysh.org/~katie/computing/methodologies.txt

E no centro do RUP há uma pequena área em que você precisa usar os talentos do projeto OO ... se você não os possui, é como ter uma metodologia para executar os 100m.

"Etapa 1: escreva sobre como correr muito rápido. Etapa 2: vá e faça um plano da pista. Etapa 3: vá e compre shorts de lycra bem apertados. Etapa 4: corra muito, muito, muito rápido. Etapa 5: cruze primeiro a linha "

Esse passo 4 é o mais difícil. Mas se você colocar muita ênfase em 1,2,3 e 5, é possível que ninguém perceba e, provavelmente, você poderia ganhar muito dinheiro vendendo a metodologia para atletas que pensam que há algum "segredo" nos 100m corredor

Martin
fonte
4

Você fez uma pergunta que muitos autores usam para escrever um livro. Há várias metodologias e você deve escolher uma que pareça "mais bonita" para você.
Eu posso recomendar o livro "Domain Driven Design", de Eric Evans. Além disso, consulte o site dddcommunity.org .

zendar
fonte
3

Eu acho que a resposta aqui deve ser muito diferente, dependendo da experiência do mundo real do cara perguntando.

Se você tem apenas um ou dois anos de experiência profissional, deve ir ao ponto que é: como chegar ao ponto de realmente conhecer seus dados e entender exatamente o que está tentando fazer?

Sim, se você trabalha no mundo real há mais de 5 anos, pode escolher entre qualquer um dos muitos modelos ou técnicas de processos de desenvolvimento de software.

Mas você não obtém experiência lendo apenas livros. Você deve aprender trabalhando em um bom grupo, sob uma boa liderança.

Se isso não for possível, você deve fazer sozinho. Comece iterando codificando um pedaço de código provavelmente muito desagradável, aprendendo seus erros, descartando tudo, codificando um melhor e assim por diante.

Você aprenderá muito sobre sua base de código. As ferramentas são ferramentas, elas não ensinarão nada a você.

IlDan
fonte
3

Se você possui experiência no domínio do projeto, irá trabalhar como, por exemplo, bancário. É fácil estruturar seus objetos e você sabe como essas melhorias acontecem todos os dias.

Se você não tiver esse conhecimento, trabalhe com alguém que tenha esse conhecimento e converta essas idéias em detalhes técnicos.

Se você está confuso sobre como estruturar o design do seu projeto. Siga cegamente o livro "programador pragmático". Eu estava na mesma situação antes, tente ler um capítulo desse livro. você verá a diferença. Isso mudará a maneira como você pensa como desenvolvedor de software.

Link quebrado
fonte
2
  1. estudar e dominar padrões de design.
  2. Em seguida, aprenda sobre o design orientado a domínio
  3. Depois disso, aprenda a coleta de requisitos

Fiz um curso de OOD há alguns semestres e aprendi muito com ele; como escrever UML e traduzir documentos de requisitos em objetos e classes. Também aprendemos diagramas de sequência, mas de alguma forma eu perdi a palestra ou algo assim, eles realmente não ficaram comigo.

  1. Você conhece a etapa 3. Você precisa dominá-la. Quero dizer, através de muita prática para torná-lo sua segunda natureza. Isso ocorre porque o método que você aprende é simplesmente contrário ao que costumávamos ter. Então você precisa realmente dominá-lo. Caso contrário, você sempre voltará à sua maneira original de fazer as coisas. De alguma forma, isso é parecido com o Test Driven Process, em que muitos desenvolvedores java o abandonam após algumas tentativas. A menos que eles dominem completamente, caso contrário, é apenas um fardo para eles

  2. Escreva casos de uso, especialmente para cursos alternativos. Cursos alternativos ocupam mais de 50% do nosso tempo de desenvolvimento. Normalmente, quando seu PM atribui uma tarefa a você, por exemplo, crie um sistema de login, ele pensará que é simples, você pode levar 1 dia para finalizar. Mas ele nunca leva em consideração o que você precisa considerar: 1. e se o usuário digitar a senha errada, 2. o que se o usuário digitar a senha errada por 3 vezes, 3. o que se o usuário não digitar o nome do usuário e etc. Você precisa listá-los e mostrá-lo ao seu PM, peça a ele para reagendar o prazo.

janetsmith
fonte
2

Receio que esta não seja uma resposta que as pessoas gostem de ouvir . De qualquer forma, deixe-me expressar minha opinião.

OOP deve ser visto como um dos paradigmas, não como o paradigma superior. OOP é bom para resolver certos tipos de problemas, como o desenvolvimento de uma biblioteca de GUI. Também se encaixa no estilo de desenvolvimento de software geralmente seguido por grandes empresas de software - uma equipe de elite de designers ou arquitetos estabelece o design de software em diagramas UML ou em algum outro meio semelhante e uma equipe menos esclarecida. desenvolvedorestraduza esse design para o código fonte. OOP oferece pouco benefício se você estiver trabalhando sozinho ou com uma pequena equipe de programadores altamente talentosos. Então, é melhor usar uma linguagem que suporte múltiplos paradigmas e o ajude a criar um protótipo rapidamente. Python, Ruby, Lisp / Scheme etc são boas escolhas. O protótipo é o seu design. Então você melhora nisso. Use o paradigma melhor para resolver o problema em questão. Se necessário, otimize os pontos de acesso com extensões escritas em C ou em algum outro idioma do sistema. Ao usar um desses idiomas, você também obtém extensibilidadede graça, não apenas no nível do programador, mas também no nível do usuário. Idiomas como o Lisp podem gerar e executar código dinamicamente, o que significa que seus usuários podem estender o aplicativo escrevendo pequenos trechos de código, no idioma em que o próprio software está codificado! Ou, se você optar por escrever o programa em C ou C ++, considere incorporar um intérprete para um idioma pequeno como Lua. Exponha as funcionalidades como plug-ins escritos nesse idioma.

Penso que, na maioria das vezes, OOP e OOD criam software que é vítima de excesso de design.

Para resumir, minha maneira preferida de escrever software é:

  1. Use uma linguagem dinâmica.
  2. Escreva o design (protótipo) no próprio idioma.
  3. Se necessário, otimize determinadas áreas usando C / C ++.
  4. Forneça extensibilidade por meio do intérprete da própria linguagem de implementação.

O último recurso permite que o software se adapte facilmente a requisitos específicos de usuários (inclusive eu!).

Vijay Mathew
fonte
Isto não é aconselhar sobre como projetar
nomen
2
Eu uso uma abordagem semelhante. Para evitar ficar impressionado com a complexidade, comece com uma visão de helicóptero. Eu gosto de um esboço com 8 a 20 funções. Se começar a obter mais, analiso como particionar em subsistemas. Assim que tiver essa visão de alto nível, decomporemos cada função em 8 a 20 subfunções, etc. Observando o que essas funções manipulam, recebo as classes de nível superior. É quando começo a criar o sistema esquelético em Python, também conhecido como pseudo-código executável. Que, juntamente com os blocos de comentários, é minha 'especificação executável', que é progressivamente refinada.
CyberFonic
2

Eu uso o Design Orientado a Testes (TDD). Escrever o teste primeiro, na verdade, ajuda a levar você a um design limpo e correto. Veja http://en.wikipedia.org/wiki/Test-driven_development .

David Allen
fonte
2
O TDD ajuda a visualizar inicialmente seu sistema como uma caixa preta com sua entrada e saída de amostra. Mas, por si só, não ajuda você a criar o design do sistema. Eu quis dizer para o teste de unidade primeiro você tem que vir para cima com a interface de classe para teste
Vicente Bolea
2

Aprenda padrões de design . Foi minha revolução pessoal nos últimos dois anos em relação ao POO. Pegue um livro. Eu recomendaria este:

Head First Design Patterns

Está em Java, mas pode ser extensível a qualquer idioma.

David Espart
fonte
1

Honestamente, um bom passo seria voltar atrás e analisar o fluxograma e o diagrama de sequência. Existem vários sites bons que mostram como fazê-lo. Acho que é inestimável quando se analisa como quero dividir um programa em classes, pois sei exatamente o que o programa precisa ser inserido, calculado e gerado e cada etapa pode ser dividida em uma parte do programa.

user133018
fonte
1
Gosto de fluxogramas para quando fico preso em um problema. Às vezes, me ajuda a pensar sobre o problema de uma maneira diferente.
User133018
Em vez de ou bem como fluxogramas, "dados de diagramas de fluxo" (DFDs) são muito mais alto nível: eles são mais como um diagrama de implantação UML, e adequado para obter uma visão sobre sistema de funcionalidade (isto é, entrada de dados do sistema e saída de dados, armazenamento interno e externo de dados e processamento de dados) e arquitetura. Os fluxogramas (IMHO) estão mais próximos no escopo da modelagem de uma única função com instruções if-then-else.
28420 ChrisW
Sim, eu costumo usar a maior parte do tempo, geralmente, os fluxogramas são principalmente para quando estou tentando descobrir um problema específico.
user133018
O uso de raias de natação resolve muitos problemas com fluxogramas. Descobri que usar um diagrama de sequência por cenário funciona melhor. Cada cenário cobre um caminho específico na árvore de decisão, para que não haja FIs no fluxo. Se você deseja ter um único diagrama com todo o fluxo, precisará incluir os pontos de decisão, mas ele fica confuso rapidamente, especialmente se você deseja incluir a atribuição de responsabilidades.
55550 S. Kelly French
1

Uma técnica útil é relacionar sua descrição exclusiva do problema a algo que você pode encontrar no mundo real. Por exemplo, você está modelando um sistema de saúde complexo que conquistará o mundo. Existem exemplos que você pode chamar prontamente para modelar isso?

De fato. Observe como a farmácia lateral funcionaria ou a sala do médico.

Reduza o problema do seu domínio para algo compreensível para você; algo com o qual você pode se relacionar.

Depois que os "players" no domínio começarem a parecer óbvios e você começar a modelar seu código, opte por uma abordagem de modelagem "provedor-consumidor", ou seja, seu código é o "provedor" do modelo e você é o "consumidor" "

Relacionar-se com o domínio e entendê-lo em alto nível é parte essencial de qualquer design.

Mike J
fonte
1

Durante minhas aventuras de projetar estruturas de classe, notei que é muito útil começar escrevendo algum pseudo-código. Isso significa: começo com "escrevendo" alguns fragmentos gerais do código do aplicativo em um nível mais alto, brinco com ele e descubro os elementos que estão aparecendo - de fato, os elementos que eu - como programador - gostaria de usar. É um ponto de partida muito bom para projetar a estrutura geral dos módulos e suas interações. Após algumas iterações, toda a estrutura começa a se parecer mais com um sistema completo de classes. É uma maneira muito flexível de projetar partes do código. Você pode chamá-lo de design orientado a programador.

Darius
fonte