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: