Decorator mode

Decorator pattern: belongs to structural design pattern, is relatively simple, one of the common design pattern. The main purpose is to add a layer of decoration to existing classes

define

Allowing you to add new functionality to an existing object without changing its structure dynamically adds additional responsibilities to a class. To put it more simply, as a foodie, does giving that hot dog you have in your hand, plus sausage, plus egg, plus vegetables, make it a real dog? No, hot dog is the same hot dog.

example

It’s time for another favorite example, and this time you get a bonus. If your goddess finally agrees to go out with you today, you might want to prepare. Let’s talk about how to prepare to send, directly on the code:

/** * When you're dating a goddess, take care of yourself. * Start with a human abstract class and take care of yourself */
public interface Person {
    public void dressUp(a);
}
Copy the code

If you’re dating a goddess, you gotta be someone who takes care of herself. You can’t go out looking for a goddess in an unkempt state

/** * first to you * goddess date, always first to freshen up, the most basic requirements, or your goddess was you smelly away how to do? * /
public class Man implements Person{

    @Override
    public void dressUp(a) {
        System.out.println("You freshen up."); }}Copy the code

All right, now for a mock date with the goddess

public class Client {
    public static void main(String[] args) {
        Person man = new Man();
        man.dressUp();
        System.out.println("Go date a goddess."); }}Copy the code

Running results:

But is it really a good thing? The goddess said yes to your date, and you just cleaned up and went? Not trying to impress the goddess? No more grooming yourself? So, we have to go back to the oven and rebuild it. Come on, you have to put on a nice suit.

public class GetClothesMan implements Person{
    private Person person;

    public GetClothesMan(Person person) {
        this.person = person;
    }

    @Override
    public void dressUp(a) {
        person.dressUp();
        System.out.println("Put on your smart clothes."); }}Copy the code

Let’s do the dating scenario again

public class Client {
    public static void main(String[] args) {
        Person man = new Man();
        Person getClothesMan = new GetClothesMan(man);
        getClothesMan.dressUp();
        System.out.println("Go date a goddess."); }}Copy the code

Running results:

Now that we’re all dressed up, why don’t you put on some cologne?

public class GetCologne implements Person{
    private Person person = null;

    public GetCologne(Person person) {
        this.person = person;
    }
    @Override
    public void dressUp(a) {
        person.dressUp();
        System.out.println("Put on some cologne."); }}public class Client {
    public static void main(String[] args) {
        Person man = new Man();
        Person getClothesMan = new GetClothesMan(man);
        Person getCologne = new GetCologne(getClothesMan);
        getCologne.dressUp();
        System.out.println("Go date a goddess."); }}Copy the code

Running results:

Sure, if you’re a big family, you can spray

public class Client {
    public static void main(String[] args) {
        Person getDoubleCologne = new GetCologne(new GetCologne(new GetClothesMan(new Man())));
        getDoubleCologne.dressUp();
        System.out.println("Go date a goddess."); }}Copy the code

Running results:

Usage scenarios

  • Need to extend the functionality of a class or add additional functionality to a class
  • Functions need to be added to an object dynamically, and those functions can be revoked dynamically

Note: Although the decorator pattern can nest layers, layers of decorators are complex, so minimize the number of decorator classes and reduce the complexity of the system.

summary

In this case, adding extra functionality to an existing object (the freshened up you) (putting on cool clothes and cologne) is a classic decorator pattern. As you can see from the example above, you are always dressing up for your date with the goddess.

Extend a

The decorator pattern and the proxy pattern are written very similarly. But there are differences

  • The characters are different: the decorator mode, from beginning to end, the characters are unique and decorate the existing objects; But the agency model has two roles, the agent and the principal, who have different responsibilities.
  • The purpose is different: the purpose of the decorator pattern is to add additional functionality to existing objects (after investing in themselves, still themselves); But the purpose of the proxy model is to control access to existing objects (that is, the proxy decides whether the goddess can ask you out or not).
  • It’s written differently: The decorator pattern requires the outside to pass in the object that needs to be decorated, and the caller needs to know who to decorate; But in proxy mode, there is no need to pass in the proxy object from outside. The caller does not need to be the proxy. The caller only needs to deal with the proxy.

Extension 2

The decorator pattern and inheritance development follow the principle of composition > inheritance. The decorator pattern is to extend objects in composition, so it is more flexible than inheritance, and it is better to write robust, extensible code. Take the cologne step above, for example. Sometimes it takes one spray, sometimes it takes two. The above decorative pattern is written with the same cologne-wearing class for two times to achieve the effect; So if you use inheritance, you need to create two classes, one is a spray implementation and two spray implementation, this will increase the number of classes, if this situation is too many, it will make the project bloated and difficult to maintain.