[handwritten source code - design mode 9] - decorator mode - based on the king's glory hero - Zhen Ji's skin scene

1: Subject disassembly

① Basic introduction

② King glory hero Zhen Ji skin scene

③ Advantages and disadvantages of decorator mode

④ Applicable scenario

⑤ Related extension

2: Basic introduction

          Decoration mode can add additional new behavior to an object without changing the function of the object itself. To extend functionality, decorators offer a more flexible alternative than inheritance.

         Decoration mode is a technology used to replace inheritance. It can dynamically add responsibilities to objects without defining subclasses, and use the association relationship between objects to replace the inheritance relationship. Decoration classes are introduced in decoration mode. In decoration classes, you can not only call the original class methods to be decorated, but also add new methods to expand the original class functions.

3: King glory hero Zhen Ji skin scene

Below, choose the skin of the current popular game king glory hero Zhen Ji, and then start the battle to simulate

1: Basic Edition

① Hero abstract class base class

public abstract class AbstractBaseCharacter
{
    public AbstractBaseCharacter() 
    {
      //Constructor
    }
    public int Id { get; set; }
    public string Name { get; set; }
    /// <summary>
    ///Start the game
    /// </summary>
    public void Play()
    {
        Console.WriteLine("  Current player, mylove: {0}", this.Name);
    }
    //Show skin
    public abstract void Show();
}

② Player class inherits and implements

public class ZhenjiPlay : AbstractBaseCharacter
{ 
    //Choose Zhen Mi to automatically get classic skin
    public override void Show()
    {            
        Console.WriteLine("  Really, will anyone choose AMI?");
        Console.WriteLine("  Fall into the bubble of love.");
        Console.WriteLine("  It's agreed to be together forever.");
        Console.WriteLine("  Sure enough, the man who fell in love first was the loser.");            
        Console.WriteLine("  Get skin-classic");
    } 
}

③ Upper end call

AbstractBaseCharacter zhenji = new ZhenjiPlay()
{
    Id = 1,
    Name = "Yingbao"
};
zhenji.Show();
zhenji.Play();

Analysis: This version is the most basic abstract factory mode. The methods and attributes of heroes are constrained by abstract classes, and the subclasses are rewritten and implemented.

If another player likes Youheng's skin in addition to the classic skin, what should he do. Directly changing the player class is bound to violate the principle of closing the modification.

There are now two ways.

2: Combination version

① Add a composite class

public class ZhenjiPlayCombination
{
    private AbstractBaseCharacter _AbstractBaseCharacter = null;
    public ZhenjiPlayCombination(AbstractBaseCharacter abstractBaseCharacter)
    {
        this._AbstractBaseCharacter = abstractBaseCharacter;
        this._AbstractBaseCharacter.Id = abstractBaseCharacter.Id;
        this._AbstractBaseCharacter.Name = abstractBaseCharacter.Name;
    }


    public void Show()
    {
        this._AbstractBaseCharacter.Show();
        Console.WriteLine("  Get skin-Youheng");
    }
    public void Play()
    {
        this._AbstractBaseCharacter.Play();
    }
}

② Upper end call

AbstractBaseCharacter zhenji = new ZhenjiPlay()
{
    Id = 1,
    Name = "Yingbao"
};
ZhenjiPlayCombination zhenjiPlayCombination = new ZhenjiPlayCombination(zhenji);
zhenjiPlayCombination.Show();
zhenjiPlayCombination.Play();

Analysis: the combination method is adopted to realize the function expansion, and the original classes are not changed. It follows the principle of closing to modification and opening to expansion.

3: Inheritance mode version

① Add an inherited class

public class ZhenjiPlay Youheng : ZhenjiPlay
{
    public override void Show()
    {
        base.Show();
        Console.WriteLine("  Get skin-Youheng");
    } 
}

② Upper end call

ZhenjiPlay Youheng zhenjiPlay Youheng = new ZhenjiPlay Youheng()
{
    Id = 1,
    Name = "Yingbao"
};
zhenjiPlay Youheng.Show();
zhenjiPlay Youheng.Play();

Analysis: the method of inheritance is also used to realize the expansion of business functions without changing the original encapsulation

