Design mode of Dahua, decorator mode of structural mode

Keywords: Attribute JDK Java Programming

Overview of structural mode

Overview of structural mode

Decorator Pattern allows you to add new functionality to an existing object without changing its structure. This type of design pattern belongs to structural pattern, which is a wrapper for existing classes.

This pattern creates a decoration class to wrap the original class, and provides additional functions while maintaining the integrity of class method signature.

Let's demonstrate the use of the decorator pattern with the following example. Among them, we will decorate a shape with different colors without changing the shape class.

Model motivation and definition

Mode motivation


There are generally two ways to add behavior to a class or object:

  • Inheritance mechanism, using inheritance mechanism is an effective way to add functions to existing classes. By inheriting an existing class, a subclass can have its own methods as well as the methods of its parent class. But this method is static, and users can't control how and when to increase their behavior.
  • Association mechanism, that is, the object of one class is embedded in another object, and another object decides whether to call the behavior of the embedded object to extend its behavior. We call this embedded object the decorator.

Decoration mode dynamically attaches more responsibilities to an object in a transparent way to the customer. In other words, the client does not feel that the object is different before and after decoration. Decoration pattern can extend the function of objects without creating more subclasses. This is the pattern motive of decoration pattern.

Schema definition

Decorator Pattern: dynamically add some extra responsibilities to an object. In terms of adding object functions, decorator pattern is more flexible than subclass generation. The aliases can also be called wrappers, which are the same as the aliases for adapter patterns, but they are suitable for different situations. According to different translations, the decoration mode is also called "painter mode", which is an object structure mode.

Pattern structure and analysis

Pattern structure


The decoration mode includes the following roles:

  • Component: abstract component
  • ConcreteComponent: concrete component
  • Decorator: abstract decoration class
  • ConcreteDecorator: concrete decoration class

pattern analysis

Compared with the inheritance relationship, the main advantage of the association relationship is that it does not destroy the encapsulation of the class, and the inheritance is a static relationship with a large degree of coupling, which can not be expanded dynamically when the program is running. In the software development stage, although the association relationship can not reduce the amount of coding compared with the inheritance relationship, in the software maintenance stage, because the association relationship makes the system have better loose coupling, so it makes the system easier to maintain. Of course, the disadvantage of an association relationship is that it creates more objects than an inheritance relationship.

Using decorating patterns to implement extensions is more flexible than inheritance, which dynamically attaches more responsibility to an object in a transparent way to the customer. Decoration pattern can extend the function of objects without creating more subclasses.

Typical abstract decoration Code:

public class Decorator extends Component
{
    private Component component;
    public Decorator(Component component)
    {
        this.component=component;
    }
    public void operation()
    {
        component.operation();
    }
}

Typical specific decoration Codes:

public class ConcreteDecorator extends Decorator
{
    public ConcreteDecorator(Component component)
    {
        super(component);
    }
    public void operation()    //Add a method to the operation method of the subclass
    {
        super.operation();
        addedBehavior();
    }
    public void addedBehavior()
    {
                  //New method    
    }
}

Pattern instance and analysis

Pattern instance and analysis

Example 1: Transformers

The transformer was a car before it was deformed. It can move on land. When it becomes a robot, it can not only move on land, but also speak; if necessary, it can also become an airplane, which can fly in the sky as well as move on land.

public interface Transform
{
    public void move();
}

//Concrete construction
public final class Car implements Transform
{
    public Car()
    {
        System.out.println("Transformer is a car!");
    }
    
    public void move()
    {
        System.out.println("Move on land!");    
    }
}

//Abstract decoration class
public class Changer implements Transform
{
    private Transform transform;
    
    public Changer(Transform transform)
    {
        this.transform=transform;
    }
    
    public void move()
    {
        transform.move();    
    }
}

//Specific decoration
public class Robot extends Changer
{
    public Robot(Transform transform)
    {
        super(transform);
        System.out.println("Become a robot!");
    }
    
