博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
装饰器模式
阅读量:4626 次
发布时间:2019-06-09

本文共 3155 字,大约阅读时间需要 10 分钟。

转自:

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

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

 

 

 

 

转载于:https://www.cnblogs.com/nishilunhui/archive/2013/01/14/2859831.html

你可能感兴趣的文章
抽象类不能实例化对象
查看>>
树状数组(hdu-4325,hdu-1166,pat-1057)
查看>>
C#引用类型参数,ref按引用传值
查看>>
Flume简介与使用(二)——Thrift Source采集数据
查看>>
原生对象-Array
查看>>
词法解析的基本原理
查看>>
IDEA安装
查看>>
MySQL分库分表
查看>>
PyQt5--TextDrag
查看>>
Netty轻量级对象池实现分析
查看>>
Eclipse中的Web项目自动部署到Tomcat
查看>>
web前端学习总结--HTML
查看>>
非主流测试洞见:系统思考
查看>>
上海买车流程
查看>>
ExtJs store操作
查看>>
不要使用Integer做HashMap的key,尤其在json序列化的时候
查看>>
操作符重载调用优先级
查看>>
let和const
查看>>
获取样式的方法--参考
查看>>
URI的格式(URL)
查看>>