Quão essencial é criar uma camada de serviço?

68

Comecei a criar um aplicativo em 3 camadas (DAL, BL, UI) [ele lida principalmente com CRM, alguns relatórios de vendas e inventário].

Um colega me disse que devo mudar para o padrão da camada de serviço, que os desenvolvedores chegaram ao padrão de serviço a partir de sua experiência e é a melhor abordagem para projetar a maioria dos aplicativos. Ele disse que seria muito mais fácil manter a aplicação no futuro dessa maneira.

Pessoalmente, tenho a sensação de que está apenas tornando as coisas mais complexas e não pude ver muitos benefícios que justificariam isso.

Este aplicativo possui uma pequena interface de usuário parcial adicional que usa algumas (mas apenas algumas) das funções de aplicativos da área de trabalho, então me vi duplicando algum código (mas não muito). Só por causa de alguma duplicação de código, eu não o converteria para ser orientado a serviços, mas ele disse que eu deveria usá-lo de qualquer maneira, porque em geral é uma arquitetura muito boa, por que os programadores são tão apaixonados por serviços?

Tentei pesquisar no Google, mas ainda estou confuso e não consigo decidir o que fazer.

BornToCode
fonte

Respostas:

58

O livro de Martin Fowler, "Patterns of Enterprise Architecture", afirma:

A pergunta mais fácil de responder é provavelmente quando não usá-lo. Você provavelmente não precisa de uma Camada de Serviço se a lógica de negócios de seu aplicativo tiver apenas um tipo de cliente - por exemplo, uma interface de usuário - e as respostas de casos de uso não envolverem vários recursos transacionais. [...]

Porém, assim que você imaginar um segundo tipo de cliente ou um segundo recurso transacional nas respostas de casos de uso, vale a pena projetar em uma Camada de Serviço desde o início.

Os benefícios que uma Camada de Serviço oferece é que ela define um conjunto comum de operações de aplicativos disponíveis para diferentes clientes e coordena a resposta em cada operação. Onde você tem um aplicativo que possui mais de um tipo de cliente que consome sua lógica de negócios e possui casos de uso complexos envolvendo vários recursos transacionais - faz sentido incluir uma Camada de Serviço com transações gerenciadas.

Com CRM, Vendas e Inventário, existem muitos casos de uso do tipo CRUD, dos quais quase sempre existe uma correspondência individual com as operações da Camada de Serviço. As respostas à criação, atualização ou exclusão de um objeto de domínio devem ser coordenadas e transacionadas atomicamente pelas operações da Camada de Serviço.

Outro benefício de ter uma Camada de Serviço é que ela pode ser projetada para invocação local ou remota, ou ambas - e oferece flexibilidade para isso. O padrão estabelece as bases para a implementação encapsulada da lógica de negócios de um aplicativo e a invocação dessa lógica por vários clientes de maneira consistente. Isso significa que você também reduz / remove a duplicação de código, pois seus clientes compartilham os mesmos serviços comuns. Você também pode reduzir potencialmente os custos de manutenção - como quando a lógica de negócios muda, geralmente você só precisa alterar o serviço, e não cada um dos clientes.

Em resumo, é bom usar uma Camada de Serviço - mais, acho que no seu exemplo você forneceu, pois parece que você tem vários clientes da lógica de negócios.

