很多东西在装饰 着你:比如你的衣服...
所谓装饰吗,仅仅是装饰而已。假如你有一只狗,给它系了跟红领巾,变漂亮了,这就是装饰了。可是狗该跑还是跑,该叫还是叫,总之你装饰不能(至少大多数情况下不能)把原来的东西给装饰没了吧。还有,你小时候看过那些小人在机器人里的动画片吧,看看,人家叫来了机器人,钻到里面,手上就能开火了,两只脚也变成了火箭推进器,功能是大大地增加了呀 !看到了吧,装饰不仅仅是花架子。
在设计模式的世界里,也有装饰,这个装饰也不是花架子,它对于扩展现有系统的功能而尽量少改变原来的系统是很有帮助的。看看一个小例子:
(由于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声!
从此,我不用再去费劲自己去数它们叫了多少声了!而此时此刻,你依然可以使用没有被装饰过的鸭子(如果你不需要知道它们叫了多少声的话)。其实我们做的就是为每只鸭子装了个跟踪器。