C#设计模式学习之装饰者模式
写这个随笔时,其实对该模式理解的并不是十分透彻。在此想到什么写什么,希望对自己对他人有所帮助。
装饰者模式主要是应用继承和组合的思想,极大的实现了程序的多态,使得的程序有了更高的扩展性。
第一个基础例子:
这里假如我们要实现有这么一群人,他们都要穿西服。那么我们首先建立这个人类。
代码如下:
class Person { private string name; //要装扮的人的名称 public Person() { } public Person(string _name) { this.name = _name; } public virtual void Show() //注意此处是虚方法 { Console.WriteLine("装扮的人是:{0}", this.name); } }
然后构建西服类,代码如下
class Suit:Person { Person component = null; //穿西服的人 public void Decorate(Person _component) //把要穿西服的人传递到该类(组合思想) { this.component = _component; } public override void Show() { //如果有穿西服的人 if (component != null) { component.Show(); } Console.WriteLine("穿上西服"); } }
假如我们给小明和小红分别穿上西服,Main方法的代码如下
static void Main(string[] args) { Person xiaoming = new Person("小明"); Person xiaohong = new Person("小红"); Suit suit = new Suit(); //装扮小明 suit.Decorate(xiaoming); suit.Show(); //装扮小红 suit.Decorate(xiaohong); suit.Show(); Console.ReadKey(); }
运行结果如下
类图结构如下
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
第二个基础例子:
假如此时需求变了,我们的不仅要给小明和小红穿西服,我们还要给小狗阿黄穿西服,那该如何修改原程序呢。
开始扩展代码
此时我们新建一个Animal的抽象类
abstract class Animal //抽象的Animal类 { protected string name; public Animal() { } public Animal(string _name) { this.name = _name; } public abstract void Show(); //原来Person的虚方法则改为对应的抽象方法 }
然后我们继续新建Person类和Dog类,都继承Animal类
class Person : Animal //人类,继承自Animal类 { public Person(string _name) : base(_name) { } public override void Show() //实现Animal类的抽象方法 { Console.WriteLine("装扮的人{0}", base.name); } } class Dog : Animal //够类,继承自Animal类 { public Dog(string _name) : base(_name) { } public override void Show() //实现Animal类的抽象方法 { Console.WriteLine("装扮的狗{0}", base.name); } }
接下来我们分别给小明小红和阿黄穿上西服
static void Main(string[] args) { Person xiaoming = new Person("小明"); Person xiaohong = new Person("小红"); Dog ahuang = new Dog("阿黄"); //装扮小明和小红 Suit suit = new Suit(); suit.Decorate(xiaoming); suit.Show(); suit.Decorate(xiaohong); suit.Show(); //装扮阿黄 suit.Decorate(ahuang); suit.Show(); Console.ReadKey(); }
运行结果如下
类结构图如下,此时我们可以看到人和狗都继承自Animal,实现了一次的扩展的
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
第三个基础例子
此时我们不仅想让小明小红阿黄穿西服了,我们还想让他们穿鞋子,打领带,并且以后可能会有更多的衣服供他们选择(变成奇迹暖暖了);
我们在第二个例子的基础上继续修改,满足需求
此时,我们将原来的Suit类改成抽象的衣服类,然后分别让Suit,Shoes和Sneake类继承自衣服类来实现
首先构造衣服类,代码如下
class Finery : Animal //此处继承Animal的抽象类,从而实现了所有类都继承自Animal类,在Derorate组合获得的component的字段,都可以使用Show()方法,从而达到一层一层装扮的目的 { protected Animal component; public void Decorate(Animal _component) //注意:此处是组合的思想,主要是为了把要修饰的主体放到该类的component字段中 { this.component = _component; } public override void Show() { if (component != null) { component.Show(); } } }
然后分别构造西服,鞋子,领带类,代码如下
class Sneake : Finery { public override void Show()//此处实现的最上层Animal的抽象类 { base.Show(); Console.WriteLine("系上领带"); } } class Shoes : Finery { public override void Show()//此处实现的最上层Animal的抽象类 { base.Show(); Console.WriteLine("穿上鞋子"); } } class Suit : Finery { public override void Show()//此处实现的最上层Animal的抽象类 { base.Show(); Console.WriteLine("穿上西服"); } }
接下来开始给小红小明和阿黄装扮,代码如下
static void Main(string[] args) { //实例化所有被装饰的主体 Person xiaoming = new Person("小明"); Person xiaohong = new Person("小红"); Dog ahuang = new Dog("阿黄"); //实例化所有装饰 Suit suit = new Suit(); Sneake sneake = new Sneake(); Shoes shoes = new Shoes(); suit.Decorate(xiaoming); sneake.Decorate(suit); shoes.Decorate(sneake); shoes.Show(); Console.WriteLine(); suit.Decorate(xiaohong); sneake.Decorate(suit); shoes.Decorate(sneake); shoes.Show(); Console.WriteLine(); //狗就不系领带了 shoes.Decorate(ahuang); suit.Decorate(shoes); suit.Show(); Console.ReadKey(); }
运行结果如下:
类图结构如下
总结:
装饰者模式的难点在于多继承,存在组合的思想,将最高层次的被继承的类(Animal)组合(Decorate)在装饰类(Finery)中,通过base.Show()方法来一层一层的展现(这点有点绕,很像俄罗斯套娃,需要跟一下程序,一开始不太好理解)。
最后,如果有其他错误,欢迎指出,谢谢