Deco
fonte
2
Curiosamente, Martin Fowler defende a mesma interface para invocação local e remota, argumentando que a enorme diferença de desempenho na invocação remota força uma interface mais granular.
psr
Não entendi bem o seu parágrafo With CRM, Sales and Inventory there will be a lot of CRUD-type use cases of which there is almost always a one-to-one correspondence with Service Layer operations- se é sobre várias interfaces de usuário, como o CRUD chega aqui? E se eu não precisar de várias interfaces de usuário, mesmo que o CRUD funcione bem com os serviços, ainda assim não criaria uma camada de serviço, se entendi corretamente, e realmente espero que sim, porque prefiro manter as coisas simples (a camada de serviço é uma para minha opinião inexperiente)
BornToCode 4/12/12
4
Nesses casos, é raro haver apenas um cliente que possa tirar proveito disso. Se você tivesse apenas uma interface do usuário, posso pensar em dois motivos pelos quais você ainda pode querer a camada de serviço: segurança e reutilização. Uma configuração típica da empresa teria o aplicativo de interface do usuário disponível para clientes externos e sua camada de serviço disponível apenas na rede. Portanto, o servidor da Web delagra o trabalho para uma parte bloqueada da sua rede. No exemplo de vendas, você poderia reutilizá-lo se obtiver vendas no seu site e expandir para o eBay ou Amazon. Agora você tem uma interface do usuário, mas vários clientes.
23412 Phil
5
Apenas para adicionar ao comentário de @PhilPatterson. Vários clientes não precisam apenas ser baseados na interface do usuário. Pense em serviços da web ou bibliotecas - eles também podem ser clientes. Sua interface do usuário front-end pode usar a camada de serviço, bem como os serviços de software que você empacota e permitir que outra pessoa use.
Deco
você pode fornecer um exemplo de uma camada de serviço?
user962206
34

Adicionando uma camada de serviço porque você avaliou a ideia e concluiu a melhor abordagem: boa

Adicionando uma camada de serviço porque é isso que todas as crianças legais estão fazendo: ruim

Se seu intestino diz que você não precisa de um, não faça um.

Um dos desenvolvimentos mais decepcionantes no mundo da programação nos últimos 10 anos, mais ou menos, é que ele se tornou irritantemente orientado para a 'moda', com pessoas seguindo tendências e bandwagons como se fossem os sapatos desta temporada. Não caia nessa armadilha. Porque na próxima temporada 'todo mundo' estará lhe dizendo que você deveria ter projetado de outra maneira.

Não há nada de errado ou certo com uma camada de serviço - é uma abordagem específica cuja adequação deve ser avaliada em seus méritos técnicos para o projeto em questão. Não se sinta compelido a substituir a opinião de outras pessoas por seu próprio julgamento.

GrandmasterB
fonte
27
Isso não aborda o assunto de maneira alguma, apenas faz uma declaração / discurso geral sobre práticas de desenvolvimento que, depois de substituir algumas palavras, poderiam se aplicar a praticamente qualquer pergunta neste site. Da leitura desta resposta, eu não estou mesmo convencido de que você sabe exatamente o que uma camada de serviço é .
Aaronaught 29/08/12
12
Certamente pode ser aplicado a outras questões ... não o torna menos verdadeiro. O fato é que nem você nem eu temos o contexto necessário para declarar o que ele precisa em seu projeto; portanto, dizer a ele que sim ou não, não é apenas um palpite e não profissional. O que o OP precisa aqui é de um pouco de apoio moral para tomar as decisões que ele sabe serem as corretas.
GrandmasterB
5
@Aaronaught Independentemente da exatidão da resposta, ele ainda está essencialmente respondendo à pergunta principal: "Quão essencial é uma camada de serviço?". Ele afirma que não é absolutamente essencial e que é possivelmente apenas uma moda passageira. Se você não concordar com a resposta, faça o voto negativo.
maple_shaft
2
@GrandmasterB Eu diria que as modas são boas no desenvolvimento de software. A maioria dos desenvolvedores é muito nova ou incompetente para tomar decisões bem informadas sobre design e arquitetura. Ainda esperamos que eles produzam alguma aparência de software funcional, portanto, pular em um movimento e ser consistente com uma má escolha de design é muito preferível e mais sustentável do que a maneira como as coisas eram feitas anos atrás, onde codificávamos cowboys em tudo o que eles não entendi ou apreciei.
maple_shaft
10
@maple_shaft Apenas para esclarecer, não estou dizendo que as Camadas de Serviço são uma moda passageira. Estou dizendo, com base na maneira como a pergunta foi feita, que parece que há comportamento de moda / moda / moda por parte de seus colegas para forçá-lo a usar uma arquitetura que ele acha que não é garantida em seu projeto. Esclareço na minha resposta que vejo Camadas de Serviço (ou qualquer outro conceito) apenas isso - conceitos neutros cuja adequação deve ser avaliada por mérito próprio para projetos individuais. Eles não devem ser aplicados / usados ​​quando o próprio julgamento diz que não é necessário.
GrandmasterB
22

Existem muitos fatores que levam à decisão de criar uma camada de serviço. Eu criei camadas de serviço no passado pelos seguintes motivos.

  1. Código que precisa ser reutilizado por vários clientes.
  2. Bibliotecas de terceiros para as quais temos licenças limitadas.
  3. Terceiros que precisam de um ponto de integração em nosso sistema.
  4. Centralizando a lógica de negócios duplicada.

Caso 1: Você está criando uma funcionalidade básica que precisa ser usada por uma infinidade de clientes diferentes. A camada de serviço se baseia na funcionalidade de diferentes clientes para acessar a funcionalidade fornecida imediatamente.

Caso 2: você normalmente hospeda o código no espaço do aplicativo, mas está usando uma biblioteca de terceiros para as quais possui licenças limitadas. Nesse caso, você tem um recurso que gostaria de usar em qualquer lugar, mas apenas um número limitado deles. Se você hospedá-lo atrás de um serviço, toda a organização poderá utilizá-lo em seus aplicativos sem precisar comprar uma licença para cada hospedagem individual.

Caso 3: você está criando funcionalidade para terceiros se comunicarem com você. No seu exemplo, você pode configurar um ponto de extremidade de inventário para permitir que os fornecedores passem mensagens para você sobre remessas de produtos recebidas.

Caso 4: você analisou seu código em toda a empresa e descobriu que equipes separadas criaram a mesma coisa (apenas implementadas de maneira um pouco diferente). Com uma camada de serviço, você pode escolher as melhores abordagens e agora pode implementar o processo da mesma forma em todas as equipes, solicitando que elas entrem no serviço. Outro benefício para centralizar a lógica é quando erros são encontrados. Agora você pode implantar a correção uma vez e todos os clientes desfrutam do benefício ao mesmo tempo.

Tudo isso dito, existem potenciais negativos para uma camada de serviço.

  1. Adiciona complexidade do sistema. Onde antes você tinha apenas um aplicativo para depuração, agora você tem dois. Os problemas de produção exigem a verificação das configurações do aplicativo cliente, do aplicativo de serviço ou dos problemas de comunicação entre os aplicativos cliente e servidor configurados corretamente. Isso pode ser complicado se você nunca fez isso antes.
  2. Um ponto de falha. Se você tiver uma falha de serviço, todos os clientes serão afetados. Quando o código não é implantado dessa maneira, o risco pode ser menor (embora haja maneiras de atenuar isso).
  3. O controle de versão pode ser mais difícil de fazer. Quando você tem um aplicativo usando um serviço, as alterações na interface podem ser feitas ao mesmo tempo entre os dois. Quando você tem vários clientes agora, deve gerenciar quem está na V1, quem está na V2 e coordenar a remoção da V1 (depois de saber que todos foram atualizados para a V2).

O ponto principal é que nem sempre é um slam dunk tornar o serviço do sistema orientado. Na minha experiência, geralmente é uma boa ideia (costumo estruturar aplicativos dessa maneira), mas não é uma decisão automática. No final do dia, você precisa pesar os prós e os contras e tomar a decisão certa para sua situação.

Phil Patterson
fonte
2
+1 Obrigado pela resposta informativa. Eu realmente tinha dúvidas quanto ao tempo para aceitar sua resposta ou a resposta de Deco. Eventualmente, porque não tenho muita experiência, decidi escolher a resposta que mais recebe votos. Ainda sinto que sua resposta merece mais votos positivos. De qualquer forma, eu realmente aprecio o fato de você ter compartilhado seu conhecimento e experiência. Obrigado!
BornToCode 4/12/12
11
Não há de quê! O ponto principal a ser retirado das duas respostas é que se trata principalmente de resolver problemas de manutenção com vários clientes que precisam fazer a mesma coisa. Quanto maior o número de clientes que usam o serviço, maior o ganho de manutenção para você.
Phil Patterson
11
Também há segurança - as camadas de serviço podem fornecer outra barreira para os hackers violarem e chegarem ao tesouro no banco de dados. A falta de camadas de serviço talvez seja o motivo pelo qual tantos sites sofrem violações enormes; com um serviço no meio, os hackers obtêm significativamente menos dados antes de serem detectados.
Gbjbaanb #
6

