Patrón de decorador (decorador) del patrón de diseño de java (8)

El patrón de decorador / decorador del patrón de diseño de Javava

Aprenda a cambiar su estado de ánimo, porque solo así podrá luchar contra el dolor y ser feliz.

Aprendizaje de patrones de diseño ,
escribiré en un blog sobre 23 patrones de diseño en un futuro cercano , así que estad atentos ~ —2021/1/11

definición

El modo de modificación es un modo de diseño que agrega dinámicamente nuevos comportamientos a una clase en el campo de la programación orientada a objetos. En términos de función, el modo de modificación es más flexible que la generación de subclases, por lo que puede agregar algunas funciones a un objeto en lugar de a toda la clase.

Enciclopedia de Baidu

Escenario de aplicación

En el caso de que una clase necesite agregar nuevas características, sin cambiar la clase actual,

Por ejemplo, si la función de una clase es 'arroz frito', quiero agregar una función 'huevo' a esta clase, o agregar una función 'tocino' para convertir el 'arroz frito' original en 'arroz frito con huevo';

Análisis de roles

  • Rol de estructura abstracta (componente) : define una interfaz abstracta para estandarizar objetos que están listos para aceptar responsabilidades adicionales
  • Roles de componentes concretos : implemente estructuras abstractas y agregue algunas responsabilidades a través de roles decorativos.
  • Función de decoración abstracta (decorador) : herencia o construcción abstracta, e incluye ejemplos de construcción de hormigón, que pueden extender las funciones de construcción de hormigón a través de sus subclases.
  • El papel del decorador de hormigón : implementar los métodos relevantes de decoración abstracta y agregar responsabilidades adicionales al objeto de construcción de hormigón.

Análisis simple:

  • Rol de construcción abstracta: clase abstracta por decorador
  • Papel de la estructura de hormigón: implementar la clase abstracta del dispositivo decorado, el dispositivo decorado
  • Papel de decoración abstracta: decorador clase abstracta
  • Función de decoración específica: decorador, implementar la clase abstracta decorador

¿Por qué definir tantas clases abstractas?

Observe el principio de inversión de dependencia (programación orientada a la interfaz)

análisis

UML类图(1.1):

  • Tallarines
  • Arroz frito
  • Comida

Los fideos y el arroz frito pertenecen a los alimentos, por lo que se heredan de los alimentos, necesitamos agregar algunos productos nuevos a cada alimento.

Por ejemplo, quiero agregar un huevo.

Ahora esta categoría de alimentos se ha convertido en el decorador, y el huevo se decora para lograr el efecto de 'huevo de fideos' o 'huevo de arroz frito', y el huevo se convierte en decorador.

Si originalmente un arroz frito costaba 10 yuanes y un huevo costaba 1 yuanes, pediría un arroz frito con huevo a 11 yuanes.

UML类图(1.2):


Esta es la renderización final que vamos a completar, no importa si esta imagen no se entiende, primero echemos un vistazo al código y finalmente volvamos a ver esta imagen de un vistazo.

Código

Categoría de alimentos:

public abstract class Food {
    
    
    private String name;//名字
    private float price;//价格
    //总价
    public abstract float totalPrice();
    set...
    get...
}

Arroz frito con arroz:

public class FriedRice extends Food {
    
    

    public FriedRice() {
    
    
        setName("炒饭");
        setPrice(12);
    }

    @Override
    public float totalPrice() {
    
    
        //调用父类的价格方法 将set的值获取出来 
        return getPrice();
    }
}

análisis:

代码流程图(2.1):


Aquí, si llama al constructor FriedRice (arroz frito), primero asigne el precio del arroz frito.

Tallarines:

public class Noodles extends Food {
    
    
    public Noodles() {
    
    
        setName("面食");
        setPrice(9);
    }
    @Override
    public float totalPrice() {
    
    
        return getPrice();
    }
}

Igual que FriedRice (arroz frito)

Código de implementación:

//面条
Noodles noodles = new Noodles();

Log.i("装饰器模式", noodles.getName() + "\t" + 
			noodles.getPrice() + "\t总价:" + 
			noodles.totalPrice()
		);

