Notas sobre padrões de design Java para iniciantes - padrão decorador

O modo Decorador também é chamado de modo Wrapper.

 

1. A intenção é
adicionar dinamicamente algumas responsabilidades adicionais a um objeto.

 

2. Participantes
• Componente abstrato (Component): Define uma interface de objeto que pode adicionar dinamicamente responsabilidades a esses objetos.
• Componente Concreto: Defina um objeto e adicione algumas responsabilidades a este objeto.
• Decorador abstrato (Decorator): contém uma instância de um objeto componente e define uma interface consistente com a interface abstrata do componente .

• Decorador de Concreto: Adiciona responsabilidades aos componentes.

 

3. Estrutura


 


 No padrão de design de Yan Hong, é mencionado que “o padrão de decoração estende a funcionalidade dos objetos de forma transparente ao cliente e é uma alternativa às relações de herança”.

 

Primeiro, vamos entender o propósito do modo de decoração – adicionar dinamicamente algumas responsabilidades adicionais a um objeto. 

A chamada dinâmica significa que outras responsabilidades podem ser adicionadas dinamicamente ao objeto durante o tempo de execução do sistema (RunTime) sem a necessidade de modificar o código ou recompilar;

A chamada estática significa que o código (DesignTime) deve ser ajustado para adicionar responsabilidades ao objeto, e o sistema também precisa ser recompilado;

A partir de um nível técnico específico, a combinação e herança de objetos correspondem à dinâmica e estática anteriores

Deveríamos usar mais a composição de objetos para manter a escalabilidade do tempo de execução do sistema e usar herança o menos possível, porque a herança torna o programa rígido!

Isto é favorecer a composição em vez da herança.

 

 

Vamos entender a frase “O modo decoração estende a funcionalidade dos objetos de forma transparente ao cliente e é uma alternativa às relações de herança”. 

Decorator é uma classe muito especial no padrão decorator. Ela não apenas herda de Component (relacionamento É A), mas também mantém uma referência à instância do Componente (relacionamento TEM A). De outra perspectiva, entre Decorator e Component, ambos Combinação dinâmica relacionamentos também têm relacionamentos de herança estática.

Por que foi projetado assim?

A vantagem da composição é que você pode adicionar responsabilidades aos objetos em tempo de execução. O Decorator possui um componente ( HAS A ), que é projetado para permitir que decoradores concretos (Concrete Decorator) adicionem dinamicamente responsabilidades a componentes concretos (Concrete Component) em tempo de execução . é relativamente É relativamente fácil de entender; 

Então, qual é o propósito do Decorator herdar do Component?

Aqui a herança tem apenas um propósito, que é unificar as interfaces do decorador e do decorado.De outra perspectiva, seja um componente concreto (Concrete Component) ou um decorador concreto (Concrete Decorator) , ambos são Componentes. Usuários O código pode tratá-los como componentes. O benefício adicional disso é que a extensão das responsabilidades funcionais do objeto decorador para o objeto decorado é completamente transparente para o código do usuário , porque o código do usuário faz referência a todos. não haverá erros no código do usuário que se refere ao objeto decorado após ele ser decorado, na verdade não haverá impacto, pois antes e depois da decoração o código do usuário se refere a objetos do tipo Componente.

 

O padrão decorador unifica as interfaces do decorador e do objeto decorado por meio de herança e obtém a capacidade de estender dinamicamente o objeto decorado em tempo de execução por meio de composição .

 

 

Vamos ilustrar com um exemplo:

Primeiro, em vez de usar o modo decoração, pense em como atender aos seguintes requisitos.

1. Tomemos como exemplo a compra de um carro - os clientes vão a uma concessionária para comprar um carro, e o agente presta alguns serviços, inicialmente alguns serviços de manutenção pós-venda; 

2. Posteriormente, prestou também serviços de fornecimento de peças, depois prestou alguns serviços de consultoria (os agentes responderam a algumas dúvidas que os clientes tinham antes de comprar um carro) e, por fim, prestou serviços de seguro automóvel aos clientes.  

3. Se o agente necessita fornecer diferentes combinações de serviços de acordo com a situação.

 

(Não vou escrever código para implementá-lo aqui)

 

Na maioria dos casos, é utilizada herança, o que causa principalmente os seguintes problemas:

1. O sistema tem baixa escalabilidade;

