一、装饰模式(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工具类等。

                     

最新文章

  1. Dojo动画原理解析
  2. 安装RabbitMQ遇到的问题
  3. 正确运用synchronized和二次判断 实现多线程安全
  4. SQL2008-功能设置
  5. Oracle EBS-SQL (BOM-1):检查供应类型错误.sql
  6. Vim编辑器的使用和基本配置
  7. Shorten Diameter
  8. js观察者模式与Model
  9. mysql关闭/启用外键约束
  10. Python爬虫番外篇之Cookie和Session
  11. JBOD
  12. Redis 概念以及底层数据结构
  13. raise error
  14. 查看python中模块的所有方法
  15. spring整合mybatisXML版
  16. 简单说throw和throws的区别
  17. URI Scheme注册伪协议实现远程命令执行
  18. zookeeper 详解
  19. js与native的交互
  20. PAT 1069 微博转发抽奖

热门文章

  1. jQuery事件篇---过滤选择器 & 表单选择器
  2. [javaSE] GUI(事件监听机制)
  3. 十、获取异步线程返回值Callable
  4. java.lang.SecurityException: Permission Denial: reading com.android.providers.media.MediaProvider uri content://media/external/images/media/20 from pid=711, uid=10074 requires android.permission.READ_
  5. 3.java设计模式-建造者模式
  6. Apache shiro的简单介绍与使用(与spring整合使用,并加入ehcache缓存权限数据)
  7. Python Django 路由分发
  8. 用Jq遍历一个div里面的所有input 并判断是否为空?
  9. Java中的继承:父类和子类的关系
  10. Storage 的使用