4: Decorator mode version

Demand: with the increase of players, especially local tyrants or small mushrooms with skin collection obsessive-compulsive disorder, based on the above inheritance and combination methods, it is impossible to add a combination or inheritance every time you get a skin. In particular, different players have different preferences for skin, and the purchase order is also different. In this way, whether it is realized by combination or inheritance, the corresponding classes will grow explosively.

① Abstract class base class

public abstract class AbstractBaseCharacter
{
    public AbstractBaseCharacter() 
    {
      //Constructor
    }
    public int Id { get; set; }
    public string Name { get; set; }
    /// <summary>
    ///Start the game
    /// </summary>
    public void Play()
    {
        Console.WriteLine("  Current player, mylove: {0}", this.Name);
    }
    //Show skin
    public abstract void Show();
}

② Inherit and implement the base class in the way of combination + inheritance

public class BaseZhenJi : AbstractBaseCharacter
{
    private AbstractBaseCharacter _AbstractBaseCharacter = null;        
    public BaseZhenJi(AbstractBaseCharacter AbstractBaseCharacter)
    {
        this._AbstractBaseCharacter = AbstractBaseCharacter;
        this.Id = _AbstractBaseCharacter.Id;
        this.Name = _AbstractBaseCharacter.Name;
    }
    //rewrite
    public override void Show()
    {
        this._AbstractBaseCharacter.Show();
    } 
}

③ Get the implementation of various skin classes

solution
①Basic introduction
②King glory hero Zhen Ji skin scene
③Advantages and disadvantages of decorator mode
④Applicable scenario
⑤Related extension
2: Basic introduction
 picture: https://uploader.shimo.im/f/Sn02y6CBJi8WbQbm.png!thumbnail?accessToken=eyJhbGciOiJIUzI1NiIsImtpZCI6ImRlZmF1bHQiLCJ0eXAiOiJKV1QifQ.eyJhdWQiOiJhY2Nlc3NfcmVzb3VyY2UiLCJleHAiOjE2MzE2ODAzNzEsImciOiJtNWt2OU1YSzB4UzdyS3FYIiwiaWF0IjoxNjMxNjgwMDcxLCJ1c2VySWQiOjgwMzMzMjV9.AFWNSdcRIuxenS3VwqE7fisOgR1Ia5B8KcyjCDwyR2s
 Decoration mode can add additional new behavior to an object without changing the function of the object itself. To extend functionality, decorators offer a more flexible alternative than inheritance.

Decoration mode is a technology used to replace inheritance. It can dynamically add responsibilities to objects without defining subclasses, and use the association relationship between objects to replace the inheritance relationship. Decoration classes are introduced in decoration mode. In decoration classes, you can not only call the original class methods to be decorated, but also add new methods to expand the original class functions.
3: King glory hero Zhen Ji skin scene
 Below, choose the skin of the current popular game king glory hero Zhen Ji, and then start the battle to simulate
1: Basic Edition
①Hero abstract class base class
public abstract class AbstractBaseCharacter
{
    public AbstractBaseCharacter() 
    {
      //Constructor
    }
    public int Id { get; set; }
    public string Name { get; set; }
    /// <summary>
    ///Start the game
    /// </summary>
    public void Play()
    {
        Console.WriteLine("  Current player, mylove: {0}", this.Name);
    }
    //Show skin
    public abstract void Show();
}
②Player class inherits and implements
public class ZhenjiPlay : AbstractBaseCharacter
{ 
    //Choose Zhen Mi to automatically get classic skin
    public override void Show()
    {            
        Console.WriteLine("  Really, will anyone choose AMI?");
        Console.WriteLine("  Fall into the bubble of love.");
        Console.WriteLine("  It's agreed to be together forever.");
        Console.WriteLine("  Sure enough, the man who fell in love first was the loser.");            
        Console.WriteLine("  Get skin-classic");
    } 
}
③Upper end call
AbstractBaseCharacter zhenji = new ZhenjiPlay()
{
    Id = 1,
    Name = "Yingbao"
};
zhenji.Show();
zhenji.Play();
Analysis: This version is the most basic abstract factory mode. The methods and attributes of heroes are constrained by abstract classes, and the subclasses are rewritten and implemented.
If another player likes Youheng's skin in addition to the classic skin, what should he do. Directly changing the player class is bound to violate the principle of closing the modification.
There are now two ways.
2: Combination version
①Add a composite class
public class ZhenjiPlayCombination
{
    private AbstractBaseCharacter _AbstractBaseCharacter = null;
    public ZhenjiPlayCombination(AbstractBaseCharacter abstractBaseCharacter)
    {
        this._AbstractBaseCharacter = abstractBaseCharacter;
        this._AbstractBaseCharacter.Id = abstractBaseCharacter.Id;
        this._AbstractBaseCharacter.Name = abstractBaseCharacter.Name;
    }

