Podemos facilitar a adição de fluxos de dados entre partes distantes de uma grande base de código?

10

Ao fazer alterações em sistemas grandes, geralmente enfrento o problema de que alguma funcionalidade precisa obter alguns dados de outra, mas eles estão em partes diferentes de uma árvore de chamadas profunda e ramificada, possivelmente fluindo através de ouvintes de eventos, chamadas adiadas, etc. Dessa maneira, uma simples alteração pode aumentar rapidamente.

Uma citação relacionada da postagem do blog de Yossi Kreinin em http://www.yosefk.com/blog/i-want-a-struct-linker.html :

Você tem algum tipo de estrutura de dados que você transmite bastante. Em breve, a coisa mais valiosa sobre a estrutura não são os dados que ela mantém, mas o fato de estar disponível durante todo o fluxo de controle.

As variáveis ​​globais são uma maneira clássica de deixar o código "gritar" para um código distante, mas são conhecidas por serem problemáticas. Variáveis ​​com escopo dinâmico são uma maneira mais restrita, mas também são problemáticas.

Existe alguma pesquisa em linguagem de programação com o objetivo de resolver esse problema? Podemos tornar mais fácil adicionar fluxos de dados imprevistos a uma grande base de código, enquanto ainda temos verificação estática, testes de unidade fáceis e outras vantagens?

Vladimir Slepnev
fonte
Do jeito que você está formulando sua pergunta, acho que você tem o fluxo de dados em um único processo, sem comunicação entre processos. Então, que tipo de problema você vê e que não pode ser resolvido pelos mecanismos padrão de remetente / ouvinte de eventos?
Doc Brown
Um exemplo inventado: imagine que, no fundo do seu sistema, existe algum código que envia ao usuário uma mensagem de texto. E você obtém um novo requisito de que o texto da mensagem dependa da hora atual no fuso horário do usuário. A pilha de chamadas é assim: algum código que conhece o fuso horário do usuário, chama um método que chama um método que (... repete 15 vezes) chama um método que gera o texto da mensagem. Este é um exemplo simples para meus padrões, porque envolve comunicação apenas para baixo, mas você ainda deve alterar as assinaturas de 15 métodos para fazer sua alteração trivial.
Vladimir Slepnev
Bem, acho que o que pode ajudar é modelar o fluxo de dados explicitamente e separar componentes do fluxo de dados. O engenheiro de software alemão está escrevendo muito sobre esse tópico, a maioria dos artigos em alemão. Aqui está um artigo de entrada em inglês dele: geekswithblogs.net/theArchitectsNapkin/archive/2011/03/19/…
Doc Brown
Eu acho que uma API interna de singleton poderia ajudar. Seria acessível em todo o aplicativo e encapsularia toda a lógica de recuperação de dados.
SuperM

Respostas:

1

Você está se referindo ao CDI (Injeção de Dependência de Contexto) AKA IoC (Inversão de Controle). Java JSF e Spring Framework são alguns exemplos. O ASP.NET MVC possui plugins como o Unity. Javascript está começando a ter estruturas organizadas usando bibliotecas como RequireJS, que possui comportamento de injeção visto em muitas estruturas JS modernas. Isso é para conectar aplicativos locais e remotos.

Para um acoplamento flexível entre redes, as empresas gostam de usar Web Services com SOAP, REST, AJAX ou chamada remota regular de método com RPC. Em Java, você pode usar JAX-WS ou .NET WCF para construir serviços distribuídos. Em seguida, você os alinha em um barramento de serviço ou "fluxo de dados" de qualquer idioma ou plataforma como cliente. Ruby, Python, Scala, Java, C #, ... qualquer coisa.

O acoplamento flexível permite dividir e conquistar problemas, e os serviços geralmente são o ponto de entrada para um banco de dados para extrair dados. Ao subir a escada, temos a besta chamada Fila de Mensagens. Esse caminho leva a estruturas de tipo de empresa e infraestrutura.

Se seu projeto insistir em nenhuma rede, existem idiomas como Scala, Akka, NodeJS etc. projetados para um alto fluxo de dados em um único aplicativo. Eles também trabalham com algumas ou todas as tecnologias mencionadas anteriormente para projetos complexos. Por exemplo, o Scala pode ser usado com os serviços REST JAX-RS para extrair uma espécie de "dados globais" de uma fonte de dados e ter Spring para a fiação interna de IoC. Existem também muitas estruturas de execução de negócios ou de fluxo de trabalho nas ferramentas JBoss, .NET e GUI, como o MuleESB. No desenvolvimento, o Eclipse e o Netbeans permitem arrastar e soltar serviços em uma tela visual de fluxograma.

