This is the seventh day of my participation in the August More text Challenge. For details, see: August More Text Challenge

The decorator pattern, as the name suggests, is to decorate some existing class to extend some functionality.

The following figure shows its structure:

The four main roles are: Component role: An abstract interface is given to standardize an object that is prepared to accept additional responsibilities. ConCreteComponent role: Defines a class that will accept additional responsibilities. Decorator role: Holds an instance of a Component object and defines an interface consistent with the abstract Component interface. ConcreteDecorator roles: Responsible for “attaching” additional responsibilities to component objects.

Here’s an example:

I now have shorts, T-shirts, suits and trousers in my wardrobe. I now need to match it to both of my outfits.

Below I use the object oriented virtual method to implement:

The base class: Perso. Cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
  
namespace Decorate
{
    public class Person
    {
        public Person()
        {
            this.name = name;
        }
        private string name;
        public Person(string name)
        {
            this.name = name;
        }
  
        public virtual void Show()
        {
            Console.WriteLine("Dressed up"+name); }}}Copy the code

T-shirt class: Txu.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
  
namespace Decorate
{
    public class Txu : Person
    {
        public override void Show()
        {
            Console.WriteLine("Big T-shirt."); }}}Copy the code

Shorts class:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
  
namespace Decorate
{
    public class duanku: Person
    {
        public override void Show()
        {
            Console.WriteLine("Shorts"); }}}Copy the code

Suits: xifu.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
  
namespace Decorate
{
    public class xifu: Person
    {
        public override void Show()
        {
            Console.WriteLine("Suit"); }}}Copy the code

Pants: Changku.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
  
namespace Decorate
{
    public class changku: Person
    {
        public override void Show()
        {
            Console.WriteLine("Pants"); }}}Copy the code

High-level call module: program.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
  
namespace Decorate
{
    class Program
    {
        static void Main(string[] args)
        {
            // Instantiate a person
            Person camellia = new Person("camellia");
            Txu txu = new Txu();
            duanku duan = new duanku();
            changku kuu = new changku();
            xifu fuu = new xifu();
  
            Console.WriteLine("The first dress:"); txu.Show(); duan.Show(); camellia.Show(); Console.ReadKey(); }}}Copy the code

The above code does what we want, but it has a problem: the procedure is shown outside every time it is called in program.cs. It’s like you’re standing in front of everyone with no clothes on and changing clothes one by one. Always feel not too good, this time, we can use decorative mode.

1: Define abstract Component roles

Person.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
  
namespace Decorate
{
    public class Person
    {
        public Person()
        {
            this.name = name;
        }
        private string name;
        public Person(string name)
        {
            this.name = name;
        }
  
        public virtual void Show()
        {
            Console.WriteLine("Dressed up"+name); }}}Copy the code

2: Decorator characters (this is the essence)

Decorate.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
  
namespace Decorate
{
    /// <summary>
    ///Decoration class
    /// </summary>
    public class Decorator : Person
    {
        // Declare a parent object
        protected Person component;
        / / up
        public void Decora(Person component)
        {
            // Assign the passed object to the declared parent object. This is important to understand
            this.component = component;
        }
  
        public override void Show()
        {
            // If the object passed is not null, execute the show method below it
            if(component ! =null) { component.Show(); }}}}Copy the code

3: ConCreteComponent role: Defines a class that will accept additional responsibilities.

Me.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
  
namespace Decorate
{
    public class me : Person
    {
        public override void Show()
        {
            Console.WriteLine("I'm changing.");
        }
  
        public void Song()
        {
            Console.WriteLine("I'm singing."); }}}Copy the code

ConcreteDecorator roles: Responsible for “attaching” additional responsibilities to component objects.

Suit: xifu. Cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
  
namespace Decorate
{
    public class xifu:Decorator
    {
        public override void Show()
        {
            Console.WriteLine("Suit");
            // Show the superclass method
            base.Show(); }}}Copy the code

Shorts: duanku. Cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
  
namespace Decorate
{
    public class duanku:Decorator
    {
        public override void Show()
        {
            Console.WriteLine("Shorts");
            // Show the superclass method
            base.Show(); }}}Copy the code

T-shirt: Txu. Cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
  
namespace Decorate
{
    public class Txu : Decorator
    {
        public override void Show()
        {
            Console.WriteLine("Big T-shirt.");
            // Show the superclass method
            base.Show(); }}}Copy the code

Trousers: changku. Cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
  
namespace Decorate
{
    public class changku:Decorator
    {
        public override void Show()
        {
            Console.WriteLine("Pants");
            // Show the superclass method
            base.Show(); }}}Copy the code

High-level modules: call program.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
  
namespace Decorate
{
    class Program
    {
        static void Main(string[] args)
        {
            // Instantiate a person
            Person camellia = new Person("camellia");
            Txu txu = new Txu();
            duanku duan = new duanku();
            changku kuu = new changku();
            xifu fuu = new xifu();
            me m = new me();
  
            m.Show();
            Console.WriteLine("The first dress:");
            //txu.Show();
            //duan.Show();
            //camellia.Show();
            txu.Decora(camellia);
            duan.Decora(txu);
            duan.Show();
            Console.WriteLine("");
            Console.WriteLine("-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -");
            Console.WriteLine("");
            m.Show();
            Console.WriteLine("The second dress:");
  
            // Note that the following two lines of code are commented, open the comment, may have a different effect ~
            //kuu.Decora(camellia);
            //kuu.Show();fuu.Decora(kuu); fuu.Show(); Console.ReadKey(); }}}Copy the code

That’s all the code that uses the decoration. cs class: the essence is in the base (execute the superclass method) keyword in the decoration. cs class and in the subclasses, which embody the essence of the design pattern.

The code is shown again:

  /// <summary>
    ///Decoration class
    /// </summary>
    public class Decorator : Person
    {
        // Declare a parent object
        protected Person component;
        / / up
        public void Decora(Person component)
        {
            // Assign the passed object to the declared parent object. This is important to understand
            this.component = component;
        }
  
        public override void Show()
        {
            // If the object passed is not null, execute the show method below it
            if(component ! =null) { component.Show(); }}}Copy the code

The subclass:

 public class changku:Decorator
    {
        public override void Show()
        {
            Console.WriteLine("Pants");
            // Show the superclass method
            base.Show(); }}Copy the code

The output is as follows:

Finally, make a simple summary of the decorative pattern:

The value of a decorator is to decorate, and it does not affect the core functionality of the class being decorated. In an inherited system, subclasses are usually mutually exclusive. For example, the brand of a car can only be either Audi or BMW, but it cannot belong to both Audi and BMW, and the brand is also an important attribute of a car. But when you want to paint a car, change a seat, or change a stereo, these features are compatible with each other, and their presence doesn’t affect the car’s core attribute: what it is. At this point you can define a decorator: a painted car. It doesn’t matter whether he’s decorating a BMW or an Audi, his spray paint effect can be achieved.

The decorative pattern is more of a way to dynamically add more functionality to existing functionality.

Removing the decorations we added does not affect the main function. Welcome to guanchao.site

Welcome to applet: