Estabalecer um contrato de uso independentemente da implementação de dito contrato.
Em uma aplicação é comum centralizarmos as mecânicas que são aplicadas aos dados de forma independente dos dados. No passado fizemos isto com rotinas, procedimentos e funções. Passamos alguns parâmetros e esperamos algum resultado; explicita (funções) ou implicitamente (rotinas). Nos dias de hoje com a Orientação a Objetos fazemos o mesmo utilizando métodos.
Tradicionalmente os métodos produzem resultados sobre os dados do objeto a que estão associados, mas nem sempre assim é. Um método que calcule a soma de dois números irá retornar um resultado em que nada altera os números originais. Diferenciamos o que chamamos de objeto sem estado ( stateless ) e objeto com estado ( statefull ).
Serviços são objetos que produzem resultados (como cálculos) ou mudanças no estado da aplicação, por exemplo guardando dados em um banco de dados. Contudo um serviço é um pouco mais que simples métodos que fazem coisas. Serviços , como no mundo real, são definidos através de contratos assinados por duas ou mais partes.
O propósito do padrão Service (Serviço) é definir separadamente o contrato do serviço e o provedor do serviço ( a implementação). Desta forma, diversos e diferentes formas de prover o mesmo serviço podem ser realizadas sem modificar o contrato. Com isto, o implementador pode modificar a sua implementação sem que o cliente (que usa o serviço) tenha que modificar as suas invocações.
Isto é útil, por exemplo, para provermos implementações especiais que são usadas em testes automatizados.
A implementação de um serviço tem duas fases. A primeira é definir o contrato. A segunda, definir a implementação. A primeira fase passa por definir uma simples interfaces. O quê o serviço pode fazer, quais argumentos necessita, quais resultados produz e que exceções podem acontecer. Em java isto é conseguido com uma interface java onde são declarados os métodos que é possível invocar no serviço. A interface passa a ser um documento formal, onde inclusive a informação contida no javadoc deve ser seguida à risca.
A segunda fase é implementar a interface. Para isso basta criar um classe que implemente a interface e implemente cada método da forma acordada na interface. Múltiplas implementações do mesmo serviço podem ser feitas, com propósitos diferentes para acomodar diferentes necessidades. Por exemplo, podemos pensar em um serviço de cache ou um objeto de mock para testes.
A parte mais importante de um Serviço é que ele possa ser acessado pelo seu contrato. Em teoria não importaria com que tecnologia esse contrato é implementado. É claro, que na prática, isso é uma limitação. Estabelecer o contrato com uma interface Java significa que nenhuma outra tecnologia pode ter acesso a ele, já que uma interface java só funciona em uma JVM.
O assunto de prover contratos "universais" é antigo e várias soluções foram encontradas ao longo dos anos. Tecnologias como CORBA, SOAP e mais recentemente gRPC são expressões das tentativas de desacoplar a definição lógica do contrato, da representação física do contrato. O padrão de web services que se utiliza do protocolo HTTP para prover comunicação física e de um segundo padrão de dados como XML ou JSON para prover o transporte entre dois extremos do serviço é o mais amplamente utilizada.
Com a facilidade de uso de Serviços e a facilidade de compor serviços utilizando serviços "menores", trouxe a ideia de arquiteturas orientadas a serviços (SOA). SOA não é sobre usar web services com SOAP e XML é sobre usar serviços com contratos agnósticos em que se inclui aqueles definidos com SOAP e XML , mas também os definidos com interfaces java ou .net ou qualquer outra tecnologia.
Atualmente o padrão SOAP ganhou má reputação e alternativas como gRPC tentam pegar o seu lugar, mas sendo o gRPC um padrão binário encontra o mesmo tipo de problemas que o CORBA já enfrentava.
O conceito de usar contratos fortes se diluiu nestas primeiras decadasdo seculo XXI a as pessoas passaram a usar REST baseados em simples comandos HTTP associados aos métodos padrão HTTP como GET e POST. Este tipo de contrato de serviço foca no contrato já provida e implementado pelo HTTP para ser a base da comunicação entre máquinas. Os serviços são implementados em cima desse contrato. Contudo ha algumas lacunas no mapeamento entre o que o HTTP provê e o que os serviços reais precisam.
No mundo java, não precisamos ir muito longe para encontra exemplos do uso de serviços e SOA. Toda a especificação EJB é baseada em serviços. Os chamados Stateless Enterprise Java Beans e Statefull Enterprise Java Beans são exemplos claros de serviços em java e a especificação JEE nada mais é do que um sabor especifico de SOA.
EJB Statless de serviço criados em ambiente JEE podem ser fácilmente publicados como web services SOAP e portanto utilizados por outras plataformas.
O padrão DAO (Data Acess Object), assim como o padrão Repository, são também especializações do padrão Service fornecendo mecanismos para encontrar dados em algum banco de dados. É por isso que um DAO ou um Repository sempre são criados por meio de uma interface mais uma implementação.
O padrão Service é um dos padrões mais utilizamos no dia-a-dias de aplicações comerciais, escritas, ou não, para JEE, mas é aquele de que somos menos conscientes. Entender o conceito do padrão Service é fundamental para entender arquitetura de sistemas corporativos e de larga escala, já que os serviços são os componentes essenciais destas arquiteturas. Entender este conceito é também o primeiro passo para entender a importância de padrões como Proxy.
Por outro lado, não é toda a implementação com uma interface que é um serviço. Um componente vital para que algo seja considerado um serviço é o contrato, e o contrato tem que ser formal para que interface +
implementação sejam instancias de um serviço.
O padrão Service se relaciona a muitos outros padrões. O primeiro passo para usar um serviço é encontrar um implementação que possamos usar, isso nos remete para o padrão Service Locator que permite encapsular a logica de procura da implementação. A opção de encontrar a implementação do serviço em uma máquina diferente daquela onde o queremos usar é muito grande e isso nos leva ao uso do padrão Proxy que permite esconder todos os truques tecnicos para invocar o serviço remotamente ( com ou sem web services).
As implementações do serviço são normalmente registradas em algum ponto centralizado com o uso de Registry.
É possível criar serviços compondo outros serviços já previamente existentes. Isso é normalmente feito com um serviço que simplifica as chamadas e trata o fluxo de invocar os diferentes serviços compostos. O padrão Service Façade ( mais conhecido apena como Façade) é utilizado para realizar esta composição.
Finalmente, o padrão Service é o padrão por detrás da origem dos famosos DAO e Repository. Estes padrões nada mais são, do que serviços especializado em trabalhar com dados. As mesmas regras que se aplicam a serviços se aplicam a estes serviços.