A maioria das camadas de serviço que vi são uma bagunça completa. Os serviços tendem a ter muitos métodos diferentes, 1500 LOC não são raros. Os diferentes métodos não têm nada em comum, mas compartilham código. Isso resulta em alto acoplamento e baixa coesão . Ele também viola o OCP , porque toda vez que uma nova operação é necessária, é necessário modificar o código em vez de estender a base de código. Uma camada de serviço bem construída é teoricamente possível, mas nunca a vi na prática.

O CQRS resolve esses problemas e evita que você precise criar uma dessas camadas de serviço processuais.

Jeroen
fonte
2
Bem construído pelos padrões de quem? Certamente pelos padrões OO, uma interface da camada de serviço é uma destruição completa de uma bagunça. De uma perspectiva funcional ou processual, ele incentiva uma bela abordagem de design em camadas. Acho que o maior problema que as pessoas têm com as camadas de serviço é que elas incentivam um aplicativo baseado em transações sem estado e desencorajam uma abordagem orientada a objetos pura. Eu posso entender os dois lados do argumento.
maple_shaft
6

Adicionar uma interface (uma camada de serviço é um tipo de interface) leva tempo. Uma boa leva muito tempo para projetar e testar. É muito importante acertar na primeira tentativa, porque alterá-lo mais tarde quebra todos os clientes. Além disso, considere que você provavelmente não saberá o que precisa estar nessa interface até ter um segundo cliente com necessidades ligeiramente diferentes. Manter um serviço é um projeto interminável por si só.

Na maioria das organizações, se você for ao seu patrocinador comercial e perguntar: "Deseja que outros departamentos obtenham o benefício (reutilize) desse sistema que estamos desenvolvendo com o seu orçamento?" eles vão rir de você. Faça com que ele funcione primeiro para o seu patrocinador comercial e comece a mexer na reutilização desse código (no tempo do seu departamento).

Se você sabe, de fato, que a funcionalidade que você está escrevendo hoje será reutilizada por vários clientes de serviço diferentes, considere projetar uma camada de serviço desde o primeiro dia. Se você não tiver certeza, ou se já houver muitas incógnitas no projeto, faça com que algo simples funcione primeiro e separe-o em serviço e cliente mais tarde, se você tiver tempo e orçamento. É muito mais fácil acertar a interface de serviço na primeira tentativa quando você inicia com um sistema em funcionamento.

PS Se você estiver trabalhando em Java, Joshua Bloch tem muitos conselhos fantásticos sobre interface em seu livro, Effective Java.

GlenPeterson
fonte
Uma ótima resposta sem teorias estéreis.
danilo
2

Eu concordo com você. Não há necessidade de incluir mais uma camada se você estiver usando uma única interface do usuário.

DAL, BL e UI / Controller são uma boa combinação para projetar um aplicativo. Se você planeja usar uma única interface do usuário, não há necessidade de preparar uma camada extra. A inclusão de mais uma camada no aplicativo aumenta apenas os esforços / tempo de desenvolvimento.

Outro schenerio é usar várias UIs em seu aplicativo; é bom ter uma camada de serviço para lidar com UIs nesse caso.

Estouro de pilha: discussão sobre o padrão da camada de serviço

Satish Pandey
fonte
Então, você sugere que, em cada aplicativo complexo que ele desenvolva, ele use uma camada de serviço e não se acomode apenas com as camadas de DAL, BL e UI?
BornToCode
No caso de várias UIs, devemos incluir uma camada de serviço. No seu caso, não acho que seja necessário preparar uma nova camada. Apenas aumenta a complexidade do aplicativo.
Satish Pandey
0

Eu contestaria que seu BL é sua camada de serviço. Um local central onde está a sua lógica de negócios. Essa deve ser uma DLL que pode ser usada por qualquer coisa que precise dessa lógica. Em seguida, você pode colocar uma camada de API da Web se o seu aplicativo tiver diferentes interfaces de usuário.

user441521
fonte