2. Quando diferentes combinações de serviços precisam ser fornecidas, um grande número de classes precisa ser criado, causando explosão de classes;

 

Então, vamos ver como o modo de decoração atende aos requisitos acima. O código Java é o seguinte:

 Componente Resumo: Revendedor de automóveis 

/**
 * 抽象构件(Component)
 * 
 * 汽车销售商
 */
public interface CarSeller {
	
	/*
	 * 销售汽车
	 */
	String sellCars();

}

 

Componente de concreto: concessionária Audi 

/**
 * 具体构件(Concrete Component)
 * 
 * 奥迪汽车经销商
 */
public class AudiCarAgency implements CarSeller {

	/*
	 * 销售奥迪汽车
	 */
	public String sellCars() {

		System.out.println("销售奥迪汽车");
		
		return "奥迪汽车";
	}

}

 

Decorador: concessionário Audi oferecendo serviços 

/**
 * 抽象装饰者(Decorator)
 * 
 * 提供服务的奥迪销售商
 */
public class AudiCarAgencyWithServices implements CarSeller {

	private CarSeller carSeller = null;

	/*
	 * 构造函数
	 */
	public AudiCarAgencyWithServices(CarSeller carSeller) {
		this.carSeller = carSeller;
	}

	/*
	 * 装饰
	 * @see myDecoratorPattern.sellCars.CarSeller#sellCars()
	 */
	public String sellCars() {
		String carName = null;
		carName = carSeller.sellCars();
		return carName;
	}

}

 

Decorador de concreto: concessionário Audi que presta serviços de reparo 

/**
 * 具体装饰者(Concrete Decorator)
 * 
 * 提供维修服务的奥迪销售商
 *
 */
public class AudiCarAgencyWithMaintenance extends AudiCarAgencyWithServices {
	
	/*
	 * 构造函数
	 */
	public AudiCarAgencyWithMaintenance(CarSeller carSeller) {
		super(carSeller);
	}
	
	/*
	 * 添加了其他的服务
	 */
	public String sellCars(){		
		String carName = super.sellCars();
		System.out.println("提供维修服务");
		return carName;
	}

}

 

Decorador de concreto: revendedor Audi fornece fornecimento de peças de reposição 

/**
 * 具体装饰者(Concrete Decorator)
 * 
 * 提供零配件供应的奥迪销售商
 *
 */
public class AudiCarAgencyWithSparepart extends AudiCarAgencyWithServices {

	/*
	 * 构造函数
	 */
	public AudiCarAgencyWithSparepart(CarSeller carSeller) {
		super(carSeller);
	}
	
	/*
	 * 添加了其他的服务
	 */
	public String sellCars(){
		String carName = super.sellCars();
		System.out.println("提供零配件供应");
		return carName;
	}

}

 

Decorador de concreto: concessionário Audi que presta serviços de consultoria pré-venda  

/**
 * 具体装饰者(Concrete Decorator)
 * 
 * 提供售前咨询服务的奥迪销售商
 *
 */
public  class AudiCarAgencyWithConsultation extends AudiCarAgencyWithServices {
	
	/*
	 * 构造函数
	 */
	public AudiCarAgencyWithConsultation(CarSeller carSeller){
		super(carSeller);
	}
	
	/*
	 * 添加了其他的服务
	 */
	public String sellCars() {
		System.out.println("提供了售前咨询服务");
		return super.sellCars();
	}

}

 

Decorador de concreto: revendedor Audi que oferece serviços de seguros de automóveis

 

/**
 * 具体装饰者(Concrete Decorator)
 * 
 * 提供车险服务的奥迪销售商
 *
 */
public class AudiCarAgencyWithInsurance extends AudiCarAgencyWithServices {

	/*
	 * 构造函数
	 */
	public AudiCarAgencyWithInsurance(CarSeller carSeller) {
		super(carSeller);
	}
	
	/*
	 * 添加了其他的服务
	 */
	public String sellCars(){
		
		String carName = super.sellCars();
		System.out.println("提供车险的购买");
		return carName;
	}

}

 

A estrutura é a seguinte:

 

 

 

Chamada do cliente: 

public class Customer {
	