    public void Show()
    {
        this._AbstractBaseCharacter.Show();
        Console.WriteLine("  Get skin-Youheng");
    }
    public void Play()
    {
        this._AbstractBaseCharacter.Play();
    }
}
②Upper end call
AbstractBaseCharacter zhenji = new ZhenjiPlay()
{
    Id = 1,
    Name = "Yingbao"
};
ZhenjiPlayCombination zhenjiPlayCombination = new ZhenjiPlayCombination(zhenji);
zhenjiPlayCombination.Show();
zhenjiPlayCombination.Play();
Analysis: the combination method is adopted to realize the function expansion, and the original classes are not changed. It follows the principle of closing to modification and opening to expansion.
3: Inheritance mode version
①Add an inherited class
public class ZhenjiPlay Youheng : ZhenjiPlay
{
    public override void Show()
    {
        base.Show();
        Console.WriteLine("  Get skin-Youheng");
    } 
}
②Upper end call
ZhenjiPlay Youheng zhenjiPlay Youheng = new ZhenjiPlay Youheng()
{
    Id = 1,
    Name = "Yingbao"
};
zhenjiPlay Youheng.Show();
zhenjiPlay Youheng.Play();
Analysis: the method of inheritance is also used to realize the expansion of business functions without changing the original encapsulation
4: Decorator mode version
 Demand: with the increase of players, especially local tyrants or small mushrooms with skin collection obsessive-compulsive disorder, based on the above inheritance and combination methods, it is impossible to add a combination or inheritance every time you get a skin. In particular, different players have different preferences for skin, and the purchase order is also different. In this way, whether it is realized by combination or inheritance, the corresponding classes will grow explosively.
①Abstract class base class
public abstract class AbstractBaseCharacter
{
    public AbstractBaseCharacter() 
    {
      //Constructor
    }
    public int Id { get; set; }
    public string Name { get; set; }
    /// <summary>
    ///Start the game
    /// </summary>
    public void Play()
    {
        Console.WriteLine("  Current player, mylove: {0}", this.Name);
    }
    //Show skin
    public abstract void Show();
}
②combination+Inherit and implement the base class by inheritance
public class BaseZhenJi : AbstractBaseCharacter
{
    private AbstractBaseCharacter _AbstractBaseCharacter = null;        
    public BaseZhenJi(AbstractBaseCharacter AbstractBaseCharacter)
    {
        this._AbstractBaseCharacter = AbstractBaseCharacter;
        this.Id = _AbstractBaseCharacter.Id;
        this.Name = _AbstractBaseCharacter.Name;
    }
    //rewrite
    public override void Show()
    {
        this._AbstractBaseCharacter.Show();
    } 
}
③Get the implementation of various skin classes
public class ZhenJiWith_Ice Waltz : BaseZhenJi
{
    public ZhenJiWith_Ice Waltz(AbstractBaseCharacter abstractBaseCharacter)
        : base(abstractBaseCharacter)
    {
        
    }
    public override void Show()
    {
        base.Show();
        Console.WriteLine("  Get skin-Ice Waltz");
    }
}

public class ZhenJiWith_Flower good world : BaseZhenJi
{
    public ZhenJiWith_Flower good world(AbstractBaseCharacter abstractBaseCharacter)
        : base(abstractBaseCharacter)
    {
    }
    public override void Show()
    {
        base.Show();
        Console.WriteLine("  Get skin-Flower good world");
    }
}