    public void say()
    {
        System.out.println("Speak!");    
    }
}

//Specific decoration
public class Airplane extends Changer
{
    public Airplane(Transform transform)
    {
        super(transform);
        System.out.println("Become a plane!");
    }
    
    public void fly()
    {
        System.out.println("Fly in the sky!");    
    }
}

//Client
public class Client
{
    public static void main(String args[])
    {
        Transform camaro;
        camaro=new Car();
        camaro.move();
        System.out.println("-----------------------------");
        
        Airplane bumblebee=new Airplane(camaro);
        bumblebee.move();
        bumblebee.fly();
    }
}
Example 2: multiple encryption system

A system provides a data encryption function, which can encrypt strings. The simplest encryption algorithm is realized by shifting the letters. At the same time, it also provides a slightly complex reverse output encryption and a more advanced modular encryption. The user first uses the simplest encryption algorithm to encrypt the string. If it is not enough, the user can use other encryption algorithms to encrypt the encrypted result for the second time, and of course, the third time. Now we use decoration mode to design the multi encryption system.

//Abstract construction
public interface Cipher
{
    public String encrypt(String plainText);
}

//Concrete construction
public class SimpleCipher implements Cipher
{
    public String encrypt(String plainText)
    {
        String str="";
        for(int i=0;i<plainText.length();i++)
        {
            char c=plainText.charAt(i);
            if(c>='a'&&c<='z')
            {
                c+=6;
            if(c>'z') c-=26;
            if(c<'a') c+=26;
            }
            if(c>='A'&&c<='Z')
            {
                c+=6;
            if(c>'Z') c-=26;
            if(c<'A') c+=26;
            }
            str+=c;
        }
        return str;
    }
}

//Abstract decoration class
public class CipherDecorator implements Cipher
{
    private Cipher cipher;
    
    public CipherDecorator(Cipher cipher)
    {
        this.cipher=cipher;
    }
    
    public String encrypt(String plainText)
    {
        return cipher.encrypt(plainText);
    }
}
//Specific decoration
public class ComplexCipher extends CipherDecorator
{
    public ComplexCipher(Cipher cipher)
    {
        super(cipher);
    }
    
    public String encrypt(String plainText)
    {
        String result=super.encrypt(plainText);
        result=reverse(result);
        return result;
    }
    
    public String reverse(String text)
    {
        String str="";
        for(int i=text.length();i>0;i--)
        {
            str+=text.substring(i-1,i);
        }
        return str;
    }
}

//Specific decoration
public class AdvancedCipher extends CipherDecorator
{
    public AdvancedCipher(Cipher cipher)
    {
        super(cipher);
    }
    
    public String encrypt(String plainText)
    {
        String result=super.encrypt(plainText);
        result=mod(result);
        return result;
    }
    
    public String mod(String text)
    {
        String str="";
        for(int i=0;i<text.length();i++)
        {
            String c=String.valueOf(text.charAt(i)%6);
            str+=c;
        }
        return str;
    }
}

//Client
public class Client
{
    public static void main(String args[])
    {
        String password="sunnyLiu";  //Plaintext
        String cpassword;       //ciphertext
        Cipher sc,cc;
        
        sc=new SimpleCipher();
        cpassword=sc.encrypt(password);
        System.out.println(cpassword);
        System.out.println("---------------------");
        
        cc=new ComplexCipher(sc);
        cpassword=cc.encrypt(password);
        System.out.println(cpassword);
        System.out.println("---------------------");
        
        /*
        ac=new AdvancedCipher(cc);
        cpassword=ac.encrypt(password);
        System.out.println(cpassword);
        System.out.println("---------------------");
        */
    }
}

Mode effect

