Patrón de diseño: introducción al patrón de decorador

Problema a resolver

Considere un problema de cobro de una cafetería: cómo realizar un cálculo flexible del precio del café. La cafetería vende principalmente café, pero luego para satisfacer los diferentes gustos de diferentes clientes, el café puro era demasiado monótono, por lo que consideré agregar diferentes combinaciones. Luego de combinar con diferentes ingredientes, se formaría otra bebida. De esta manera, la variedad es rica. Pero luego también surgió la pregunta, cómo calcular precios nuevos y precisos para diferentes variedades nuevas. Dos opciones:

第一种: Puede usar el método de herencia para usar café puro como clase base. Luego, si necesita alguna variedad, puede generar una subclase, que puede usarse como una variedad para reescribir el método de cálculo de precios, y puede agregar otras funciones a esta variedad. Pero: un gran problema con la herencia es que la realización de tal esquema requiere que primero sepa qué variedades están disponibles antes de derivar varias subclases. Sin embargo, si desea eliminar algunas de las variedades existentes en el futuro O agregar algún contenido, o incluso eliminar esta variedad directamente, será muy engorroso modificar siempre la categoría correspondiente, y hay una desventaja: se producirán muchas semillas, si hay muchas variedades, y la diferencia entre cada variedad es pequeña Cuando llegue el momento, será muy problemático separarlos como clase.

第二种: Es adoptar el patrón decorador de temas de este artículo del que vamos a hablar hoy . Comparemos un ejemplo en la vida: una foto en papel. Si queremos conservar esta foto por más tiempo, primero podemos plastificarla; después del empaque de plástico, si creemos que no es suficiente, podemos volver a dar esta foto. Instale un marco de fotos; si cree que no puede proteger la foto agregando un marco de fotos, agregue una cubierta de vidrio. En este ejemplo, podemos entender que la foto en sí es el objeto a decorar, y el plástico, el marco de fotos y la cubierta de vidrio se utilizan como decoradores. Los decoradores de cada capa no modificarán el objeto más interno que se está decorando. Aquí podemos considerar la bebida de café específica como decorador y la comida o bebida a agregar como decorador Cada bebida de café puede ser decorada por diferentes decoradores.

El problema anterior de calcular precios para diferentes bebidas de café se basa en el concepto de programación, que es cómo agregar funciones de manera transparente a un objeto y realizar la combinación dinámica de funciones. Esta es la función del modo decorador .

Definición de modo

El modo decorador puede agregar funciones dinámicamente a un objeto y agregar funciones a un objeto de forma transparente desde el exterior.透明地给一个对象增加功能,就是说要给一个对象增加功能,但是不能让这个对象知道,也就是不能去修改这个对象

Cada persona decorada puede ser decorada por varios decoradores. Por ejemplo: el café negro (persona decorada) se puede decorar con leche (decorador), fruta (decorador) y no hay restricción en el orden de los diferentes decoradores.

Implementación

El decorador necesita heredar la misma clase o implementar la misma interfaz que el objeto decorado (se dice que cumple con el mismo protocolo en iOS), y luego, en la implementación del decorador específico, transferir el objeto decorado [esto requiere decorador El objeto sostiene un objeto decorado]

A continuación se muestra el diagrama UML implementado y el diagrama de jerarquía de llamadas entre diferentes clases.

  • CoffeeComponent: Clase de base de café (también puede ser interfaz / protocolo)
  • BlackCoffee: El café específico es el objeto a decorar.
  • CondimentDecorator: La clase base de ingredientes (la clase base del decorador), y debe heredarse de la clase base de la decoración, y también debe CoffeeComponentcontener un CoffeeComponenttipo de atributo.
  • MilkDecorator: Decorador de leche, objeto decorativo específico.

Como puede verse en el diagrama jerárquico anterior, los decoradores multicapa se envuelven capa por capa fuera del objeto decorado, y la invocación de métodos de función también es una llamada recursiva capa por capa al objeto decorado. Se puede ver en la figura que cuando el café negro se decora con leche, el decorador de leche se convierte en el nuevo decorador y puede ser decorado por otros decoradores en el futuro, y no existe un requisito de orden entre los decoradores. La secuencia se puede realizar según sus propios deseos.

//********************************咖啡组件(基类)*********************
@interface CoffeeComponent : NSObject
- (double)getPrice;
@end

@implementation CoffeeComponent//抽象组件,可以写默认实现的方法,也可以用协议实现
- (double)getPrice
{
    return 0.f;
}
@end

//********************************黑咖啡(具体咖啡类)*********************
@interface BlackCoffee : CoffeeComponent//继承于抽象组件的具体组件
- (double)getPrice;
@end

@implementation BlackCoffee
- (double)getPrice
{
    return 5;
}
@end

//********************************装饰者基类*********************
@interface CondimentDecorator : CoffeeComponent//继承于组件的装饰者抽象类
- (instancetype)initWithComponent:(CoffeeComponent *)component;
@property (nonatomic,strong)CoffeeComponent *component;
@end

@implementation CondimentDecorator
- (instancetype)initWithComponent:(CoffeeComponent *)component
{
    if (self = [super init]) {
        _component = component;
    }
    return self;
}
@end
//********************************牛奶装饰者(具体装饰者)*********************
@interface MilkDecorator : CondimentDecorator//继承于抽象佐料装饰者的具体装饰者
@end

@implementation MilkDecorator
- (double)getPrice
{
    NSLog(@"牛奶加了2元");
    return 2 + [self.component getPrice];
}
@end
//在此省略其它装饰者的代码,与牛奶装饰者的代码一样。代码可以查看demo。
//=========================外部调用=====================
    //纯咖啡
    BlackCoffee *blackCoffee = [[BlackCoffee alloc]init];
    //加奶
    MilkDecorator *milkDecorator = [[MilkDecorator alloc]initWithComponent:blackCoffee];
    //加豆浆
    SoyDecorator *soyDecorator = [[SoyDecorator alloc]initWithComponent:milkDecorator];
    //加水果
    FruitDecorator *fruitDecorator = [[FruitDecorator alloc]initWithComponent:soyDecorator];
    NSLog(@"一共多少钱%f",[fruitDecorator getPrice]);

para resumir

  • El patrón de decorador es más flexible que la herencia: la herencia es estática y las subclases heredadas tienen las mismas funciones que la clase base, pero el patrón de decorador puede separar funciones en diferentes decoradores y elegir dinámicamente qué funciones desea.
  • La esencia del modo decorador es la combinación dinámica : la combinación de decoradores dinámicamente puede agregar funciones a los objetos decorados de forma transparente.
  • El modo decorador no solo puede agregar funciones, sino también realizar completamente el acceso a nuevas funciones y funciones de control. Se puede controlar cuando se llama a la función del objeto decorado en el decorador.
  • Desventajas del patrón de decorador : se producirán objetos de grano fino.Si una serie de funciones complejas desea subdividir diferentes funciones en diferentes decoradores, se producirán muchos objetos de grano fino.

Supongo que te gusta

Origin blog.csdn.net/doubututou/article/details/109209934
Recomendado
Clasificación