public class ZhenJiWith_A dream in the garden : BaseZhenJi
{
    public ZhenJiWith_A dream in the garden(AbstractBaseCharacter abstractBaseCharacter)
        : base(abstractBaseCharacter)
    {
    }
    public override void Show()
    {
        base.Show();
        Console.WriteLine("  Get skin-A dream in the garden-mylove");
    }
}

public class ZhenJiWith_Youheng : BaseZhenJi
{
    public ZhenJiWith_Youheng(AbstractBaseCharacter abstractBaseCharacter)
        : base(abstractBaseCharacter)
    {
    }
    public override void Show()
    {
        base.Show();
        Console.WriteLine("  Get skin-Youheng");
    }
}

  ④ Basic player class

Basic players have their own classic skin and will sigh about life...

public class ZhenjiPlay : AbstractBaseCharacter
{ 
    //Choose Zhen Mi to automatically get classic skin
    public override void Show()
    {            
        Console.WriteLine("  Really, will anyone choose AMI?");
        Console.WriteLine("  Fall into the bubble of love.");
        Console.WriteLine("  It's agreed to be together forever.");
        Console.WriteLine("  Sure enough, the man who fell in love first was the loser.");            
        Console.WriteLine("  Get skin-classic");
    } 
}

⑤ Upper end call

Console.WriteLine("  Decorator mode");
Console.WriteLine("  *********************"); 
AbstractBaseCharacter zhenji = new ZhenjiPlay()
{
    Id = 1,
    Name = "Yingbao"
}; 
zhenji = new ZhenJiWith_Ice Waltz(zhenji);
zhenji = new ZhenJiWith_Flower good world(zhenji);                 
zhenji = new ZhenJiWith_Youheng(zhenji);
zhenji = new ZhenJiWith_A dream in the garden(zhenji);
zhenji.Show();
zhenji.Play();
Console.WriteLine($"  current time {System.DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}");

Analysis: it can be seen from the place where the upper end calls. In fact, each call uses the base class, so it can be nested continuously, and the order can be adjusted at will.

4: Advantages and disadvantages of decorator mode

1: Advantages

         Flexible dynamic extension: for the function of extending an object, decoration mode is more flexible than inheritance, and will not lead to a sharp increase in the number of classes. By selecting different specific decoration classes, the behavior of objects can be dynamically extended

         Multiple decoration: you can decorate an object multiple times. Using different specific decoration classes and the arrangement and combination of these decoration classes can create many combinations of different behaviors

         Independent change of component and decoration: specific component and decoration can be changed independently. Users can add new specific component or decoration as needed without modifying the original code and comply with the opening and closing principle

2: Shortcomings

         More objects: using decoration mode will produce many small objects. The difference between these objects lies in the different connection methods. Too many small objects will affect the performance to a certain extent

         Cumbersome Troubleshooting: Although the decoration mode is more flexible than inheritance, it also means that it is more prone to errors than inheritance, and troubleshooting is also very difficult. For objects decorated for many times, it may be necessary to troubleshoot level by level

5: Applicable scenario

Add responsibility to a single object in a dynamic and transparent manner without affecting other objects.

When the system cannot be extended by inheritance or inheritance is not conducive to system expansion and maintenance, the decoration mode can be used.

If you want to add functions to a class dynamically, and this function also wants to be revoked dynamically.

6: Related extension

1: Operation results

  2: Zhen Ji's skin

1: Ice Waltz

  2: Flower good world

  3: Youheng

  4: A dream in the garden

  3: Zhen Ji's Manual

1: Prototype

  2: Version Q

4: Zhen Ji's historical identity

Zhen Ji: "sure enough, the one who fell in love first is the loser". Do you know who that person is?

  5: The guidance of the elder King

  6: Advice

Read more books, read more newspapers, beat less kings and sleep more!

"Sure enough, the one who fell in love first was the loser". Due to the king, Zhen Ji finally unloaded and left.

Tags: C# Design Pattern architecture Game Development

Posted on Fri, 17 Sep 2021 19:21:07 -0400 by cluce