[19/04/27-星期六] GOF23_结构型模式(装饰模式、外观模式)
一、装饰模式(decorator)
职责:动态的为一个对象增加新的功能。
是一种用于代替继承的技术,无须通过继承增加子类就能扩展对象的新功能。使用对象的关联关系代替继承关系,更加灵活,避免类体系的膨胀。
实现细节:
– Component抽象构件角色:真实对象和装饰对象有相同的接口。这样,客户端对象就能够以与真实对象相同的方式同装饰对象交互。
– ConcreteComponent 具体构件角色(真实对象):IO流中的FileInputStream、FileOutputStream
– Decorator装饰角色:持有一个抽象构件的引用。装饰对象接受所有客户端的请求,并把这些请求转发给真实的对象,这样,就能在真实对象调用前后增加新的功能。
– ConcreteDecorator具体装饰角色:负责给构件对象增加新的责任。


【被装饰对象与装饰对象】
/***
* 抽象组件ICar
*/
package cn.sxt.decorator; public interface ICar {
void move(); } //具体构件对象,被装饰对象,真实对象:普通的汽车
class Car implements ICar{
public void move() {
System.out.println("一辆普通的车");
}
} //装饰组件(们的祖宗),要传进去一个被装饰对象
class SuperCar implements ICar{
protected ICar car; public SuperCar(ICar car) {
this.car=car;
}
@Override
public void move() {
car.move();//调用的是接口中的move方法,因为car是ICar类的对象
}
} //各种具体装饰
class FlyCar extends SuperCar{ public FlyCar(ICar car) {
super(car);
}
public void fly() {
System.out.println("天上飞");
} @Override
public void move() {
super.move();//表示调用父类SuperCar的move方法
fly();
}
} class WaterCar extends SuperCar{ public WaterCar(ICar car) {
super(car);
}
public void swim() {
System.out.println("水中潜");
} @Override
public void move() {
super.move();//表示调用父类SuperCar的move方法
swim();
}
} class AICar extends SuperCar{ public AICar(ICar car) {
super(car);
}
public void auto() {
System.out.println("自动驾驶");
} @Override
public void move() {
super.move();//表示调用父类SuperCar的move方法
auto();
}
}
【客户端】
/**
*
*/
package cn.sxt.decorator; public class Client {
public static void main(String[] args) {
Car car=new Car();//被装饰对象,真实角色
car.move();
System.out.println("----增加新的功能:天上飞----");
FlyCar flyCar=new FlyCar(car);
flyCar.move();
System.out.println("----增加新的功能:天上飞+水下潜----");
WaterCar waterCar=new WaterCar(flyCar);//直接传入一个飞行汽车,在飞行汽车的基础上搞装饰(加水里游)
waterCar.move();
System.out.println("----增加新的功能:天上飞+人工智能----");
AICar iCar=new AICar(new FlyCar(car));//也可以这样写
iCar.move(); }
}
【UML类图】

示例场景:
– IO中输入流和输出流的设计
– Swing包中图形界面构件功能
– Servlet API 中提供了一个request对象的Decorator设计模式的默认实现类HttpServletRequestWrapper,HttpServletRequestWrapper类,增强了request对象的功能。
– Struts2中,request,response,session对象的处理

• 总结:
装饰模式(Decorator)也叫包装器模式(Wrapper)装饰模式降低系统的耦合度,可以动态的增加或删除对象的职责,并使得需要装饰的具体构建类和具体装饰类
可以独立变化,以便增加新的具体构建类和具体装饰类。
• 优点:
– 扩展对象功能,比继承灵活,不会导致类个数急剧增加;
– 可以对一个对象进行多次装饰,创造出不同行为的组合,得到功能更加强大的对象
– 具体构建类和具体装饰类可以独立变化,用户可以根据需要自己增加新的具体构件子类和具体装饰子类。
• 缺点:
– 产生很多小对象。大量小对象占据内存,一定程度上影响性能。
– 装饰模式易于出错,调试排查比较麻烦。
与桥接模式的区别:
两个模式都是为了解决过多子类对象问题。但他们的诱因不一样。桥模式是对象自身现有机制沿着多个维度变化,是既有部分不稳定。
装饰模式是为了增加新的功能。
二、外观模式(facade:正面,外表)