Finalmente, Java ainda possui beans Singleton. Para ajustar seus métodos em tempo de execução, use estruturas de proxy ou reflexão. Mas, honestamente, isso é verdade em 1999.

Se você estiver fazendo tantas chamadas para enviar uma mensagem a um usuário com base no fuso horário, na minha opinião, provavelmente há uma maneira de duas etapas para obter o mesmo efeito que o usuário vê. Mas sim, as estruturas CDI são usadas pelas linguagens existentes, como um casaco que lhes oferece todos os poderes flexíveis que você mencionou. Eu gosto de chamá-lo de subconsciente do meu programa, cuidando do trabalho sujo sem problemas.

Senor Developer
fonte
As filas de mensagens podem ser um exagero, mas as mensagens são a maneira perfeita de gerar eventos de maneira geral. Java usa Message Driven Beans (MDB) e isso deve permitir que seu programa envie ou receba 'conversas' entre si. Você pode fazer isso dessa maneira para o bônus assíncrono.
Desenvolvedor Senor
Obrigado pelas indicações! Definitivamente, me faz pensar em como seria uma linguagem se ela fosse projetada desde o início para suportar injeção de dependência e padrões semelhantes.
precisa saber é o seguinte
0

A maneira mais simples de fazer isso em larga escala é de fato usar algum tipo de API de encapsulamento de dados. Pode ser um repositório NoSQL ou um RDBMS encapsulado (ou de fato pode estar em horários e locais diferentes no mesmo aplicativo - não há nenhuma razão para que você não possa ter um RDBMS lidando com longo prazo armazenamento e um banco de dados NoSQL lidando com controle de estado de curto prazo). Pode até ser uma série de objetos singleton.

Suas estruturas de dados podem ser disponibilizadas em algum tipo de espaço neutro, de uma maneira um pouco gerenciada. Essa é a abordagem que adotamos com o LedgerSMB (mas com algumas variáveis ​​semi-globais para os singletons essencialmente escondidos, mas, novamente, essas são gerenciadas, escolhemos esconder o objeto diretamente, porque isso facilitou um pouco o gerenciamento das variáveis, mas existem todos eles).

É claro que qualquer abordagem tem trocas e você não pode contornar essas trocas. A chave é analisar quais são as vantagens e desvantagens (gerenciamento x desempenho x limpeza do código x possíveis armadilhas de codificação) e tomar uma decisão com base no que é melhor para o seu aplicativo.

Chris Travers
fonte
Obrigado pela resposta! Parece-me que a pesquisa em linguagem de programação poderia ajudar com esse problema. Por exemplo, se o código ler alguns dados de um banco de dados global ou de singletons ocultos, poderá haver uma garantia estática / declarativa sobre quais dados ele requer.
precisa saber é o seguinte
-1

Se você usar (ou citar) as palavras

hairy flow of control

então eu assumo que seu código é realmente uma bagunça. Você deve largá-lo imediatamente. Se você usa modularização / separação de preocupações, não existe um "fluxo de controle cabeludo". Seu código simplesmente não possui simplicidade, o que também é inferível pelo fato de você ter consultado variáveis ​​globais :-).

user127749
fonte
Por que o voto negativo? Faltava a introdução da citação que justifica exatamente a minha opinião: "(provavelmente é classificada como" Antipadrão "ou" Cheiro de código "e, como tal, tem um nome nos círculos apropriados, mas eu não saberia, então vou deixe-o sem nome) "
user127749
2
Isto não é realmente uma resposta para a questão, que é provavelmente a razão para o downvote
Daniel Gratzer
Então deixe-me reformular a pergunta: existe algum truque de mágica para desfazer a bagunça do código que viola um dos princípios mais básicos do design de software: KISS (mantenha-o simples, estúpido)? O truque não é mágico, ou é um programador que não pode ser substituído porque conhece todos os detalhes não tão óbvios (que matarão a empresa a longo prazo) ou para reestruturar a base de código. Infelizmente, muitas empresas inicialmente não ligo para o projeto de código apropriada ou nem sequer compreende as consequências, em seguida, ter que reescrever seu código, pelo menos uma vez, muitos ainda reescrevê-lo muitas vezes ...
user127749