设计模式---装饰者模式

      装饰者模式拥有一个设计非常巧妙的结构。它可以动态添加对象功能。在基本的设计原则中,有一条重要的设计准则叫做合成、聚合复用原则。根据该原则的思想,代码复用应该尽可能使用委托,二部是使用继承。因为继承是一种紧密耦合,任何父类的改动都会影响子类。不利于系统维护。二委托则是松散耦合,只要接口不变,委托类的改动并不会影响其上层对象。

     装饰者模式就充分运用了这种思想,通过委托机制,复用了系统中的各个组件,在运行时,可以将这些功能组件进行叠加,从而构造一个“超级对象”,使其拥有所有这些组件的功能。而各个子功能模块,被很好地维护在各个组件的相关类中,拥有整洁的系统结构。

      装饰者模式的基本结构如下图所示。

装饰者和被装饰者拥有相同的接口。被装饰者通常是系统的核心组件,完成特定的功能目标。而装饰者可以在被装饰者的方法前后,加上特定的前置处理和后置处理,增强被装饰者的功能。

      装饰者模式的一个典型案例就是对输出结果进行增强。比如,现在需要将某一结果通过HTML进行发布,那么首先就需要将内容转化成一个HTML文本。同时,由于内容需要在网络上通过HTTP流传,故,还需要为其增加一个HTTP头。当然,作为一个更复杂的情况,可能还要为其安置TCP头等。但作为一个示例,这里做简化处理。

     装饰者模式的核心思想在于:无需将所有的逻辑,即,核心内容的构建、HTML文本构造和HTTP头生成等三个功能模块粘合在一起实现。通过装饰者模式,可以将它们分解为三个几乎完全独立的组件,并在使用的时候灵活地进行配置。为实现这个功能,可以使用如图所示的结构。

IPacketCreator即装饰接口,用于处理具体的内容。PacketBodyCreator是具体的组件,它的功能是构造要发布的信息的核心内容,但是它不负责将其构造成一个格式工整、可直接发布的数据格式。PacketHTTPHeaderCreator负责对给定的内容加上HTTP头部,PacketHTMLHeaderCreator负责借给定的接口格式化成HTML文本。3个功能模块相对独立且分离,易于维护。

    IPacketCreator的实现很简单,它是一个单方法的接口:

public interface IPackatCreator {
    public String handleContent(); //处理内容
}

PacketBodyCreator用于返回数据包的核心数据:

public class PacketBodyCreator implements IPackatCreator {

    public String handleContent() {
        return "Content of Packet";
    }
}

PacketDecorator维护核心组件component对象,它负责告知其子类,其核心业务逻辑应该全权委托component完成,自己仅仅是做增强处理。

public abstract class PacketDecorator implements IPackatCreator{

    IPackatCreator component;
    public PacketDecorator(IPackatCreator c){
        component = c;
    }
}

PacketHTMLHeaderCreator是具体的装饰器,它负责对核心发布的内容进行HTML格式化操作。需要特别注意的是,它委托了具体组件component进行核心业务处理。

public class PacketHTMLHeaderCreator extends PacketDecorator {


    public PacketHTMLHeaderCreator(IPackatCreator c) {
        super(c);
    }

    public String handleContent() {
        StringBuilder sb = new StringBuilder();
        sb.append("<html>");
        sb.append("<body>");
        sb.append(component.handleContent());
        sb.append("</body>");
        sb.append("</html>\n");
        return sb.toString();
    }
}

PacketHTTPHeaderCreator与PacketHTMLHeaderCreator类似,但是它完成数据包HTTP头部的处理。其余业务处理依然交由内部的component完成。

public class PacketHTTPHeaderCreator extends PacketDecorator {
    public PacketHTTPHeaderCreator(IPackatCreator c) {
        super(c);
    }

    public String handleContent() {
        StringBuilder sb = new StringBuilder();
        sb.append("Cache-Control: no-cache\n");
        sb.append("Date:Mon,31Dec201203:25:57GMT\n");
        sb.append(component.handleContent());

        return sb.toString();
    }
}

对于装饰者模式,另一个值得注意的地方是它的使用方法。在本利中,通过层层构造和组装这些被装饰者到一个对象中。使其有机地结合在一起工作。

public class Main {

    public static void main(String[] args){
        IPackatCreator pc = new PacketHTTPHeaderCreator(new PacketHTMLHeaderCreator(new PacketBodyCreator()));
        System.out.println(pc.handleContent());
    }
}

可以看到,通过装饰者的构造函数,将被装饰对象转入。本例中,共生成3个对象实例,作为核心组件的PacketBodyCreator是最先被构造的,其次PacketHTMLHeaderCreator,最后才是PacketHTTPHeaderCreator。

这个顺序表示,首先由PacketBodyCreator对象去生成核心发布内容,接着由PacketHTMLHeaderCreator对象对这个内容进行处理,将其转化为HTML,最后由PacketHttpHeaderCreator对PacketHTMLHeaderCreator的输出安置HTTP头部。程序运行的输出如下。

Cache-Control: no-cache
Date:Mon,31Dec201203:25:57GMT
<html><body>Content of Packet</body></html>

在JDK中,有不少组件也是用装饰者模式实现的。其中,一个最典型的例子就是OutputStream和InputStream类族的实现。以OutputStream为例,OutputStream对象提供的方法比较简单,功能比较弱,但通过各种装饰者的增强,OutputStream对象可以被赋予强大的功能。

 

Python网络爬虫与推荐算法新闻推荐平台:网络爬虫:通过Python实现新浪新闻的爬取,可爬取新闻页面上的标题、文本、图片、视频链接(保留排版) 推荐算法:权重衰减+标签推荐+区域推荐+热点推荐.zip项目工程资源经过严格测试可直接运行成功且功能正常的情况才上传,可轻松复刻,拿到资料包后可轻松复现出一样的项目,本人系统开发经验充足(全领域),有任何使用问题欢迎随时与我联系,我会及时为您解惑,提供帮助。 【资源内容】:包含完整源码+工程文件+说明(如有)等。答辩评审平均分达到96分,放心下载使用!可轻松复现,设计报告也可借鉴此项目,该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的。 【提供帮助】:有任何使用问题欢迎随时与我联系,我会及时解答解惑,提供帮助 【附带帮助】:若还需要相关开发工具、学习资料等,我会提供帮助,提供资料,鼓励学习进步 【项目价值】:可用在相关项目设计中,皆可应用在项目、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面,可借鉴此优质项目实现复刻,设计报告也可借鉴此项目,也可基于此项目来扩展开发出更多功能 下载后请首先打开README文件(如有),项目工程可直接复现复刻,如果基础还行,也可在此程序基础上进行修改,以实现其它功能。供开源学习/技术交流/学习参考,勿用于商业用途。质量优质,放心下载使用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

互联网极客

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值