Eu escrevi muitos softwares em vários idiomas diferentes e também "escrevi" hardware para uso com FPGAs usando Verilog e VHDL.
Costumo gostar de escrever hardware mais do que software, e acho que um dos principais motivos é que é possível escrever um hardware "pronto" e que nunca precisa ser modificado: você define as interfaces e a funcionalidade, escreve um banco de testes , implemente o módulo de hardware e teste-o usando um simulador. Em seguida, você pode confiar nesse módulo de hardware como um componente básico para criar algo maior e melhor: se você precisar adicionar um recurso a esse módulo, crie um segundo módulo e adicione a funcionalidade. Você nunca joga fora o módulo original, pois ele está funcionando muito bem e ainda pode ser útil.
Uma das minhas principais frustrações com o software é que nunca é "feito". Sempre há outro recurso a ser adicionado. Muitas vezes, ao adicionar um recurso, ele introduz um bug em outro lugar que estava funcionando bem antes. Isso não acontece no hardware, desde que as interfaces não sejam violadas.
Para deixar claro, não estou defendendo a criação de uma versão de algo com uma lista de recursos e é isso para sempre: sou a favor de iterações e vários lançamentos ao longo do tempo para adicionar novos recursos. Eu só não quero cutucar o código à esquerda e encontrar um bug à direita, e isso parece acontecer depois de adicionar um novo recurso.
É possível escrever software de maneira semelhante na qual o hardware é "gravado"? Existe uma boa metodologia de desenvolvimento de software que permita que o progresso sempre seja feito e que novas funcionalidades sejam adicionadas sem a necessidade de reescrever o código existente e introduzir novos bugs?
fonte
Respostas:
Exatamente meus pensamentos!
Módulos bem projetados com interfaces claras tendem a ser essencialmente perfeitos. Pense em algo como
String
classe de Java. É um programa de computador, mas possui uma interface clara. Não há erros conhecidos nele. Ele faz o que deveria fazer, perfeitamente. Certamente, ele foi extensivamente testado nos últimos 15 anos e, como praticamente todos os programas usamString
s como blocos de construção básicos, qualquer bug nele seria rapidamente percebido. Quaisquer "peculiaridades" - não estritamente bugs, mas detalhes de design que merecem atenção - como os descritos aqui http://www.jwz.org/doc/java.html são bem conhecidos agora e, portanto, podem ser levados em consideração conta.O software do Buggy é em parte uma questão cultural: as pessoas estão acostumadas com o software do buggy e, diferentemente do hardware, o software geralmente pode ser facilmente corrigido posteriormente, portanto não precisa ser aperfeiçoado inicialmente (ou nunca, porque, ei, precisamos enviar agora, vamos corrigir na próxima versão). Mas, em grande parte, é um problema de complexidade real: a complexidade do software tem aumentado constantemente nos últimos 50 anos, mas o cérebro humano é o mesmo. Quando a crescente dificuldade de alcançar a perfeição e a crescente facilidade de consertar as coisas posteriormente (compilações rápidas e automáticas, distribuição da Internet) combinam-se com a pressão do cronograma e a falta de disciplina, o resultado é o que é.
Provavelmente não existe uma bala de prata, mas uma boa combinação de práticas recomendadas, incluindo, entre outras:
Vale ressaltar que os dois pontos visam reduzir a complexidade. Esse é o ponto chave. A entropia sempre tende a aumentar e, a menos que combatamos isso, em breve nos afogaremos em complexidade. Também é interessante ver que, nos últimos anos, as linguagens de programação evoluíram para incentivar ou mesmo reforçar as práticas mencionadas acima. Particularmente, a ascensão das linguagens funcionais é exatamente isso: funções puras sempre retornam o mesmo valor para a mesma entrada, não há estado nelas. Depois, você apenas compõe funções puras que recebem e retornam valores imutáveis e limitam a inevitável mutabilidade a pequenos lugares bem definidos, em vez de espalhá-lo por toda parte. Confira: http://clojure.org/state
fonte
A diferença é quanto mais fácil e mais barato é modificar o software comparado ao hardware. Se o hardware fosse tão fácil e barato de modificar e enviar aos clientes, eles o fariam.
Você definitivamente deve verificar o desenvolvimento orientado a testes .
fonte
Vou comentar algumas de suas observações, esperando que você obtenha a resposta desses comentários.
Isso ocorre porque a especificação da solução está incompleta ou porque o plano para fornecer aprimoramentos não é preciso. Isso pode acontecer com qualquer software, hardware ou qualquer outro projeto.
Obviamente, a criação de módulos independentes deve reduzir bastante a dependência. Isso deve ser considerado quando você estiver projetando o software. É necessário considerar a separação de preocupações, camadas, camadas, objetos do controlador, interfaces, etc.
1-Entenda os requisitos com cuidado. Pode ser que você precise considerar o fechamento dos requisitos antes do design. Se você fizer desenvolvimento iterativo, não há chance de fazer isso. Algumas metodologias encorajam isso, mas, pessoalmente, acho que isso não é bom para todos os tipos de projetos. Construir software com requisitos sólidos permite um melhor design.
2-Faça seu usuário entender essa filosofia de longo prazo.
Planeje a implementação cuidadosamente
4-Design antes do código.
5-Use design genérico quando apropriado.
6-Use protótipos como uma ferramenta de confirmação de design.
fonte
Como as pessoas costumam ser muito rápidas em apontar, um dos benefícios do software é que é fácil e relativamente barato mudar em comparação com o hardware. Isso é especialmente importante quando você percebe tarde que algo está errado. Faça o mesmo com o hardware e você perderá um milhão de dólares; portanto, como já disse, usa seus simuladores, etc., e testa o bazinga com ele. Acho que é aí que o paradigma falha um pouco quando você muda para o software.
Entre na cabeça do desenvolvedor de software comum, e o que você tem é uma pessoa muito ocupada, com um prazo incrivelmente apertado. Seu gerente está dizendo que não há problema em deixar alguns erros, porque você sempre pode corrigi-lo mais tarde. Os testes geralmente são uma reflexão tardia, mas mesmo em um cenário orientado a testes, os testes são mantidos mínimos e o código é gravado no mínimo dos testes, e geralmente são atalhos para que muitos dos casos de fronteira possam ser perdidos. O sistema pode ser exaustivamente testado em unidade, mas raramente é rigorosamente testado como um todo, e tão raramente quanto testado em grande escala. Acrescente a isso que você escreve software do zero e há poucas oportunidades de simular o software antes de se comprometer a escrevê-lo, principalmente porque raramente escrevemos software com o mesmo tipo de blocos de construção refinados que você encontraria no hardware.
De volta à pergunta do OP. Você poderia definir um sistema de blocos de construção para derivar todo o seu software? Possivelmente. Seria muito rentável? Provavelmente não, porque no momento em que você começa a desenvolver um sistema robusto o suficiente de componentes, testes e outras parafernálias para suportar esse idealsistema de programação, você descobriria que sua concorrência já o derrotaria no mercado e, pior ainda, do ponto de vista do programador médio, você provavelmente acharia um estilo de sistema de programação "cortador de biscoitos" muito limitador e provavelmente muito entediante. Pessoalmente, trabalho em uma API, onde a maior parte do código do módulo foi refinada e padronizada tão completamente, que tudo o que faço agora é gerar um modelo de código e preencher os espaços em branco. A maior parte do meu tempo pode ser gasta escrevendo código de conector simples e colocando os módulos fora da porta o mais rápido possível. É seriamente entorpecente. Há muito pouca oportunidade de fazer mais do que apenas codificar os mesmos tipos de coisas repetidas vezes; portanto, quando outra oportunidade de projeto aparece, aproveito a chance de poder fazer QUALQUER OUTRA COISA.
Então, como você pode entregar software de alta qualidade e bem fatorado e ainda assim se divertir fazendo isso? Acredito que isso se resume a sua escolha de ferramentas e metodologia. Para mim, a resposta foi empregar o uso de uma boa API BDD, porque me permitiu criar um código muito fácil de ler, mas altamente granular. Posso criar um conjunto de testes com um número mínimo de métodos reutilizáveis e descrever meus testes no idioma das especificações. Dessa maneira, chego perto de uma abordagem de desenvolvimento mais componente, exceto pelo fato de ser responsável por projetar e verificar os blocos de construção. Além disso, a saída do teste identifica a parte exata do teste em que a falha ocorre, para que eu não precise adivinhar se as falhas estão na configuração ou na afirmação.
Ajustar sua metodologia também ajuda. Sou um grande defensor da aplicação de princípios de desenvolvimento enxuto e de combiná-los com muitas das outras técnicas e princípios com os quais o movimento Agile está discutindo há muitos anos. Tendo eliminado a maioria das práticas inúteis que costumava achar tão frustrantes, ajudou muito a tornar o desenvolvimento uma atividade mais agradável. Ainda me resta a questão de que, às vezes - mas espero que não com muita frequência - bugs apareçam no meu código, agora eu me encontro com mais tempo e ainda mais incentivo para gastar mais tempo escrevendo testes mais robustos e buscando 100 % de cobertura de teste. Melhor ainda, é ótimo ver todas essas luzes verdes aparecerem no final do meu dia,
fonte
Se isso o frustra, considere uma carreira diferente. A sério.
O objetivo do software é poder adicionar recursos. Todo o motivo para inventar "software" em primeiro lugar foi para podermos adicionar recursos.
Esse é um problema de controle de qualidade.
Isso também é verdade em software.
Sim. Você precisa realmente praticar a garantia da qualidade.
fonte
Eu recomendo que você analise os " métodos formais " para verificar a correção de projetos e software. As ferramentas do simulador usadas para o design de hardware estão tentando fazer algo próximo. Não acredito que as ferramentas para métodos formais estejam perto de serem úteis na indústria no momento, e as únicas indústrias que têm fortes incentivos para evitar defeitos são a aviônica e a medicina (curiosamente, a FDA diz claramente que "o software é diferente do hardware "nesse link). Além disso, se você estiver desenvolvendo com o Verilog / VHDL, estará seguindo a lógica binária. Isso reduz drasticamente a complexidade. Não haverá um hardware equivalente a um problema do Y2K.
O grande problema é que as coisas são complexas. E você não pode eliminar a complexidade, apenas pode movê-la.
fonte
No mundo do software, chamamos esse "módulo" de biblioteca e a usamos da mesma maneira. Muitas bibliotecas são construídas a ponto de funcionarem bem e, em seguida, ficam satisfeitas realizando seus trabalhos sem alterações até que Algo Importante leve à próxima revisão. Pense neles como um software repleto de epóxi :-)
Hogwash. Talvez você seja pessoalmente melhor do que muitas outras pessoas de "hardware" de ferro sem solda, mas já vi vários projetos de circuitos ruins, chips com falha ( por exemplo , o famoso problema da Intel "f00f"), mas isso não acontece fale com o campo como um todo. E, à medida que o material falsificado se torna "mais suave", os problemas se tornam mais difíceis de evitar.
Sim. Nós simplesmente não usamos muito essas metodologias. Eles tendem a ser extremamente caros para operar, e a maioria dos programadores não gosta de trabalhar dentro de suas restrições. Mas quando a vida humana está envolvida, por exemplo, bem, sim, tentamos não matar os usuários.
Um último ponto: o software tem um modelo financeiro diferente do hardware, mesmo o hardware programado. A maioria dos softwares que não são de consumo, e alguns também, são vendidos de uma maneira que incentive a mudança. Quando você pode dizer a uma empresa "Pague US $ 10.000 agora mais 18% ao ano", poderá essencialmente revender o produto a cada poucos anos. Mas para justificar essa taxa, você precisa fornecer ao cliente as alterações que ele deseja. Hmm ... pensando na curva de obsolescência de hardware da Apple, talvez isso não faça diferença, afinal - o hardware faz com que você realmente o compre novamente!
fonte
Gostaria muito de encontrar uma resposta final para sua pergunta. Mas a realidade é que não há uma maneira fácil de fazer isso, é por isso que a programação extrema e as técnicas de TDD estão se tornando tão populares. Você precisa abraçar a mudança, porque isso vai acontecer. Eu não sei se é mais engraçado dessa maneira, mas muito menos estressante, com certeza ;-)
http://en.wikipedia.org/wiki/Extreme_Programming
Quando você interage com o hardware, o hardware precisa de x valor e isso é tudo (em teoria), mas quando você interage com as pessoas hoje elas precisam de x, e amanhã podem precisar de y etc. É assim que as coisas mudam, os requisitos de negócios e de pessoas mudam. . Porque People! = Máquinas, o código que NUNCA muda na maioria das vezes não é possível.
Além disso, como eu disse na minha resposta excluída / anterior, tente evitar alterações que não são importantes, fazendo as pessoas pensarem antes de começar a codificar. Envolva os usuários mais na tomada de decisões, etc. Esclareça os custos das mudanças, planeje mais etc. Essas não são "formas de codificação", são formas de "não codificação" porque, com mais informações sobre os requisitos, haverá menos alterações e mais diversão.
fonte
Sim. Apenas tome cuidado como se estivesse desenvolvendo hardware, teste tudo o que puder e seu software será de qualidade semelhante.
a propósito, você nunca ouviu falar de insetos HW? Muito mais desagradável que qualquer bug do SW e mais difícil de corrigir (não apenas atualizando o software)
fonte
Eu também apontaria que os erros de software no hardware geralmente podem matar pessoas. Portanto, são necessários mais cuidadosos para determinar completamente os requisitos e testá-los extensivamente com antecedência. E esses requisitos não precisam ser alterados até que o hardware o faça. E como o novo hardware pode exigir uma reescrita, eu suspeito que o cruft também não acumula tanto.
Por outro lado, os requisitos comerciais mudam constantemente; às vezes, dificilmente é possível obter um requisito em produção antes que uma alteração seja solicitada. Às vezes, o requisito foi alterado várias vezes antes de chegar à produção. Isso é resultado de várias coisas. Primeiro, a parte interessada do projeto do lado dos negócios geralmente fica menos interessada em gastar tempo para definir minuciosamente o que ele quer, porque é "ocupado" e "importante" e as pessoas não morrem e as famílias o processam ou o jogam na prisão se ele acaba com sua parte do processo. Segundo, as partes interessadas no projeto tendem a ter uma idéia melhor do que desejam que o hardware faça, pois é menos abstrato para elas. Eles realmente não sabem o que querem até vê-lo. O que é menos problemático com o hardware.
fonte
Existem ferramentas de alto nível com muitos 'tijolos' acabados, como você os chama, que você pode combinar em aplicativos. Os tijolos são peças acabadas para você usar, basta combiná-las. Talvez você pense que é mais fácil ... até que seu cliente solicite algumas mudanças estranhas e inesperadas.
fonte