	public static void main(String[] args){
		
		String car = null;
		
		System.out.println("--------------只卖车,没有服务------------------");	
//		汽车经销商
		CarSeller carSeller = new AudiCarAgency();
		car = carSeller.sellCars();
		System.out.println("买到了" + car);
		
		System.out.println("--------------第一种组合-维修服务------------------");		
//		提供了维修服务
		CarSeller carSellerWithMaintenance = new AudiCarAgencyWithMaintenance(carSeller);
		car = carSellerWithMaintenance.sellCars();
		System.out.println("买到了" + car);
		
		System.out.println("--------------第二种组合-添加了零部件供应服务---------");		
//		提供了零部件供应		
		CarSeller carSellerWithSparepart = new AudiCarAgencyWithSparepart(carSellerWithMaintenance);
		car = carSellerWithSparepart.sellCars();
		System.out.println("买到了" + car);

		System.out.println("--------------第三种组合-添加了咨询服务--------------");		
//		提供了咨询服务		
		CarSeller carSellerWithConsultation = new AudiCarAgencyWithConsultation(carSellerWithSparepart);
		car = carSellerWithConsultation.sellCars();	
		System.out.println("买到了" + car);

		System.out.println("--------------第四种组合-添加了车险服务--------------");		
//		提供了车险	
		CarSeller carSellerWithInsurance = new AudiCarAgencyWithInsurance(carSellerWithConsultation);
		car = carSellerWithInsurance.sellCars();
		System.out.println("买到了" + car);
		
		
		System.out.println("#########################################");	
//		还可以有其他的组合方式
		System.out.println("还可以尝试其他形式自由的组合。。。。。。");
		
	}

}

 

 

resultado da operação:

--------------只卖车,没有服务------------------
销售奥迪汽车
买到了奥迪汽车
--------------第一种组合-维修服务------------------
销售奥迪汽车
提供维修服务
买到了奥迪汽车
--------------第二种组合-添加了零部件供应服务---------
销售奥迪汽车
提供维修服务
提供零配件供应
买到了奥迪汽车
--------------第三种组合-添加了咨询服务--------------
提供了售前咨询服务
销售奥迪汽车
提供维修服务
提供零配件供应
买到了奥迪汽车
--------------第四种组合-添加了车险服务--------------
提供了售前咨询服务
销售奥迪汽车
提供维修服务
提供零配件供应
提供车险的购买
买到了奥迪汽车
#########################################
还可以尝试其他形式自由的组合。。。。。。

 

Você pode ver que usar o modo decoração tem as seguintes vantagens: 

1. O objetivo do modo de decoração e do relacionamento de herança é estender a funcionalidade dos objetos, mas o modo de decoração pode fornecer mais flexibilidade do que a herança.

2. Ao usar diferentes classes de decoração específicas e as permutações e combinações dessas classes de decoração, os designers podem usar muito poucas classes para criar muitas combinações de comportamento diferentes.

 

O conteúdo acima é parcialmente referenciado em "Java and Patterns" de Yan Hong e detalhes de aplicação de exemplo de padrão de xícara de café-Decorator (Decorator)

 

Se você observar atentamente a invocação do modo decoração (por exemplo: a segunda combinação - adicionar um serviço de fornecimento de peças ), parece que o modo decoração e o modo proxy têm o mesmo efeito (ambos adicionam funções adicionais a um objeto); até mesmo , se comparados Parece não haver diferença na estrutura desses dois modos. Então, qual é a diferença entre eles?

 

Primeiro, suas intenções são diferentes:

O padrão proxy controla o acesso a um objeto.

O modo de decoração consiste em adicionar responsabilidades (funções) a uma classe.

 

A julgar apenas pela sua estrutura,

Ao usar o modo proxy, você também pode adicionar algumas operações adicionais antes ou depois de acessar o objeto. Nesse sentido, o modo de decoração é semelhante ao modo proxy. Pode-se até dizer que os dois modos são iguais, ambos adicionando uma classe (um objeto) outras funções.

Mas se você entender cuidadosamente as duas palavras “controlar” e “aumentar”, poderá descobrir que

No modo proxy, operações adicionais são frequentemente adicionadas para determinar se o objeto acessado pode ser acessado.

No modo decoração, essas funções adicionadas não afetarão o funcionamento dos objetos originais, e os objetos decorados serão definitivamente acessados.

 

Acho que você gosta

Origin blog.csdn.net/louis_lee7812/article/details/83807894
Recomendado
Clasificación