[design mode] decorator

Time:2021-10-13

Introduction to decorator mode

The core of the decorator is to add new functions to the class without changing the original class. It can avoid too many subclasses caused by inheritance and the complexity brought by AOP.

The decorator mainly solves the problem of subclass expansion due to the continuous horizontal expansion of functions under direct inheritance. However, after using the decorator mode, it will be more flexible than direct inheritance. At the same time, it will no longer need to consider the maintenance of subclasses.

In the process of implementation, the specific implementation only cares about the functions of the extended part. At the same time, it will not affect the core services of the original class, nor will it cause more than one subclass due to the use of inheritance, which increases the overall flexibility.

The decorator mode meets the principle of single responsibility. It can extend the functional logic in its own decoration class without affecting the main class. At the same time, it can add and delete this logic at runtime as needed. In addition, decorator patterns and inheritance parent class override methods need to be selected on demand at some times, and not necessarily one is the best.

The implementation of decorator focuses on the use of abstract class inheritance interface methods. At the same time, it is set that the inherited interface can pass its implementation class through the constructor, so as to increase scalability and rewrite the functions implemented by this part of the parent class in the method.

A wrapper is an object that can be connected to other target objects. The wrapper contains the same series of methods as the target object. It delegates all received requests to the target object, but the wrapper can process the requests before and after delegating them to the target, so the final result may be changed.

Decoration mode because the target object and decorator follow the same interface, you can use decoration to encapsulate the object infinitely. As a result, the object will obtain the behavior superimposed by all encapsulators.

Abstract point of Decorator Pattern

  • Abstract component roles – define abstract interfaces

  • Concrete component roles – implement abstract interfaces, which can be a set of

  • Decorative role – define abstract classes and inherit methods in the interface to ensure consistency

  • Specific decoration role – expand the implementation logic of decoration


Several serious problems that inheritance can cause:

1. Inheritance is static. You cannot change the behavior of an existing object at run time. You can only replace the current entire object with an object created by a different subclass.

2. A subclass can only have one parent. Most programming languages do not support multiple inheritance.

Decorator structure

  • partsDeclare the common interface between the wrapper and the encapsulated object.
  • Specific componentsClass is the class to which the encapsulated object belongs. It defines the basic behavior, but the decoration class can change these behaviors.
  • Foundation decorationClass has a reference member variable that points to the encapsulated object. The type of this variable should be declared as a generic part interface so that it can reference specific parts and decorations. The decoration base class delegates all operations to the encapsulated object.
  • Specific decorationDefines additional behaviors that can be dynamically added to an assembly. The concrete decoration class overrides the method of the decoration base class and performs additional behavior before or after calling the parent class method.
  • clientA multi-layer decoration can be used to encapsulate a component as long as it can interact with all objects using a common interface.

Applicable scenario

1. You can use an object without modifying the code, and you want to add additional behavior to the object at run time, you can use decoration mode.

Decoration can organize business logic into a hierarchy. You can create a decoration for each layer and form various different logic into objects at run time. Because these objects follow the common interface, the client code can use these objects in the same way.

2. When some businesses cannot use inheritance to extend object behavior, decoration mode can be used.

Advantages and disadvantages of decorator mode

advantage:

  • You need to create a new subclass to extend the behavior of the object.

  • The ability to add or remove objects at run time.

  • Several behaviors can be combined with multiple decoration encapsulated objects.

  • Meet the principle of single responsibility.

Disadvantages:

  • It is difficult to remove a specific wrapper from the wrapper stack

  • It is difficult to implement decoration whose behavior is not affected by the order of decoration stack

  • At the beginning, the initialization configuration code of each layer was poor

Demo

/// 
    ///Components
    /// 
    public abstract class Component
    {
        public abstract string Operation();
    }
}
/// 
    ///Abstract decorator
    /// 
    class ConcreteComponent:Component
    {
        public override string Operation()
        {
            return "ConcreteComponent";
        }
    }
abstract class Decorator:Component
    {
        protected Component _component;
        public Decorator(Component component)
        {
            this._component = component;
        }

        public void SetComponent(Component component) 
        {
            this._component = component;
        }

        public override string Operation()
        {
            if (this._component!=null)
            {
                return this._component.Operation();
            }
            else
            {
                return string.Empty;
            }
        }
    }
class ConcreteDecoratorA : Decorator
    {
        public ConcreteDecoratorA(Component comp):base(comp)
        {

        }

        public override string Operation()
        {
            return "ConcreteDecoratorA " + base.Operation();
        }
    }
    
    class ConcreteDecoratorB:Decorator
    {
        public ConcreteDecoratorB(Component comp)
            : base(comp)
        {

        }

        public override string Operation()
        {
            return "ConcreteDecoratorA " + base.Operation();
        }
    }
public class Client
    {
        public void ClientCode(Component component) 
        {
            Console.WriteLine("Result:"+component.Operation());
        }
    }
class Program
    {
        static void Main(string[] args)
        {
            Client client = new Client();

            var temp = new ConcreteComponent();
            Console.WriteLine("Start------");
            Console.WriteLine();

            ConcreteDecoratorA d1 = new ConcreteDecoratorA(temp);
            ConcreteDecoratorB d2 = new ConcreteDecoratorB(d1);
            Console.WriteLine("Start Music");
            client.ClientCode(d2);
            Console.ReadKey();
        }
    }

In fact, it can be seen that the decorator mode and the combination mode are similar. The decorator mode is the rewritability of the methods in the existing class, that is, it can change the structure of its methods, while the combination can not change the methods in the existing class, but can only combine them into what they want to achieve.

Small message

Life is short. I don’t want to pursue what I can’t see. I just want to catch what I can see.

I amAh Hui, thank you for reading. If it’s helpful to you, please like it and forward it. Thank you.

Recommended Today

OC basis

IOS development interview essential skills chart.png What are objects and what are the objects in OC? An object is an instance of a class; Is an instance created through a class, which is generally called an instance object; Common objects in OC include instance objects, class objects, and metaclass objects; What is a class? What […]