1.初始装饰模式:
在进行OO编程的时候,大家一定遇到过类似的情况:那就是“销售人员的固化问题”,即现在有这样一种销售人员类:化妆品销售人员,他具有销售方法,现在要让让化妆品销售人员可以进行化妆和打扫卫生的功能,怎么实现呢?如果按照原始的类继承的方式实现,虽然是能够实现的;但是要是在这个基础上在让这个化妆品销售人员具有定换装品价格的功能,那么就又要继续继承,这显然是不太好的吧,这会导致子类膨胀 ,最终将会导致不可控制的类爆炸而使得设计失败。
实际上在上面的例子中说的可以抽象成这样的一类情况:给对象添加一些额外的功能。针对这种情况用装饰模式来设计系统是比较好的。即我们想通过一个装饰类完成对某一个类的所有的增加职责,也就是对这个类进行装饰。
2.用装饰模式解决销售人员能力固化问题:
销售人员基类:
public abstract class Employee
{
private String name;//员工名字属性
public String getName()
{
Return name;
}
Public void setName()
{
this.name = name;
}
Public Employee()
{
Super();
}
Public Employee(String name)
{
This.name = name;
}
Public abstract void work();//抽象方法
}
有两类销售人员类:化妆品销售人员和水果销售人员。这两个类继承Employee类并实现work()方法。
化妆品销售人员类:
Public class CosmeticsSalesEmployee extends Employee
{
Public CometicsSalesEmployee(String name)
{
Super(name);
}
Public void work()
{
Syetem.out.println(getName() + “开始销售化妆品。”);
}
}
水果销售人员:
Public class FruitSalesEmployee extends Employee
{
Public FruitSalesEmployee (String name)
{
Super(name);
}
Public void work()
{
Syetem.out.println(getName() + “开始销售水果。”);
}
}
现在要给两种销售人员增加功能,我们引入一个装饰类EmployeeDecorator。这个类负责完成对销售人员的功能的增加。
Public abstract classemployeeDecorator extends Employee
{
Private Employee employee;
Public EmployeeDecorator(Employee employee)
{
//这个构造方法是典型的装饰模式的构造方法
This.employee = employee;
}
Public String getName()
{
Return employee.getName();
}
Public void work()
{
employee.work();
}
}
其实,要给销售人员增加:1.打扫卫生;2.整理货物;3.清洗商品功能。这要通过实现三个类实现。
打扫卫生装饰类:
Public class CleanDecorator extends employeeDecorator
{
Public CleanDecorator (Employee employee)
{
Super(employee);
}
Public work()
{
Super.work();
Syetem.out.println(emploree.getName() + “开始打扫”);
}
}
整理货架装饰类:
Public class ArrangeGoodDecorator extends EmployeeDecorator
{
Public ArrangeGoodDecorator(Employee employee)
{
super(employee);
}
Public work()
{
System.out.println(employee.getName() + “开始整理货架。”);
Super.work();
}
}
清洗商品装饰类:
Public class WashFruitEdcorator extends EmployeeDecorator
{
Public WashFruitEdcorator(Employee employee)
{
super(employee);
}
Public work()
{
System.out.println(employee.getName() + “开始清洗商品。”);
Super.work();//不要小看这个super调用哦,这个是一个递归的过程哈
//仔细体会一下。
}
}
下面实现client客户使用类
Public class client
{
Public static void main(String []args)
{
Employee fruitSaler = new FruitSalesEmployee(“张三”);
Employee comseticsSaler = new CosmseticsEmployee(“李四”);
Syetem.out.println(“本职工作:”);
fruitSaler.work();
cosmeticsSaler.work();
System.out.println(“装饰工作”);
fruitSaler = new CleanDecorator(new WashGodsDecorator(new WashGoodsDecorator(fruitSaler)));
//体会这种调用方式
fruitSaler.work();
cosmeticsSaler = new ArrangeGoodsDecorator(new Cleandecorator(cosmeticsSaler));
cosmeticsSaler.work();
}
}
运行的输出结果是:
本职工作:
张三开始销售水果
李四开始销售化妆品
装饰工作:
张三开始清洗商品
张三开始清洗商品
张三开始打扫
张三开始销售水果
李四开始整理货架
李四开始打扫
李四开始销售化妆品
3.装饰模式小结
从上面的实现的方式发现这看起来像是一个对象一层一层包装起来一样,这也正是装饰模式别名“包装器”的由来。我的理解是这样的:1装饰模式的类EmployeeDecorator其实是从Employee类继承来的,也是用来装饰Employee类的,这点要注意;2同时在装饰类中有一个这样的构造方法:
Public EmployeeDecorator(Employee employee)
{
//这个构造方法是典型的装饰模式的构造方法
This.employee = employee;
}
这个构造方法有点特殊的,参数是Employee类型哦,这个使得一层一层装饰成为了可能,也就是通过不断的给一个Employee增加功能变得极其方便;3还有一点就是体会一下在Client中具体怎么使用的情况。
那么,现在大家是否体会到了用装饰模式和用之前的继承有什么区别呢?如果是用继承来实现功能增加,那么每次添加有一种功能的销售人员,则要进行一次继承,这样到最后继承的层次会很高,如果在设计的最初就已经确定的每种销售人员具有哪些功能,那么用不用装饰模式就无所谓了,因为,没有增加功能的可能,但是了,现实不是一成不变的,所以装饰模式有极大的意义。