Advantages of decorator mode
  • The purpose of decoration pattern and inheritance relationship is to extend the function of objects, but decoration pattern can provide more flexibility than inheritance.
  • The function of an object can be extended in a dynamic way, and different decorators can be selected at runtime through configuration files, so as to achieve different behaviors.
  • Through the use of different specific decoration classes and the arrangement and combination of these decoration classes, many different behavior combinations can be created. Multiple concrete decoration classes can be used to decorate the same object to get more powerful objects.
  • Specific component class and specific decoration class can be changed independently. Users can add new specific component class and specific decoration class according to their needs, and then combine them when using. The original code does not need to be changed, which conforms to the "opening and closing principle".
Disadvantages of decorator mode
  • There will be many small objects in the system design using decoration mode. The difference between these objects is that they are connected in different ways, not their classes or attribute values are different. At the same time, there will be many specific decoration classes. The emergence of these decoration classes and small objects will increase the complexity of the system and the difficulty of learning and understanding.
  • This feature is more flexible and flexible than inheritance, which also means that decoration mode is more prone to errors than inheritance, and it is also very difficult to troubleshoot. For objects decorated many times, finding errors during debugging may require level by level troubleshooting, which is more cumbersome.

Applicable environment and Application

Applicable environment

Decorative mode can be used when:

  • Add responsibilities to individual objects in a dynamic and transparent manner without affecting other objects.
  • You need to add functions to an object dynamically, and these functions can also be revoked dynamically.
  • When the system cannot be extended by inheritance or inheritance is not conducive to system expansion and maintenance. There are two main types of cases in which inheritance cannot be adopted: the first type is that there are a large number of independent extensions in the system. To support each combination, a large number of subclasses will be generated, which makes the number of subclasses increase explosively; the second type is because the class definition cannot be inherited (such as the final class).

application

  1. In javax.swing package, you can dynamically add new behavior or improve the appearance of some components through decoration mode.
    For example, the JList component itself does not support direct scrolling, that is, there is no scroll bar. To create a scrollable list, you can use the following code:
JList list = new JList();
JScrollPane sp = new JScrollPane(list); 
  1. The most classic example of decoration mode in JDK is Java IO.
    Take InputStream for example:

    Abstract decoration class: FilterInputStream
 ......
 protected volatile InputStream in;
 protected FilterInputStream(InputStream in) {
 this.in = in;
 }
 ...... 

Role assignment:

  • Abstract component class: InputStream
  • Specific component classes: FileInputStream, ByteArrayInputStream, etc
  • Abstract decoration class: FilterInputStream
  • Specific decoration classes: BufferedInputStream, DataInputStream, etc

Client use:

FileInputStream inFS=new FileInputStream("temp/fileSrc.txt");        
BufferedInputStream inBS=new BufferedInputStream(inFS);
//Define a byte array to hold buffered data
byte[] data = new byte[1024];
inBS.read(data);

Mode extension

Simplification of decoration pattern
  • The interface of a decoration class must be the same as that of the decorated class. For clients, objects before and after decoration can be treated in the same way.
  • Try to keep the specific Component class Component as a "light" class, that is, don't put too much logic and state in the specific Component class, which can be extended by decoration class.
  • If there is only one concrete component class and there is no abstract component class, then the abstract decoration class can be the direct subclass of concrete component class.
Simplification of decoration mode

Transparent decoration mode (multiple encryption system)

In the transparent decoration mode, the client is required to be completely aimed at Abstract Programming. The transparency of decoration mode requires that the client program should not declare specific component type and specific decoration type, but all of them should be declared as abstract component type.

Cipher sc,cc,ac;
sc=new SimpleCipher();
cc=new ComplexCipher(sc);    
ac=new AdvancedCipher(cc); 
Translucent decoration mode (transformer)

Most of the decoration modes are semi transparent rather than transparent. That is to say, the user is allowed to declare the object of specific decorator type on the client and call the new method in the specific decorator.

Transform camaro;
camaro=new Car();
camaro.move();
Robot bumblebee=new Robot(camaro);
bumblebee.move();
bumblebee.say(); 
Published 47 original articles, won praise 29, visited 1773
Private letter follow

Posted by Slashscape on Sun, 19 Jan 2020 06:40:08 -0800