Notas sobre patrones de diseño de Java para principiantes: patrón decorador

El modo Decorador también se llama modo Wrapper.

 

1. La intención es
agregar dinámicamente algunas responsabilidades adicionales a un objeto.

 

2. Participantes
• Componente abstracto (Componente): Defina una interfaz de objeto que pueda agregar dinámicamente responsabilidades a estos objetos.
• Componente Concreto: Defina un objeto y agregue algunas responsabilidades a este objeto.
• Decorador abstracto (Decorator): contiene una instancia de un objeto componente y define una interfaz coherente con la interfaz del componente abstracto .

• Decorador de hormigón: añade responsabilidades a los componentes.

 

3. Estructura


 


 En el patrón de diseño de Yan Hong, se menciona que "el patrón de decoración extiende la funcionalidad de los objetos de manera transparente al cliente y es una alternativa a las relaciones de herencia".

 

Primero, comprendamos el propósito del modo de decoración : agregar dinámicamente algunas responsabilidades adicionales a un objeto. 

La llamada dinámica significa que se pueden agregar dinámicamente otras responsabilidades al objeto durante el tiempo de ejecución del sistema (RunTime) sin necesidad de modificar el código o volver a compilarlo;

El llamado estático significa que el código (DesignTime) debe ajustarse para agregar responsabilidades al objeto y el sistema también debe volver a compilarse;

Desde un nivel técnico específico, la combinación y herencia de objetos corresponden a las dinámicas y estáticas anteriores.

Deberíamos usar más la composición de objetos para mantener la escalabilidad del tiempo de ejecución del sistema y usar la herencia lo menos posible, ¡porque la herencia hace que el programa sea rígido!

Esto es favorecer la composición sobre la herencia.

 

 

Entendamos la frase “El modo decoración extiende la funcionalidad de los objetos de forma transparente al cliente y es una alternativa a las relaciones de herencia”. 

Decorador es una clase muy especial en el patrón decorador. No solo hereda del Componente (relación ES A), sino que también mantiene una referencia a la instancia del Componente (TIENE relación A). Desde otra perspectiva, entre Decorador y Componente, ambos son combinaciones dinámicas. Las relaciones también tienen relaciones de herencia estática.

¿Por qué está diseñado así?

La ventaja de la composición es que puede agregar responsabilidades a los objetos en tiempo de ejecución. El decorador tiene un componente ( HAS A ), que está diseñado para permitir que los decoradores concretos (Concrete Decorator) agreguen dinámicamente responsabilidades a los componentes concretos (Concrete Component) en tiempo de ejecución . es relativamente Es relativamente fácil de entender; 

Entonces, ¿cuál es el propósito de que Decorator herede de Component?

Aquí la herencia tiene un solo propósito, que es unificar las interfaces del decorador y el decorado . Desde otra perspectiva, ya sea un componente concreto (Concrete Component) o un decorador concreto (Concrete Decorator) , ambos son Componentes. El código de los usuarios puede tratarlos como componentes. El beneficio adicional de esto es que la extensión de las responsabilidades funcionales del objeto decorador al objeto decorado es completamente transparente para el código de usuario , porque el código de usuario hace referencia a todos los componentes. No habrá errores en el código de usuario que se refiere al objeto decorado después de que esté decorado, de hecho, no habrá ningún impacto, porque antes y después de la decoración, el código de usuario se refiere a objetos del tipo Componente.

 

El patrón decorador unifica las interfaces del decorador y el objeto decorado a través de la herencia y obtiene la capacidad de extender dinámicamente el objeto decorado en tiempo de ejecución a través de la composición .

 

 

Ilustremos con un ejemplo:

Primero, en lugar de utilizar el modo decoración, piense en cómo cumplir los siguientes requisitos.

1. Tomemos como ejemplo la compra de un automóvil: los clientes van a un concesionario de automóviles para comprar un automóvil y el agente brinda algunos servicios, inicialmente algunos servicios de mantenimiento posventa; 

2. Posteriormente también brindó servicios de suministro de repuestos, luego brindó algunos servicios de consultoría (los agentes respondieron algunas preguntas que los clientes tenían antes de comprar un automóvil) y finalmente brindó servicios de seguros de automóviles a los clientes.  

3. Si el agente necesita brindar diferentes combinaciones de servicios según la situación.

 

(No escribiré código para implementarlo aquí)

 

En la mayoría de los casos se utiliza la herencia, lo que provoca principalmente los siguientes problemas:

1. El sistema tiene poca escalabilidad;

2. Cuando es necesario proporcionar diferentes combinaciones de servicios, es necesario crear una gran cantidad de clases, lo que provoca una explosión de clases;

 

Entonces, veamos cómo el modo decoración logra los requisitos anteriores. El código Java es el siguiente:

 Componente abstracto: Concesionario de automóviles 

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

}

 

Componente concreto: Concesionario de automóviles Audi 

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

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

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

}

 

Decorador: Concesionario Audi que ofrece servicios. 

/**
 * 抽象装饰者(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;
	}

}

 

Concrete Decorator: Concesionario Audi que brinda servicios de reparación. 

/**
 * 具体装饰者(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;
	}

}

 

Concrete Decorator: Concesionario Audi que suministra repuestos 

/**
 * 具体装饰者(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;
	}

}

 

Concrete Decorator: Concesionario Audi que ofrece servicios de consultoría de preventa  

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

}

 

Concrete Decorator: concesionario Audi que ofrece servicios de seguros de automóviles

 

/**
 * 具体装饰者(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;
	}

}

 

La estructura es la siguiente:

 

 

 

Llamada del 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 de la operación:

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

 

Puedes ver que usar el modo decoración tiene las siguientes ventajas: 

1. El propósito del modo de decoración y la relación de herencia es ampliar la funcionalidad de los objetos, pero el modo de decoración puede proporcionar más flexibilidad que la herencia.

2. Al utilizar diferentes clases de decoración específicas y las permutaciones y combinaciones de estas clases de decoración, los diseñadores pueden usar muy pocas clases para crear muchas combinaciones de comportamiento diferentes.

 

El contenido anterior es una referencia parcial de "Java y patrones" de Yan Hong y detalles de la aplicación de ejemplo de patrón Decorador de una taza de café (Decorator)

 

Si observa cuidadosamente la invocación del modo de decoración (por ejemplo: la segunda combinación: agregar un servicio de suministro de piezas ), parece que el modo de decoración y el modo proxy tienen el mismo efecto (ambos agregan funciones adicionales a un objeto); incluso , si se compara No parece haber diferencia en la estructura de estos dos modos. Entonces, ¿cuál es la diferencia entre ellos?

 

Primero, sus intenciones son diferentes:

El patrón de proxy controla el acceso a un objeto.

El modo de decoración consiste en agregar responsabilidades (funciones) a una clase.

 

A juzgar sólo por su estructura,

Al usar el modo proxy, también puedes agregar algunas operaciones adicionales antes o después de acceder al objeto. En este sentido, el modo decoración es similar al modo proxy. Incluso se puede decir que los dos modos son iguales, ambos se suman a una clase (un objeto) otras funciones.

Pero si comprendes cuidadosamente las dos palabras "controlar" y "aumentar", descubrirás que

En el modo proxy, se agregan operaciones adicionales para determinar si se puede acceder al objeto al que se accede.

En el modo de decoración, estas funciones agregadas no afectarán el funcionamiento de los objetos originales y definitivamente se accederá a los objetos decorados.

 

Supongo que te gusta

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