//        炒饭
FriedRice friedRice = new FriedRice();

Log.i("装饰器模式", friedRice.getName() + "\t" + 
		friedRice.getPrice() + "\t总价:" + 
		friedRice.totalPrice()
	);

Log图(3.1):


Esto es muy simple, no lo describiré, aquí se llama guarnición, toma un huevo, que se convierta en 'fideos de huevo' o 'arroz frito con huevo', el huevo aquí es el decorador.

Categoría de decoración de alimentos:

public abstract class GarnishFood extends Food {
    
    

    Food food;

    public GarnishFood(Food food) {
    
    
        this.food = food;
    }
  	set..
  	get..
}

Huevos de huevo:

public class Egg extends GarnishFood{
    
    
    public Egg(Food food) {
    
    
        super(food);
        setName("鸡蛋");
        setPrice(1);
    }

    @Override
    public float totalPrice() {
    
    
        return  getPrice()+  getFood().totalPrice();
    }
}

Análisis del parámetro Egg egg totalPrice ():

  • getPrice () Parámetros :

    Cuadro rojo: aquí el constructor establece getPrice () en 1.
    Cuadro amarillo: debido a que la clase egg (Egg) hereda de la clase de decoración (GarnishFood), la clase de decoración hereda de Food, por lo que las llamadas aquí son todos métodos de alto nivel en alimentos
  • parámetro getFood (). totalPrice () :

    aquí también está el método Food en la clase principal de nivel superior,
    por lo que getFood (). totalPrice () = precio total

Usar código:

Noodles nd = new Noodles();
Log.i("装饰器模式", nd.getName() + "\t" + 
			nd.getPrice() + "\t总价:" +
			 nd.totalPrice());

Egg egg = new Egg(nd);
Log.i("装饰器模式", egg.getName() + "\t" +
		 egg.getPrice() + "\t总价:" + 
		 egg.totalPrice());

Egg egg1 = new Egg(egg);
Log.i("装饰器模式", egg1.getName() + "\t" + 
		egg1.getPrice() + "\t总价:" + 
		egg1.totalPrice());

Log图(3.2): Se
Inserte la descripción de la imagen aquí
puede ver que sin agregar un huevo, el precio total es +1 yuan

Si puede agregar nuevos productos ahora, por ejemplo, puede agregar tocino, veamos cómo escribir el código ~

Tocino Tocino:

public class Bacon extends GarnishFood{
    
    
    public Bacon(Food food) {
    
    
        super(food);
        setName("培根");
        setPrice(3.5f);
    }

    @Override
    public float totalPrice() {
    
    
        return super.getPrice() + super.getFood().totalPrice();
    }
}

Usar código:

Bacon bacon = new Bacon(egg1);
Log.i("装饰器模式", bacon.getName() + "\t" + 
        bacon.getPrice() + "\t总价:" +
         bacon.totalPrice());

Log图(3.3):

para resumir

Cosplay:

  • Rol de estructura abstracta: Alimentos ()
  • Función de estructura específica: FriedRice (). Noodles ()
  • Papel decorativo abstracto: GarnishFood ()
  • Papel decorativo específico: Huevo (). Tocino ()

El modo decorador es decorar la función original de una clase en algo nuevo sin cambiar, así como la función de la clase original, cumpliendo con el principio de apertura y cierre (abierto para extensión, cerrado para modificación)

beneficio:

  • El modo Decorador puede traer extensiones más flexibles que la herencia.
  • El modo de decoración y la persona decorada pueden desarrollarse de forma independiente y no se emparejarán entre sí.
  • El modo decorador cumple con el principio de apertura y cierre (abierto para extensión, cerrado para modificación)

Desventajas:

  • Debido a que se necesita herencia, el acoplamiento de cada clase será muy alto

Código completo

Ir al catálogo de patrones de diseño / principios de diseño

La originalidad no es fácil, tus gustos son tu mayor apoyo para mí, deja tus gustos ~

Supongo que te gusta

Origin blog.csdn.net/weixin_44819566/article/details/112461664
Recomendado
Clasificación