今天我们从一个日常每个人都会接触的地方下手——换装,人靠衣服马靠鞍,衣服确实能提升一个人的外表分数(可是我就不会 = =),那如果让你做一个给人搭配不同衣服的系统你会怎么做呢?
下面我们设计一个程序:
class 装饰模式: MonoBehaviour
{
private void Start()
{
Person xc = new Person("小明");
Debug.Log("\n 装扮:");
xc.WearTShirts();
xc.WearBigTrouser();
xc.WearWearSneakers();
xc.Show();
}
}
class Person
{
private string name;
public Person(string name)
{
this.name = name;
}
public void WearTShirts()
{
Debug.Log("大T恤");
}
public void WearBigTrouser()
{
Debug.Log("垮裤");
}
public void WearWearSneakers()
{
Debug.Log("破球鞋");
}
public void WearSuit()
{
Debug.Log("西装");
}
public void WearTie()
{
Debug.Log("领带");
}
public void WearLeatherShoes()
{
Debug.Log("皮鞋");
}
public void Show()
{
Debug.Log("装扮的"+name);
}
}
这样每个人穿什么我们就可以搭配了,这样看上去是不是也还可以,那如果我们增加一个别的装扮呢,是不是要该Person中的逻辑,那么,我们就违背了开放-封闭原则,这里说一下这个原则的内容:
开放封闭原则:
1.对扩展开放;2.对更改封闭
是说软件实体(类,模块,函数等)应该可以扩展,但是不能修改
那么我们是不是应该把每个方法分到不同的类中去管理,在调用就好了,就像这样:
class 装饰模式: MonoBehaviour
{
private void Start()
{
Person xc = new Person("小明");
Debug.Log("\n 装扮:");
Finery dtx = new TShirts();
dtx.Show();
xc.Show();
}
}
class Person
{
private string name;
public Person(string name)
{
this.name = name;
}
public void Show()
{
Debug.Log("装扮的"+name);
}
}
abstract class Finery
{
public abstract void Show();
}
class TShirts : Finery
{
public override void Show()
{
Debug.Log("大T恤");
}
}
//etc..各种类似类
这样是把服装和人分开了,但是在Start函数中的逻辑还不是很简洁,就像你换衣服是在大庭广众之下换的一样,我们应该把他单独封装起来,在一个试衣间里换衣服才是合理地不是吗,那么我们就用到了装饰模式
装饰模式
动态的给一个对象添加一些额外的职责,就增加功能来说,装饰模式比生成子类更为灵活。
class 装饰模式: MonoBehaviour
{
private void Start()
{
ConcreteComponent c = new ConcreteComponent();
ConcreteDecoratorA d1 = new ConcreteDecoratorA();
ConcreteDecoratorB d2 = new ConcreteDecoratorB();
d1.SetComponent(c);
d2.SetComponent(d1);
d2.Operation();
}
}
abstract class Component
{
public abstract void Operation();
}
class ConcreteComponent : Component
{
public override void Operation()
{
Debug.Log("具体对象的操作");
}
}
abstract class Decorator : Component
{
protected Component component;
public void SetComponent(Component component)
{
this.component = component;
}
public override void Operation()
{
if (component != null)
{
component.Operation();
}
}
}
class ConcreteDecoratorA : Decorator
{
private string addedState;
public override void Operation()
{
base.Operation();
addedState = "NewState";
Debug.Log("具体装饰对象A的操作");
}
}
class ConcreteDecoratorB : Decorator
{
private string addedState;
public override void Operation()
{
base.Operation();
addedState = "NewState";
Debug.Log("具体装饰对象B的操作");
}
}
有没有发现,其实装饰模式是利用SetComponent来对对象进行包装的。这样每个装饰对象的实现就和如何使用这个对象分开了,每个装饰对象只关心自己的功能,不需要关系如何被添加到对象链当中。
那么,让我们把刚才的例子用装饰模式改动一下,这里有一个小改动
如果只有一个ConcreteComponent类而没有抽象的Component类,那么Decorator类可以是ConcreteComponent的一个子类。同样道理,如果只有一个ConcreteDecorator类,那么就咩有必要建立一个单纯的Decorator类,而可以把Decorator和ConcreteDecorator的责任合并成一个类。
class 装饰模式: MonoBehaviour
{
private void Start()
{
Person xc = new Person("小明");
Debug.Log("装扮");
TShirts dtx = new TShirts();
BigTrouser kk = new BigTrouser();
dtx.Decorate(xc);
kk.Decorate(dtx);
kk.Show();
}
}
class Person
{
public Person()
{
}
private string name;
public Person(string name)
{
this.name = name;
}
public virtual void Show()
{
Debug.Log("装扮的"+name);
}
}
abstract class Finery : Person
{
protected Person component;
public void Decorate(Person component)
{
this.component = component;
}
public override void Show()
{
if (component != null)
{
component.Show();
}
}
}
class TShirts : Finery
{
public override void Show()
{
Debug.Log("大T恤");
base.Show();
}
}
class BigTrouser : Finery
{
public override void Show()
{
Debug.Log("垮裤");
base.Show();
}
}
//其余类似
完成!!今天你学废了吗!