Qual é um bom exemplo de cross-cutting concern? O exemplo do registro médico na página da Wikipedia parece incompleto para mim.
Especificamente a partir deste exemplo, por que o registro levaria à duplicação de código ( dispersão )? (Além de chamadas simples, como em log("....")todos os lugares, o que não parece grande coisa).
Qual é a diferença entre a core concerne a cross-cutting concern?
Meu objetivo final é obter uma melhor compreensão do AOP.
Antes de entender a preocupação transversal , temos que entender a preocupação .
Uma preocupação é um termo que se refere a uma parte do sistema dividida com base na funcionalidade.
As preocupações são de dois tipos:
As preocupações que representam uma funcionalidade única e específica para requisitos primários são conhecidas como preocupações centrais .
OU
A funcionalidade primária do sistema é conhecida como preocupação central. Por exemplo : lógica de negócios
As preocupações que representam funcionalidades para requisitos secundários são chamadas de preocupações transversais ou de todo o sistema .
OU
A preocupação transversal é uma preocupação aplicável a todo o aplicativo e afeta todo o aplicativo. Por exemplo: registro, segurança e transferência de dados são as preocupações necessárias em quase todos os módulos de um aplicativo, portanto, são questões transversais.
Esta figura representa um aplicativo típico dividido em módulos. A principal preocupação de cada módulo é fornecer serviços para seu domínio específico. No entanto, cada um desses módulos também requer funcionalidades auxiliares semelhantes, como registro de segurança e gerenciamento de transações. Um exemplo de interesses transversais é o "registro", que é freqüentemente usado em aplicativos distribuídos para ajudar na depuração rastreando chamadas de método. Suponha que façamos o registro no início e no final de cada corpo de função. Isso resultará no corte transversal de todas as classes que têm pelo menos uma função.
"A preocupação transversal é uma preocupação aplicável em todo o aplicativo" ➤ Não tenho certeza sobre isso, pois o gerenciamento de transações não é aplicável 'em todo' o aplicativo, mas ainda é uma preocupação transversal. E a imagem não me diz nada para ser honesto, é apenas confuso ..
Koray Tugay
Boa explicação, mas tenho um pequeno problema com a imagem em que chamamos essas preocupações, questões transversais e não transversais, e seria melhor, eu acho, cortar outras preocupações com questões transversais, e não outra maneira. Como o desenvolvimento orientado a aspectos
hyeganeh
ainda a resposta não explica o problema de simplesmente usar algo como Log4j e registrar como LogManager.getLogger (). info (ModuleName, msg)
Vicky Singh
49
Acho que o melhor exemplo de uma preocupação transversal é o comportamento transacional. Ter que colocar blocos try-catch com chamadas de confirmação e rollback em todos os seus métodos de serviço seria repulsivo, por exemplo. Anotar os métodos com um marcador que o AOP pode usar para encapsulá-los com o comportamento transacional desejado é uma grande vitória.
Outro bom candidato como exemplo de preocupação transversal é a autorização. Anotar um método de serviço com um marcador que diz quem pode chamá-lo e deixar alguns conselhos de AOP decidir se permite a chamada do método ou não, pode ser preferível a lidar com isso no código do método de serviço.
Implementar o registro com conselhos de AOP pode ser uma maneira de obter mais flexibilidade, de modo que você possa alterar o que é registrado alterando um ponto de junção. Na prática, não vejo projetos fazendo isso com muita frequência. Normalmente, usar uma biblioteca como log4j, que permite filtrar por nível de registro e categoria, em tempo de execução, se necessário, funciona bem o suficiente.
Uma preocupação central é o motivo da existência do aplicativo, a lógica de negócios que o aplicativo automatiza. Se você tiver um aplicativo de logística que lida com frete marítimo, descobrir quanta carga pode embalar em um caminhão ou qual é o melhor caminho para o caminhão levar para entregar suas entregas pode ser uma preocupação central. Questões transversais são normalmente detalhes de implementação que precisam ser mantidos separados da lógica de negócios.
Portanto, embora o comportamento transacional realmente só exista na camada de acesso a dados, porque os blocos try-catch são duplicados em vários métodos, ele é considerado corte transversal. Minha percepção original era que o corte transversal significava que o código abrangia várias camadas do aplicativo.
jlars62 de
4
@ jlars62: corte transversal significa que vai perpendicularmente aos recursos.
Nathan Hughes
7
@ jlars62: por ângulos retos, quero dizer: pense em um recurso como uma pilha de camadas. uma preocupação transversal pode se aplicar a apenas uma camada, mas é comum a todos os recursos.
Nathan Hughes
A autorização @NathanHughes é um bom exemplo. Acabei de refatorar meu aplicativo para colocar todo o código de autorização em uma arquitetura transversal e funcionou maravilhas para limpar muitos códigos. Considero o domínio como uma casa. Se você tiver a chave para entrar, pode fazer o que quiser lá (presume-se que seja o proprietário). Mas você não trancaria todas as portas da casa e exigiria uma entrada com chave. Você está dentro ou não.
richard
O "comportamento transacional" pode ser comum a muitos recursos, mas não será um "corte transversal" porque não está "cruzando" as camadas. O motivo, por exemplo, de registrar em log é uma preocupação transversal é porque eu posso querer fazer login na camada de apresentação, camada de negócios, camada de dados etc.
CodingYoshi
14
Além da resposta aceita, quero mencionar outro exemplo de uma preocupação transversal: comunicação remota. Digamos que eu apenas queira chamar outros componentes em meu ecossistema localmente como se eles estivessem em execução no processo. Talvez em alguns casos até façam. Mas agora quero executar meus serviços distribuídos em uma nuvem ou cluster. Por que devo me preocupar com esse aspecto como desenvolvedor de aplicativos? Um aspecto poderia cuidar de descobrir para quem ligar e como, serializando os dados transmitidos se necessário e fazendo uma chamada remota. Se tudo estivesse funcionando no processo, o aspecto apenas encaminharia a chamada local. No lado do receptor, o aspecto desserializaria os dados, faria a chamada local e retornaria o resultado.
Agora, deixe-me contar uma pequena história sobre coisas "triviais" como saída de log: apenas algumas semanas atrás, refatorei uma base de código complexa, mas não muito grande (cerca de 250 mil linhas de código) para um cliente. Em algumas centenas de classes, um tipo de estrutura de registro foi usado, em outras centenas de outras. Então, havia vários milhares de linhas deSystem.out.println(*)onde realmente deveria haver uma saída de log. Portanto, acabei corrigindo milhares de linhas de código espalhadas por toda a base de código. Felizmente, eu poderia usar alguns truques inteligentes no IntelliJ IDEA (pesquisa e substituição estrutural) para acelerar toda a ação, mas cara, você não acha que foi trivial! Claro, o registro de depuração fortemente dependente do contexto sempre ocorrerá dentro de um corpo de método, mas muitos tipos importantes de registro, como chamadas de método de rastreamento (mesmo hierarquicamente com uma saída bem recuada), registro de exceções manipuladas ou não, auditoria de usuário (registro de chamadas para métodos restritos com base em funções de usuário) e assim por diante podem ser facilmente implementados em aspectos sem que poluam o código-fonte. O desenvolvedor de aplicativos do dia a dia não precisa pensar sobre isso ou mesmo ver as chamadas do logger espalhadas pela base de código.
Posso apresentar explicações semelhantes para outras questões transversais. Manter o código limpo e livre de espalhamento e emaranhamento IMO é uma questão de profissionalismo, não algo opcional. Por último, mas não menos importante, ele mantém o código legível, sustentável e refatorável. Amém.
As preocupações transversais são os cenários que devem estar sempre presentes, independentemente do tipo de aplicação.
Por exemplo, registro, segurança, perfil de desempenho, localização, acessibilidade, transação, etc. Independentemente do software que estamos construindo, o registro é necessário (caso contrário, como alguém irá depurar ou obter algumas informações relevantes dos dados de produção). A segurança (autenticação / autorização, etc.) é necessária quando apenas o usuário autêntico pode entrar no aplicativo com o conjunto correto de privilégios. Precisamos saber como é o desempenho de seu aplicativo, então precisamos fazer o perfil. Caso o aplicativo seja usado por usuários internacionais (com seu próprio idioma localizado), precisamos oferecer suporte ao mesmo no aplicativo. Acessibilidade é casos de usabilidade para pessoas com deficiência usarem nosso aplicativo.
Agora, independentemente de nosso aplicativo ser baseado em desktop, web etc., se ele precisa ser usado por usuários finais em toda a geografia no ambiente de produção, então cortes transversais são necessários. Até agora eu não disse nada sobre o que é o aplicativo etc, mas dada a lista de preocupações que devem ser abordadas antes de liberá-lo para os usuários finais no ambiente de produção. e isso é tudo sobre questões transversais (que precisam ser tratadas por todos os aplicativos / métodos / classes, ou seja, em vários níveis).
Acho que o melhor exemplo de uma preocupação transversal é o comportamento transacional. Ter que colocar blocos try-catch com chamadas de confirmação e rollback em todos os seus métodos de serviço seria repulsivo, por exemplo. Anotar os métodos com um marcador que o AOP pode usar para encapsulá-los com o comportamento transacional desejado é uma grande vitória.
Outro bom candidato como exemplo de preocupação transversal é a autorização. Anotar um método de serviço com um marcador que diz quem pode chamá-lo e deixar alguns conselhos de AOP decidir se permite a chamada do método ou não, pode ser preferível a lidar com isso no código do método de serviço.
Implementar o registro com conselhos de AOP pode ser uma maneira de obter mais flexibilidade, de modo que você possa alterar o que é registrado alterando um ponto de junção. Na prática, não vejo projetos fazendo isso com muita frequência. Normalmente, usar uma biblioteca como log4j, que permite filtrar por nível de registro e categoria, em tempo de execução, se necessário, funciona bem o suficiente.
Uma preocupação central é o motivo da existência do aplicativo, a lógica de negócios que o aplicativo automatiza. Se você tiver um aplicativo de logística que lida com frete marítimo, descobrir quanta carga pode embalar em um caminhão ou qual é o melhor caminho para o caminhão levar para entregar suas entregas pode ser uma preocupação central. Questões transversais são normalmente detalhes de implementação que precisam ser mantidos separados da lógica de negócios.
fonte
Além da resposta aceita, quero mencionar outro exemplo de uma preocupação transversal: comunicação remota. Digamos que eu apenas queira chamar outros componentes em meu ecossistema localmente como se eles estivessem em execução no processo. Talvez em alguns casos até façam. Mas agora quero executar meus serviços distribuídos em uma nuvem ou cluster. Por que devo me preocupar com esse aspecto como desenvolvedor de aplicativos? Um aspecto poderia cuidar de descobrir para quem ligar e como, serializando os dados transmitidos se necessário e fazendo uma chamada remota. Se tudo estivesse funcionando no processo, o aspecto apenas encaminharia a chamada local. No lado do receptor, o aspecto desserializaria os dados, faria a chamada local e retornaria o resultado.
Agora, deixe-me contar uma pequena história sobre coisas "triviais" como saída de log: apenas algumas semanas atrás, refatorei uma base de código complexa, mas não muito grande (cerca de 250 mil linhas de código) para um cliente. Em algumas centenas de classes, um tipo de estrutura de registro foi usado, em outras centenas de outras. Então, havia vários milhares de linhas de
System.out.println(*)
onde realmente deveria haver uma saída de log. Portanto, acabei corrigindo milhares de linhas de código espalhadas por toda a base de código. Felizmente, eu poderia usar alguns truques inteligentes no IntelliJ IDEA (pesquisa e substituição estrutural) para acelerar toda a ação, mas cara, você não acha que foi trivial! Claro, o registro de depuração fortemente dependente do contexto sempre ocorrerá dentro de um corpo de método, mas muitos tipos importantes de registro, como chamadas de método de rastreamento (mesmo hierarquicamente com uma saída bem recuada), registro de exceções manipuladas ou não, auditoria de usuário (registro de chamadas para métodos restritos com base em funções de usuário) e assim por diante podem ser facilmente implementados em aspectos sem que poluam o código-fonte. O desenvolvedor de aplicativos do dia a dia não precisa pensar sobre isso ou mesmo ver as chamadas do logger espalhadas pela base de código.Posso apresentar explicações semelhantes para outras questões transversais. Manter o código limpo e livre de espalhamento e emaranhamento IMO é uma questão de profissionalismo, não algo opcional. Por último, mas não menos importante, ele mantém o código legível, sustentável e refatorável. Amém.
fonte
As preocupações transversais são os cenários que devem estar sempre presentes, independentemente do tipo de aplicação.
Por exemplo, registro, segurança, perfil de desempenho, localização, acessibilidade, transação, etc. Independentemente do software que estamos construindo, o registro é necessário (caso contrário, como alguém irá depurar ou obter algumas informações relevantes dos dados de produção). A segurança (autenticação / autorização, etc.) é necessária quando apenas o usuário autêntico pode entrar no aplicativo com o conjunto correto de privilégios. Precisamos saber como é o desempenho de seu aplicativo, então precisamos fazer o perfil. Caso o aplicativo seja usado por usuários internacionais (com seu próprio idioma localizado), precisamos oferecer suporte ao mesmo no aplicativo. Acessibilidade é casos de usabilidade para pessoas com deficiência usarem nosso aplicativo.
Agora, independentemente de nosso aplicativo ser baseado em desktop, web etc., se ele precisa ser usado por usuários finais em toda a geografia no ambiente de produção, então cortes transversais são necessários. Até agora eu não disse nada sobre o que é o aplicativo etc, mas dada a lista de preocupações que devem ser abordadas antes de liberá-lo para os usuários finais no ambiente de produção. e isso é tudo sobre questões transversais (que precisam ser tratadas por todos os aplicativos / métodos / classes, ou seja, em vários níveis).
fonte