【各个政府机构接口】
/***
* 工商局
*/
package cn.sxt.facade; public interface AIC {
void checkName();
} class HaidianAIC implements AIC{
public void checkName() {
System.out.println("在海淀区工商局检查公司名字是否重名!"); }
} /**
*银行
*/
package cn.sxt.facade; public interface Bank {
void openAccount(); } class ICBC implements Bank{
@Override
public void openAccount() {
System.out.println("在中国工商银行开设公司账户!"); }
} /***
* 国家质检局
*/
package cn.sxt.facade; public interface SAMR {
void orgCode();
} class HaidianSAMR implements SAMR{
@Override
public void orgCode() {
System.out.println("在海淀区质检局办理组织机构登记代码证!"); }
} /***
* 税务局
*/
package cn.sxt.facade; public interface Tax {
void taxCertificate(); } class HaidianTax implements Tax{ public void taxCertificate() {
System.out.println("在海淀区税务局办理税务登记!"); }
}
【政府服务大厅】
/***
*注册公司流程
*政府综合办事服务大厅,客户只需要与它打交道即可
*服务中心去调用各个机构的方法,去与各个机构打交道
*/
package cn.sxt.facade; public class Register {
public void registerCompany(){
AIC aic=new HaidianAIC();
Bank icbc=new ICBC();
SAMR samr=new HaidianSAMR();
Tax tax=new HaidianTax();
aic.checkName();
icbc.openAccount();
samr.orgCode();
tax.taxCertificate();
}
}
【客户端】
/***
* 客户
*/
package cn.sxt.facade; public class Client {
public static void main(String[] args) {
//未采用外观模式的情况,需要一个机构一个机构去跑
/* AIC aic=new HaidianAIC();
Bank icbc=new ICBC();
SAMR samr=new HaidianSAMR();
Tax tax=new HaidianTax();
aic.checkName();
icbc.openAccount();
samr.orgCode();
tax.taxCertificate();*/ //采用外观模式,直接与政府服务中心打交道即可,效果一样
new Register().registerCompany();// Register re=new Register(); re.registerCompany(); }
}
开发中常见的场景:
频率很高,哪里都会遇到。各种技术和框架中,都有外观模式的使用。如:JDBC封装后的,commons提供的DBUtils类,Hibernate提供的工具类、Spring JDBC工具类等。
[19/04/27-星期六] GOF23_结构型模式(装饰模式、外观模式)的更多相关文章
- [19/04/28-星期日] GOF23_结构型模式(享元模式)
一.享元模式(FlyWeight,轻量级) [共享类与非共享类] /*** *FlyweightFactory享元工厂类: 创建并管理享元对象,享元池一般设计成键值对 */ package cn.sx ...
- 结构型设计模式之外观模式(Facade)
结构 意图 为子系统中的一组接口提供一个一致的界面,F a c a d e 模式定义了一个高层接口,这个接口使得这一子系统更加容易使用. 适用性 当你要为一个复杂子系统提供一个简单接口时.子系统往往因 ...
- Java门面模式(或外观模式)
门面模式(或外观模式)隐藏系统的复杂性,并为客户端提供一个客户端可以访问系统的接口. 这种类型的设计模式属于结构模式,因为此模式为现有系统添加了一个接口以隐藏其复杂性.门面模式涉及一个类,它提供客户端 ...
- 一天学习两个设计模式之Facade模式(外观模式,结构型模式)
程序这东西随着时间推移,程序会越来越大,程序中的类越来越多,而且他们之间相互关联,这会导致程序结构变得越来越复杂.因此我们在使用他们时候,必须要弄清楚他们之间的关系才能使用他们. 特别是在调用大型程序 ...
- GoF23种设计模式之结构型模式之外观模式
一.概述 为子系统中的一组接口提供一个一致的界面,外观模式定义了一个高层接口,这个接口使得这一子系统更加容易使用. 二.适用性 1.当你要为一个复杂子系统提供一个简单接口的时候.子系统 ...
- 结构型模式(五) 外观模式(Facade)
一.动机(Motivate) 在软件系统开发的过程中,当组件的客户(即外部接口,或客户程序)和组件中各种复杂的子系统有了过多的耦合,随着外部客户程序和各子系统的演化,这种过多的耦合面临很多变化的挑战. ...
- 七个结构模式之外观模式(Facade Pattern)
定义: 为子系统的一组接口提供一个统一的入口,从而降低系统之间的耦合度,提高子系统的可用性.外观模式又称为门面模式,是迪米特法则的一个体现,主要目的就是降低耦合. 结构图 Facade:抽象外观类,子 ...
- 【设计模式最终总结】桥接模式 VS 外观模式
差异点 外观模式,是把功能通过一个接口提供出来,方便日后更换实现,或者这种实现可以由多方提供,但同时只用一个.典型例子:@Slf4j 桥接模式,多个维度,每个维度提供一个接口,这些接口集中在一个类中, ...
- [19/04/26-星期五] GOF23_结构型模式(桥接模式、组合模式)
一.桥接模式(bridge) 场景:商城系统中常见的商品分类,以电脑为例,首先想到使用多层继承结构. —— 台式机(联想台式机.戴尔台式机.神舟台式机) 电脑 ——笔记本(联想笔记本.戴尔笔记本 ...
随机推荐
- PHP反射ReflectionClass、ReflectionMethod 学习笔记 (一)
PHP5 具有完整的反射API,添加对类.接口.函数.方法和扩展进行反向工程的能力. 反射是什么? 它是指在PHP运行状态中,扩展分析PHP程序,导出或提取出关于类.方法.属性.参数等的详细信息,包括 ...
- js中数组, JSON的与字符串的处理
1. JSON转字符串 var jsonStr = {"name": "xiaoming", "sex": "男"} J ...
- EMC光纤交换机故障处理和命令分析
主机没有Login到存储是一个比较常见的故障,故障多发于主机新上线,或者是重启后.例如在Unisphere中,显示Host状态是”Registered: Yes; Logged In: No” ...
- 【SSH网上商城项目实战28】使用Ajax技术局部更新商品数量和总价
转自: https://blog.csdn.net/eson_15/article/details/51487323 昨天把项目部署了一下,玩了玩,今天完善了一下购物车中修改商品数量就能局部 ...
- megajson 高性能的json序列化、反序列化工具
go 自带的 encoding/json 支持json的序列化和反序列化, 然而它是基于反射的,有下面几个缺点: 反射是性能差的代名词, 并且无法在编译时进行优化. 只有 Public 字段才可以,反 ...
- jenkins 分布式部署
一 什么是Jenkins的分布式构建和部署 Jenkins的分布式构建,在Jenkins的配置中叫做节点,分布式构建能够让同一套代码或项目在不同的环境(如:Windows7\winxp和Linux系统 ...
- 01.JavaScript-->js组成
- SQL-字符串运算符和函数
COALESCE(columnname,string) 函数 将 NULL 值作为字符串(用空字符串或其他字符串替换 NULL)- 接受一列输入值(字段)如果该字段为 NULL,则返回后面替换的字符串 ...
- AngularJS 最常用指令的功能
第一迭代输出之ng-repeat标签 ng-repeat让table ul ol等标签和js里的数组完美结合 <ul> <li ng-repeat="person in p ...
- 简单使用git上传代码
1,首先在github上面创建一个仓库 2,在本地目录中右击,选择git bash 3,将github上的仓库克隆到本地目录,(这个就是您的仓库) git clone https://github.c ...