门面模式和装饰器模式

1.门面模式

1.1门面模式定义

  又叫外观模式,提供了一个统一的接口,用来访问子系统中的一群接口。其主要特征是定义了一个高层接口,让子系统更容易使用,属于结构性模式。

1.2门面模式应用场景

  1.2.1子系统越来越复杂,增加门面模式提供简单接口

  1.2.2构建多层系统结构,利用门面对象作为每层的入口,简化层间调用。

1.3门面模式通用写法

  

  门面模式主要包含2 种角色:统一接口(门面角色,类图中的Facade) ,子系统角色(类图中的SubSystemA、SubSystemB、SubSystemC)

1.4门面模式业务场景实例

public class GiftInfo {

    private String name;

    public GiftInfo(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

}
//子系统角色
public class PaymentService {

    public boolean pay(GiftInfo giftInfo){
        System.out.println("扣减" + giftInfo.getName() + " 积分成功");
        return true;
    }
}
//子系统角色
public class QualifyService {

    public boolean isAvailable(GiftInfo giftInfo){
        System.out.println("校验" +giftInfo.getName() + "积分通过,库存通过。");
        return true;
    }

}
//子系统角色
public class ShippingService {
    public String delivery(GiftInfo giftInfo){
        System.out.println(giftInfo.getName() + "进入物流系统");
        String shippingNo = "666";
        return shippingNo;
    }
}
//外观角色
public class FacadeService {
    private QualifyService qualifyService = new QualifyService();
    private PaymentService paymentService = new PaymentService();
    private ShippingService shippingService = new ShippingService();


    public void exchange(GiftInfo giftInfo){
        if(qualifyService.isAvailable(giftInfo)){
            if(paymentService.pay(giftInfo)){
                String shippingNo = shippingService.delivery(giftInfo);
                System.out.println("物流系统下单成功,物流单号是:" + shippingNo);
            }
        }
    }
}

//测试类
public class Test {

    public static void main(String[] args) {

        FacadeService facadeService = new FacadeService();

        GiftInfo giftInfo = new GiftInfo("《Spring 5核心原理》");

        facadeService.exchange(giftInfo);

    }

}
View Code

测试结果展示

校验《Spring 5核心原理》积分通过,库存通过。
扣减《Spring 5核心原理》 积分成功
《Spring 5核心原理》进入物流系统
物流系统下单成功,物流单号是:666
View Code

1.5门面模式在源码中的应用

  1.5.1Spring JDBC 模块下的JdbcUtils 类,它封装了和JDBC 相关的所有操作

  1.5.2MyBatis 中的Configuration 类。它其中有很多new 开头的方法

  1.5.3Tomcat 的源码中RequestFacade 类它封装了非常多的request 的操作,也整合了很多servlet-api 以外的一些内容,给用户使用提供了很大便捷。同样,Tomcat 对Response 和Session 当也封装了

ResponseFacade 和StandardSessionFacade 类。

1.6门面模式的优缺点

  1.6.1优点:  

  1、简化了调用过程,无需深入了解子系统,以防给子系统带来风险。

  2、减少系统依赖、松散耦合

  3、更好地划分访问层次,提高了安全性

  4、遵循迪米特法则,即最少知道原则。

  1.6.2缺点:

  1、当增加子系统和扩展子系统行为时,可能容易带来未知风险

  2、不符合开闭原则

  3、某些情况下可能违背单一职责原则。

2.装饰器模式

2.1定义

  在不改变原有对象的基础之上,将功能附加到对象上,提供了比继承更有弹性的替代方案(扩展原有对象的功能),属于结构型模式装饰器模式的核心是功能扩展。使用装饰器模式可以透明且动态地扩展类的功能。

  通用装饰器UML图:  

 

  如上图,装饰器主要包括4种角色:

  1).抽象组件(Component):可以是一个接口或者抽象类,其充当被装饰类的原始对象,规定了被装饰对象的行为;

  2).具体组件(ConcreteComponent):实现或继承Component 的一个具体对象,也即被装饰对象;

  3).抽象装饰器(Decorator):通用的装饰ConcreteComponent 的装饰器.内部构成包括:

    a.一个属性指向Component 抽象组件

    b.该类一般是一个抽象类,主要是为了让其子类按照其构造形式传入一个Component 抽象组件,这是强制的通用行为.

    c.具体装饰器(ConcreteDecorator):Decorator 的具体实现类,理论上,每个ConcreteDecorator都扩展了Component 对象的一种功能;

    抽象装饰器源码:

public abstract class Decorator extends Component {
    /** 
     * 持有组件对象 
     */  
    protected Component component;  
  
    /** 
     * 构造方法,传入组件对象 
     * @param component 组件对象 
     */  
    public Decorator(Component component) {  
        this.component = component;  
    }  
  
    public void operation() {  
        //转发请求给组件对象,可以在转发前后执行一些附加动作  
        component.operation();  
    }  
  
}  
View Code

    测试类源码:

public class Client{
    public static void main(String[] args){
        Component c1 = new ConcreteComponent (); //首先创建需要被装饰的原始对象(即要被装饰的对象)
        Decorator decoratorA = new ConcreteDecoratorA(c1); //给对象透明的增加功能A并调用
        decoratorA .operation();

        Decorator decoratorB = new ConcreteDecoratorB(c1); //给对象透明的增加功能B并调用
        decoratorB .operation();
        Decorator decoratorBandA = new ConcreteDecoratorB(decoratorA);//装饰器也可以装饰具体的装饰对象,此时相当于给对象在增加A的功能基础上在添加功能B
        decoratorBandA.operation();
    }
}
View Code

2.2装饰器模式在源码中的应用

  2.2.1JDK 中体现最明显的类就是IO 相关的类, 如BufferedReader、InputStream、OutputStream.类图如下:

  

   2.2.2Spring 中的TransactionAwareCacheDecorator 类。这个类主要是用来处理事务缓存的。

public class TransactionAwareCacheDecorator implements Cache {
private final Cache targetCache;
public TransactionAwareCacheDecorator(Cache targetCache) {
Assert.notNull(targetCache, "Target Cache must not be null");
this.targetCache = targetCache;
}p
ublic Cache getTargetCache() {
return this.targetCache;
}
...
}
View Code

  2.2.3MVC 中的装饰器模式HttpHeadResponseDecorator 类

2.3装饰器模式和代理模式对比

  2.3.1装饰器模式其实是一种特殊的代理模式

  2.3.2装饰器模式强调自身功能的扩展,着重类功能的变化

  2.3.3代理模式强调对代理过程的控制

2.4装饰器模式的优缺点

  2.4.1优点:

  1)装饰器是继承的有力补充,比继承灵活,不改变原有对象的情况下动态地给一个对象扩展功能,即插即用。

  2)通过使用不同装饰类以及这些装饰类的排列组合,可以实现不同效果。

  3)装饰器完全遵守开闭原则

  2.4.2缺点

  1)会出现更多的代码,更多的类,增加程序复杂性。

  2)动态装饰时,多层装饰时会更复杂。

 

猜你喜欢

转载自www.cnblogs.com/majority/p/12441050.html