您的位置:首页 > 其它

装饰器模式

2013-01-14 15:47 288 查看
转自:/article/3645504.html

很多东西在装饰 着你:比如你的衣服...

所谓装饰吗,仅仅是装饰而已。假如你有一只狗,给它系了跟红领巾,变漂亮了,这就是装饰了。可是狗该跑还是跑,该叫还是叫,总之你装饰不能(至少大多数情况下不能)把原来的东西给装饰没了吧。还有,你小时候看过那些小人在机器人里的动画片吧,看看,人家叫来了机器人,钻到里面,手上就能开火了,两只脚也变成了火箭推进器,功能是大大地增加了呀 !看到了吧,装饰不仅仅是花架子。

在设计模式的世界里,也有装饰,这个装饰也不是花架子,它对于扩展现有系统的功能而尽量少改变原来的系统是很有帮助的。看看一个小例子:
(由于Java概念上的规范性,Java是很适合来做设计模式的例子的)

继续我们鸭子的故事:

鸭子一般都是会叫的东西,前提是它是活的,如果是一只木头鸭子,那它就不会叫了。。。

package dec;

public interface Quackable {
//会叫的东西都要实现这个接口
public void quack();
}

下面是我们搞来的一只鸭子,它是红头鸭,是一种会呱呱叫的鸭子:

package dec;

public class RedheadDuck implements Quackable {

@Override
public void quack() {
// TODO Auto-generated method stub
System.out.println("我在呱呱叫!!");
}

}

毕竟不仅仅红头鸭会呱呱叫 ,我们又逮了一只绿头鸭:

package dec;

public class MallardDuck implements Quackable {

@Override
public void quack() {
// TODO Auto-generated method stub
System.out.println("我在呱呱叫!!");
}

}

技术太发达了,居然可以模拟呱呱叫的机器都出来了:

package dec;

public class DuckCall implements Quackable {

@Override
public void quack() {
// TODO Auto-generated method stub
System.out.println("我在模拟呱呱叫!!");
}

}

玩具厂商生产了一种橡皮鸭子(捏一捏可会吱吱叫的哦):
package dec;

public class RubberDuck implements Quackable {

@Override
public void quack() {
// TODO Auto-generated method stub
System.out.println("吱吱叫!!");
}

}

我们把这些真真假假的鸭子弄到一起,听听它们的叫声:

package dec;

public class DuckSimulator {

/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
DuckSimulator simulator = new DuckSimulator();
simulator.simulate();
}

void simulate(){
Quackable mduck = new MallardDuck();
Quackable rduck = new RedheadDuck();
Quackable duckCall = new DuckCall();
Quackable rubberDuck = new RubberDuck();

System.out.println("鸭子模拟器:/n");
simulate(mduck);
simulate(rduck);
simulate(duckCall);
simulate(rubberDuck);
}

void simulate(Quackable duck){
duck.quack();
}
}

输出:

鸭子模拟器:

呱呱叫!!!
我在呱呱叫!!
我在模拟呱呱叫!!
吱吱叫!!

哈哈,他们都在叫!!他们叫了多少声啊,我数了数叫了4下 !,可能不能让程序自己给我统计出来。。增加功能,那就装饰器呗:

package dec;

public class QuackCounter implements Quackable {

Quackable duck;
static int numberOfQuacks;

public QuackCounter(Quackable duck){
this.duck = duck;
}

@Override
public void quack() {
// TODO Auto-generated method stub
duck.quack();
numberOfQuacks ++;
}

public static int getQuacks(){
return numberOfQuacks;
}
}

正如你所见的,装饰器也是一个会叫的东西,毕竟,我们需要的还是鸭子。。。至于要装饰哪只鸭子,你当然得告诉装饰器了,正如构造函数里所做的那样!

我们看看装饰后的效果:
package dec;

public class DuckSimulator {

/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
DuckSimulator simulator = new DuckSimulator();
simulator.simulate();
}

void simulate(){
Quackable mduck = new QuackCounter(new MallardDuck());
Quackable rduck = new QuackCounter(new RedheadDuck());
Quackable duckCall = new QuackCounter(new DuckCall());
Quackable rubberDuck = new QuackCounter(new RubberDuck());

System.out.println("鸭子模拟器:/n");
simulate(mduck);
simulate(rduck);
simulate(duckCall);
simulate(rubberDuck);
System.out.println("我们一共叫了 " + QuackCounter.getQuacks() + "少声!");
}

void simulate(Quackable duck){
duck.quack();
}
}

输出:

鸭子模拟器:

呱呱叫!!!
我在呱呱叫!!
我在模拟呱呱叫!!
吱吱叫!!
我们一共叫了 4少声!

从此,我不用再去费劲自己去数它们叫了多少声了!而此时此刻,你依然可以使用没有被装饰过的鸭子(如果你不需要知道它们叫了多少声的话)。其实我们做的就是为每只鸭子装了个跟踪器,呵呵。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: