注:示例来自《大话设计模式》
现有如下要求 写一个可以给人搭配不同的服饰的系统 代码如下
Person类
package Test06;
public class Person {
private String name;
public Person(String name)
{
this.name = name;
}
public void WearTShirts()
{
System.out.print("大T恤 ");
}
public void WearBigTrouser()
{
System.out.print("垮裤 ");
}
public void WearSneakers()
{
System.out.print("破球鞋 ");
}
public void WearSuit()
{
System.out.print("西装 ");
}
public void WearTie()
{
System.out.print("领带 ");
}
public void WearLeatherShoes()
{
System.out.print("皮鞋 ");
}
public void Show()
{
System.out.print("装扮的"+name);
}
}
客户端代码
package Test06;
public class Program {
public static void main(String[] args)
{
Person xc = new Person("小菜");
System.out.println("\n第一种装扮:");
xc.WearTShirts();
xc.WearBigTrouser();
xc.WearSneakers();
xc.Show();
System.out.println("\n第二种装扮:");
xc.WearSuit();
xc.WearTie();
xc.WearLeatherShoes();
xc.Show();
}
}
现在有个问题就是如果需要增加超人的装扮 该如何做呢
需要改Person类 违背了开放-封闭原则 应该把服饰都写成子类
重构后代码如下
Person类
package Test06;
public class Person {
private String name;
public Person(String name)
{
this.name = name;
}
public void Show()
{
System.out.print("装扮的"+name);
}
}
服饰抽象类
package Test06;
public abstract class Finery {
public abstract void Show();
}
各种服饰子类
package Test06;
public class TShirts extends Finery {
@Override
public void Show() {
System.out.print("大T恤 ");
}
}
package Test06;
public class BigTrouser extends Finery {
@Override
public void Show() {
System.out.print("垮裤 ");
}
}
package Test06;
public class Sneakers extends Finery {
@Override
public void Show() {
System.out.print("破球鞋 ");
}
}
package Test06;
public class Suit extends Finery {
@Override
public void Show() {
System.out.print("西装 ");
}
}
package Test06;
public class Tie extends Finery {
@Override
public void Show() {
System.out.print("领带 ");
}
}
package Test06;
public class LeatherShoes extends Finery {
@Override
public void Show() {
System.out.print("皮鞋 ");
}
}
客户端代码
package Test06;
public class Program {
public static void main(String[] args)
{
Person xc = new Person("小菜");
System.out.println("\n第一种装扮:");
Finery dtx = new TShirts();
Finery kk = new BigTrouser();
Finery pqx = new Sneakers();
dtx.Show();
kk.Show();
pqx.Show();
xc.Show();
System.out.println("\n第二种装扮:");
Finery xz = new Suit();
Finery ld = new Tie();
Finery px = new LeatherShoes();
xz.Show();
ld.Show();
px.Show();
xc.Show();
}
}
上面的代码是一个词一个词显示出来的 就好比 光着身子 当着大家的面 先穿 T恤 再穿裤子 再穿鞋 应该把所需的功能按正确的顺序串联起来进行控制 用装饰模式看看如何实现 代码如下
Person类
package Test06;
public class Person {
public Person()
{ }
private String name;
public Person(String name)
{
this.name = name;
}
public void Show()
{
System.out.print("装扮的"+name);
}
}
服饰类
package Test06;
public class Finery extends Person {
protected Person component;
//打扮
public void Decorate(Person component)
{
this.component = component;
}
@Override
public void Show()
{
if (component != null)
{
component.Show();
}
}
}
具体服饰类
package Test06;
public class TShirts extends Finery {
@Override
public void Show() {
System.out.print("大T恤 ");
super.Show();
}
}
package Test06;
public class BigTrouser extends Finery {
@Override
public void Show() {
System.out.print("垮裤 ");
super.Show();
}
}
package Test06;
public class Sneakers extends Finery {
@Override
public void Show() {
System.out.print("破球鞋 ");
super.Show();
}
}
package Test06;
public class Suit extends Finery {
@Override
public void Show() {
System.out.print("西装 ");
super.Show();
}
}
package Test06;
public class Tie extends Finery {
@Override
public void Show() {
System.out.print("领带 ");
super.Show();
}
}
package Test06;
public class LeatherShoes extends Finery {
@Override
public void Show() {
System.out.print("皮鞋 ");
super.Show();
}
}
客户端代码
package Test06;
public class Program {
public static void main(String[] args)
{
Person xc = new Person("小菜");
System.out.println("\n第一种装扮:");
Sneakers pqx = new Sneakers();
BigTrouser kk = new BigTrouser();
TShirts dtx = new TShirts();
pqx.Decorate(xc);
kk.Decorate(pqx);
dtx.Decorate(kk);
dtx.Show();
System.out.println("\n第二种装扮:");
LeatherShoes px = new LeatherShoes();
Tie ld = new Tie();
Suit xz = new Suit();
px.Decorate(xc);
ld.Decorate(px);
xz.Decorate(ld);
xz.Show();
}
}
装饰模式是为已有功能动态地添加更多功能的一种方式 它把每个要装饰的功能放在单独的类中 并让这个类包装它所要装饰的对象 可以在运行时 根据需要有选择地 按顺序地使用装饰功能包装对象
缺点:会产生过多的相似的对象 不容易排错