装饰器模式,顾名思义就是对一个主体进行修饰。
原理就是用一个新的类去包含一个旧的类,在新的类中先调用旧的类的方法,再调用新的类中新添加的方法。这样就实现了链式调用。然后可以不断的添加新的修饰类去修饰。
为了能使新的类(装饰类)能够包含旧的类(主体类或者已经经过修饰的修饰类),就需要统一基类,所以不论是主体类还是修饰类都需要继承同一个基类。
用代码来举例:
1.定义2个主体类,Man和Women,都继承与Body这一个基类。Body中的Print方法是最关键的,整个链式方法的调用全是通过这个Print方法来实现的。
public abstract class Body
{
public abstract void Print();
}
public class Man : Body
{
public override void Print()
{
Console.WriteLine("男人");
}
}
public class Woman : Body
{
public override void Print()
{
Console.WriteLine("女人");
}
}
2.定义装饰抽象类
public abstract class Decorator : Body
{
public abstract override void Print();
}
这个抽象类的作用是可以简化很多代码,可以将很多不需要装饰类修改的方法可以在这个抽象类中完成,而不需要再每个装饰类都写一样的方法
3.定义装饰类
public class Clothes : Decorator
{
private readonly Body _body;
public Clothes(Body body)
{
_body = body;
}
public override void Print()
{
_body.Print();
Console.WriteLine("穿上衣服");
}
}
public class Shoes : Decorator
{
private readonly Body _body;
public Shoes(Body body)
{
_body = body;
}
public override void Print()
{
_body.Print();
Console.WriteLine("穿上鞋子");
}
}
public class Pants : Decorator
{
private readonly Body _body;
public Pants(Body body)
{
_body = body;
}
public override void Print()
{
_body.Print();
Console.WriteLine("穿上裤子");
}
}
可以看到,每一个装饰类中的Print方法都是先调用body的Print方法,然后再调用自己的方法。就基本实现了链式调用。
调用
class Program
{
static void Main(string[] args)
{
Body man = new Man();
man = new Shoes(man);
man = new Pants(man);
man = new Clothes(man);
man = new Clothes(man);
man = new Clothes(man);
man.Print();
Console.ReadLine();
}
}
结果
还可以采用另外一种方式来定义装饰器抽象类和装饰类。
2.1装饰抽象类
public abstract class Decorator : Body
{
private readonly Body _body;
protected Decorator(Body body)
{
_body = body;
}
public override void Print()
{
_body.Print();
}
}
3.1装饰类
public class Clothes : Decorator
{
public Clothes(Body body):base(body)
{
}
public override void Print()
{
base.Print();
Console.WriteLine("穿上衣服");
}
}
public class Shoes : Decorator
{
public Shoes(Body body) : base(body)
{
}
public override void Print()
{
base.Print();
Console.WriteLine("穿上鞋子");
}
}
public class Pants : Decorator
{
public Pants(Body body) : base(body)
{
}
public override void Print()
{
base.Print();
Console.WriteLine("穿上裤子");
}
}
个人比较倾向第一种模式