大话设计模式-第06章 穿什么有这么重要?--装饰模式
2016-06-05 22:15
323 查看
第06章
穿什么有这么重要?--装饰模式
6.2 小菜扮靓第一版
“Person”类
class Person
{
private string name;
public Person(string name)
{
this.name = name;
}
public void WearTShirts()
{
Console.Write(“大T恤”);
}
public void WearBigTrouser()
{
Console.Write(“垮裤”);
}
public void WearSneakers()
{
Console.Write(“破球鞋”);
}
public void WearSuit()
{
Console.Write(“西装”);
}
public void WearTie()
{
Console.Write(“领带”)
}
public void WearLeatherShoes()
{
Console.Write(“皮鞋”)
}
public void Show()
{
Console.WriteLine(“装扮的{0}”,name);
}
}
客户端代码
static void Main(string[] args)
{
Person xc = new Person(“小菜”);
Console.WriteLine(“\n第一种装扮:”);
xc.WearRShirts();
xc.WearBigTrouser();
xc.WearSneakers();
xc.SHow();
Console.WriteLine(“\n第二种装扮:”);
xc.WearSuit();
xc.WearTie();
xc.WearLeatherShoes();
xc.Show();
Console.Read();
}
现在如果想增加新的装扮,就要修改Person类、这就违反了开放-封闭原则。
6.3 小菜扮靓第二版
Person类
class Person
{
private string name;
public Person(string name)
{
this.name = name;
}
public void Show()
{
Console.WriteLine(“装扮{0}”,name);
}
}
服饰抽象类
//服饰
abstract class Finery
{
public abstract void Show();
}
各种服饰子类
//大T恤
class TShirts : Finery
{
public override void Show()
{
Console.Write(“大T恤”);
}
}
……
客户端代码
static void Main(string[] args)
{
Person xc = new Person(“小菜”);
Console.WriteLine(“\n第一种装扮:”);
Finery dtx = new TShirts();
Finery kk = new BigTrouser();
Finery pqx = new Sneakers();
ddx.Show();
kk.Show();
pqx.Show();
xc.Show();
Console.WriteLine(“\n第二种装扮:”);
Finery xz = new Suit();
Finery ld = new Tie();
Finery px = new LeatherShoes();
xz.Show();
ld.Show();
px.Show();
xc.Show();
Console.Read();
}
建造者要求建造的过程必须是稳定的,而现在我们这个例子,建造过程是不稳定的,各种人的穿衣顺序完全不同,穿衣风格也不同,因此不适合用建造者模式。
此例中我们要把所需的功能按正确顺序串联起来进行控制。
6.4 装饰模式
装饰模式(Decorator),动态地给一个对象添加一些额外的职责,就增加功能来说,装饰模式比生成子类更加灵活。
“Component是定义一个对象接口,可以给这些对象动态地添加职责。ConcreteComponent是定义了一个具体的对象,也可以给这个对象添加一些职责。Decorator,装饰抽象类,继承了Component,从外类来扩展Component类的功能,但对于Component来说,是无需知道Decorator的存在的。至于ConcreteDecorator就是具体的装饰对象,起到给Component添加职责的功能。
Component类
abstract class Component
{
public abstract void Operation();
}
ConcreteComponent类
class ConcreteComponent : Component
{
public override void Operation()
{
Console.WriteLine(“具体对象的操作”);
}
}
Decorator类
abstract class Decorator : Component //注意这里,装饰类也是继承与Component抽象类
{
protected Component component;
public void SetComponent(Component component)
{
this.component = component;
}
public override void Operation()
{
if(component != null)
{
component.Operation();
}
}
}
ConcreteDecoratorA类
class ConcreteDecoratorA:Decorator
{
private string addState;
public override void Operation() // 注意这个操作是抽象类中定义的操作
{
base.Operation();
addedState = “New State”;
Console.WriteLine(“具体装饰对象A的操作”);
}
}
class ConcreteDecoratorB : Decorator
{
public override void Operation()
{
base.Operation();
AddedBehavior();
Console.WriteLine(“具体装饰对象B的操作”);
}
private void AddedBehavior()
{
}
}
客户端代码
static void Main(string[] args)
{
ConcreteComponent c = new ConcreteComponent();
ConcreteDecoratorA d1 = new ConcreteDecoratorA();
ConcreteDecoratorB d2 = new ConcreteDecoratorB();
d1.SetComponent(c);
d2.SetComponent(d1);
d2.Operation;
Console.Read();
}
装饰模式是利用SetComponent来对对象进行包装。这样每个装饰对象的实现就和如何使用这个对象分离开了,每个装饰对象只关心自己的功能,不需要关心如何被添加到对象链当中去。
6.5 小菜扮靓第三版
“Person”类 ConcreteComponent
class Person
{
public Person()
{ }
private string name;
public Person(string name)
{
this.name = name;
}
public virtual void Show()
{
Console.WriteLine(“装扮的{0}”,name);
}
}
服饰类(Decorator)
class Finery:Person
{
protected Person component;
//打扮
public void Decorate(Person component)
{
this.component = component;
}
public override void Show()
{
if (component != null)
{
component.Show();
}
}
}
具体服饰类(ConcreteDecorator)
class TShirts : Finery
{
public override void Show()
{
Console.Write(“大T恤”);
base.Show();
}
}
class BigTrouser : Finery
{
public override void Show()
{
Console.Write(“垮裤”);
base.Show();
}
}
//其余类类似,省略
………
客户端代码
static void Main(string[] args)
{
Person xc = new Person(“小菜”);
Console.WriteLine(“\n第一种装扮:”);
Sneakers pax = new Sneakers();
BigThrouser kk = new BigTrouser();
TShirts dtx = new TShirts();
pqx.Decorate(xc);
kk.Decorate(pqx);
dtx.Decorate(kk);
dtx.Show();
Console.WriteLine(“\n第二种装扮:”);
LeatherShoes px = new LeatherShoes();
Tie ld = new Tie();
Suit xz = new Suit();
px.Decorate(xc);
ld.Decorate(px);
xz.Decorate(ld);
xz.Show();
Console.Read();
}
6.6 装饰模式总结
装饰模式是为已有功能动态地添加更多更能的一种方式。当系统需要新功能的时候,是向旧的类中添加新的代码。这些新的代码通常装饰了原有类的核心职责或主要行为,在主类中加入了新的字段,新的方法和新的逻辑,从而增加了主类的复杂度,而这些新加入的东西仅仅是为了满足一些在某些特定情况下才会执行的特殊行为的需求。装饰模式却提供了一个非常好的解决方案,它把每个要装饰的功能放在单独的类中,并让这个类包装他所要装饰的对象,因此,当需要执行特殊行为时,客户代码就可以在运行时根据需要有选择地、按顺序地使用装饰功能包装对象了。
装饰模式的优点:把类中的装饰功能从类中搬移去除,这样可以简化原有的类。这样做最大的好处是有效地把类的核心职责和装饰功能区分开了。而且可以去除相关类中重复的装饰逻辑。
穿什么有这么重要?--装饰模式
6.2 小菜扮靓第一版
“Person”类
class Person
{
private string name;
public Person(string name)
{
this.name = name;
}
public void WearTShirts()
{
Console.Write(“大T恤”);
}
public void WearBigTrouser()
{
Console.Write(“垮裤”);
}
public void WearSneakers()
{
Console.Write(“破球鞋”);
}
public void WearSuit()
{
Console.Write(“西装”);
}
public void WearTie()
{
Console.Write(“领带”)
}
public void WearLeatherShoes()
{
Console.Write(“皮鞋”)
}
public void Show()
{
Console.WriteLine(“装扮的{0}”,name);
}
}
客户端代码
static void Main(string[] args)
{
Person xc = new Person(“小菜”);
Console.WriteLine(“\n第一种装扮:”);
xc.WearRShirts();
xc.WearBigTrouser();
xc.WearSneakers();
xc.SHow();
Console.WriteLine(“\n第二种装扮:”);
xc.WearSuit();
xc.WearTie();
xc.WearLeatherShoes();
xc.Show();
Console.Read();
}
现在如果想增加新的装扮,就要修改Person类、这就违反了开放-封闭原则。
6.3 小菜扮靓第二版
Person类
class Person
{
private string name;
public Person(string name)
{
this.name = name;
}
public void Show()
{
Console.WriteLine(“装扮{0}”,name);
}
}
服饰抽象类
//服饰
abstract class Finery
{
public abstract void Show();
}
各种服饰子类
//大T恤
class TShirts : Finery
{
public override void Show()
{
Console.Write(“大T恤”);
}
}
……
客户端代码
static void Main(string[] args)
{
Person xc = new Person(“小菜”);
Console.WriteLine(“\n第一种装扮:”);
Finery dtx = new TShirts();
Finery kk = new BigTrouser();
Finery pqx = new Sneakers();
ddx.Show();
kk.Show();
pqx.Show();
xc.Show();
Console.WriteLine(“\n第二种装扮:”);
Finery xz = new Suit();
Finery ld = new Tie();
Finery px = new LeatherShoes();
xz.Show();
ld.Show();
px.Show();
xc.Show();
Console.Read();
}
建造者要求建造的过程必须是稳定的,而现在我们这个例子,建造过程是不稳定的,各种人的穿衣顺序完全不同,穿衣风格也不同,因此不适合用建造者模式。
此例中我们要把所需的功能按正确顺序串联起来进行控制。
6.4 装饰模式
装饰模式(Decorator),动态地给一个对象添加一些额外的职责,就增加功能来说,装饰模式比生成子类更加灵活。
“Component是定义一个对象接口,可以给这些对象动态地添加职责。ConcreteComponent是定义了一个具体的对象,也可以给这个对象添加一些职责。Decorator,装饰抽象类,继承了Component,从外类来扩展Component类的功能,但对于Component来说,是无需知道Decorator的存在的。至于ConcreteDecorator就是具体的装饰对象,起到给Component添加职责的功能。
Component类
abstract class Component
{
public abstract void Operation();
}
ConcreteComponent类
class ConcreteComponent : Component
{
public override void Operation()
{
Console.WriteLine(“具体对象的操作”);
}
}
Decorator类
abstract class Decorator : Component //注意这里,装饰类也是继承与Component抽象类
{
protected Component component;
public void SetComponent(Component component)
{
this.component = component;
}
public override void Operation()
{
if(component != null)
{
component.Operation();
}
}
}
ConcreteDecoratorA类
class ConcreteDecoratorA:Decorator
{
private string addState;
public override void Operation() // 注意这个操作是抽象类中定义的操作
{
base.Operation();
addedState = “New State”;
Console.WriteLine(“具体装饰对象A的操作”);
}
}
class ConcreteDecoratorB : Decorator
{
public override void Operation()
{
base.Operation();
AddedBehavior();
Console.WriteLine(“具体装饰对象B的操作”);
}
private void AddedBehavior()
{
}
}
客户端代码
static void Main(string[] args)
{
ConcreteComponent c = new ConcreteComponent();
ConcreteDecoratorA d1 = new ConcreteDecoratorA();
ConcreteDecoratorB d2 = new ConcreteDecoratorB();
d1.SetComponent(c);
d2.SetComponent(d1);
d2.Operation;
Console.Read();
}
装饰模式是利用SetComponent来对对象进行包装。这样每个装饰对象的实现就和如何使用这个对象分离开了,每个装饰对象只关心自己的功能,不需要关心如何被添加到对象链当中去。
6.5 小菜扮靓第三版
“Person”类 ConcreteComponent
class Person
{
public Person()
{ }
private string name;
public Person(string name)
{
this.name = name;
}
public virtual void Show()
{
Console.WriteLine(“装扮的{0}”,name);
}
}
服饰类(Decorator)
class Finery:Person
{
protected Person component;
//打扮
public void Decorate(Person component)
{
this.component = component;
}
public override void Show()
{
if (component != null)
{
component.Show();
}
}
}
具体服饰类(ConcreteDecorator)
class TShirts : Finery
{
public override void Show()
{
Console.Write(“大T恤”);
base.Show();
}
}
class BigTrouser : Finery
{
public override void Show()
{
Console.Write(“垮裤”);
base.Show();
}
}
//其余类类似,省略
………
客户端代码
static void Main(string[] args)
{
Person xc = new Person(“小菜”);
Console.WriteLine(“\n第一种装扮:”);
Sneakers pax = new Sneakers();
BigThrouser kk = new BigTrouser();
TShirts dtx = new TShirts();
pqx.Decorate(xc);
kk.Decorate(pqx);
dtx.Decorate(kk);
dtx.Show();
Console.WriteLine(“\n第二种装扮:”);
LeatherShoes px = new LeatherShoes();
Tie ld = new Tie();
Suit xz = new Suit();
px.Decorate(xc);
ld.Decorate(px);
xz.Decorate(ld);
xz.Show();
Console.Read();
}
6.6 装饰模式总结
装饰模式是为已有功能动态地添加更多更能的一种方式。当系统需要新功能的时候,是向旧的类中添加新的代码。这些新的代码通常装饰了原有类的核心职责或主要行为,在主类中加入了新的字段,新的方法和新的逻辑,从而增加了主类的复杂度,而这些新加入的东西仅仅是为了满足一些在某些特定情况下才会执行的特殊行为的需求。装饰模式却提供了一个非常好的解决方案,它把每个要装饰的功能放在单独的类中,并让这个类包装他所要装饰的对象,因此,当需要执行特殊行为时,客户代码就可以在运行时根据需要有选择地、按顺序地使用装饰功能包装对象了。
装饰模式的优点:把类中的装饰功能从类中搬移去除,这样可以简化原有的类。这样做最大的好处是有效地把类的核心职责和装饰功能区分开了。而且可以去除相关类中重复的装饰逻辑。
相关文章推荐
- 机器学习笔记-聚类算法K-means和FCM的学习小结
- c++第七次实验
- HTML中的表单元素
- 学习进度条--第十四周
- The Definitive Antlr 4 第8章学习笔记
- Java基础语法学习——面向对象基础
- android常用的控件ViewPager的使用
- spring-AOP编程出现org.springframework.beans.factory.BeanCreationException
- jvmti
- 汇编学习(十五)X86汇编学习 (2)MBR为例
- c++第七次上机作业
- 二分查找 -- 代码之美
- 团队冲刺(二)个人工作总结3
- PRML 第二章 多项式分布
- C++第七次实验
- linux 内核定时器
- c++第七次上机实验
- HDU--2099 整除的尾数
- Mac下webpack安装
- jquery插件方式实现table查询功能