转发请注明出处:http://blog.csdn.net/qq_28055429/article/details/51571208
一,概念:动态地给一个对象添加一些额外的职责,就增加功能来说,装饰者模式比生成子类更为灵活
二,英文名:Decorator
三,理解:
(1)装饰者模式利用SetComponent来对对象进行包装的,每个装饰者对象的实现和如何使用这个对象是分开的,
(2) 每个装饰者对象只关心自己的功能,不关心如何被添加到对象链当中
四,结构图:
附加说明:
Component :是负责给对象动态添加职责的对象接口,
ConcreteComponent: 是可以添加一些职责的具体对象
Decorator :装饰者抽象类,继承并扩展Component类的功能,
ConcreteDecorator :给Component添加职责的具体装饰者对象,
注意: Component不需要知道Decorator的存在的
例子1:
Animal类:
class Animal {
private String name; //定义名字
public Animal() {}
public Animal(String name){ //
this.name = name;
}
//定义play方法
public void play(){
System.out.println("最后获得冠军的是:" + name);
}
}
/**
* 装饰者类,继承Animal
*
* @author maiyu
*
*/
class Decorator extends Animal {
private Animal animal;
public void Decorator(Animal animal) {
this.animal = animal;
}
@Override
public void play() { // 重写play方法
if (animal != null) {
animal.play();
}
}
}
四个动物类:Dog,Cat, Fish, Bird继承装饰者类:
public class Dog extends Decorator{
@Override
public void play() {
System.out.println("狗");
super.play();
}
}
public class Cat extends Decorator{
@Override
public void play() {
System.out.println("猫");
super.play();
}
}
public class Fish extends Decorator{
@Override
public void play() {
System.out.println("鱼");
super.play();
}
}
public class Bird extends Decorator{
@Override
public void play() {
System.out.println("鸟");
super.play();
}
}
测试类:
public class Test {
public static void main(String[] args){
Animal animal = new Animal("动物");
System.out.println("参加第一场比赛的动物分别是 :");
//创建动物对象
Dog dog = new Dog();
Cat cat = new Cat();
Fish fish = new Fish();
Bird bird = new Bird();
dog.Decorator(animal); //装扮狗
cat.Decorator(dog); //装扮猫
fish.Decorator(cat); //装扮鱼
bird.Decorator(fish); //装扮鸟
bird.play();
}
}
输出:
参加第一场比赛的动物分别是 :
鸟
鱼
猫
狗
最后获得冠军的是:动物
解说:
/**
* bird.play():先输出鸟,然后执行super.play()方法,其实就是执行Decorator中的方法
* 因为其Decorator已经设置值为鱼,故而相当于调用fish的play()方法
* fish.play(): 先输出鱼,再,,,,,相当于调用cat.play()
* cat.play(): 先输出猫,再,,,相当于调用dog.play()
* dog.play() : 先输出狗,再,,,相当于调用animal.play()
* animal.play():打印出最后的冠军是:动物
*/
这个例子虽然可以理解装饰者模式的概念,但可能不太能让我们明白装饰者模式的作用,那么看例子2,来理解装饰者模式的作用
例子2:
如某些公司a,b,各自的木匠和水管工到客户维修时,都先说出他们自己公司的敬语或者礼貌性动作:
如A公司:要求公司所有职员到客户家时需要说:你好
而B公司:要求公司所有职员到客户家里时需要先带脚套,防止弄脏客户家里
那么此题该怎么设计呢?继承??
那么就需要用:装饰者模式了
代码:
接口类:Worker
/**
* Component:对象接口,不需要知道Decorator的存在
* @author maiyu
*
*/
interface Worker {
public void doSomeWork();
}
水管工-----Plumber类:
/*
* ConcreteComponent:添加一些具体责任
*/
public class Plumber implements Worker{
public void doSomeWork() {
System.out.println("我是管水的,来修水管");
}
}
土木工----Carpenter:
/**
* ConcreteComponent:添加一些具体责任
*
*/
public class Carpenter implements Worker{
public void doSomeWork() {
System.out.println("我是土木工,来做土木工作");
}
}
CompanyA---A公司:
/**
* 装饰,添加责任
* @author maiyu
*
*/
public class CompanyA implements Worker{
private Worker worker;
public CompanyA(Worker worker) {
this.worker = worker;
}
public void doSomeWork() {
System.out.println("你好,我是A公司的员工!"); //添加A公司的要求
worker.doSomeWork();
}
}
CompanyB----B公司:
/**
* 装饰:添加责任
* @author maiyu
*
*/
public class CompanyB implements Worker{
private Worker worker;
public CompanyB(Worker worker) {
this.worker = worker;
}
public void doSomeWork() {
System.out.println("我是B公司的员工,我需要先戴手套"); //B公司的要求
worker.doSomeWork();
}
}
测试类:
public class Test {
public static void main(String[] args){
Plumber plumber = new Plumber(); //创建水管工对象
CompanyA a = new CompanyA(plumber); //A公司水管工
a.doSomeWork();
CompanyB b = new CompanyB(plumber); //B公司水管工
b.doSomeWork();
Carpenter carpenter = new Carpenter(); //创建土木工对象
CompanyA a2 = new CompanyA(carpenter); //A公司土木工
a2.doSomeWork();
CompanyB b2 = new CompanyB(carpenter); //B公司土木工
b2.doSomeWork();
}
}
输出结果:
你好,我是A公司的员工!
我是管水的,来修水管
我是B公司的员工,我需要先戴手套
我是管水的,来修水管
你好,我是A公司的员工!
我是土木工,来做土木工作
我是B公司的员工,我需要先戴手套
我是土木工,来做土木工作