java设计模式之门面模式

定义:

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

使用场景:

  1. 为一个复杂的模式或者子系统提供一个简洁的供外界访问的接口

  2. 希望提高子系统的独立性时

  3. 当子系统由于不可避免的暂时原因导致可能存在BUG或者性能相关问题时,可以通过门面模式提供一个高层接口,隔离客户端与子系统的直接交互,预防代码污染

UML类图:

java设计模式之门面模式_第1张图片

 

由上图可以看到,门面模式主要包含2个角色。

  1. 外观角色(Facade):也叫做门面角色,是系统对外的统一接口

  2. 子系统角色(SubSystem):可以同时有一个或者多个SubSystem。每个SubSystem都不是一个单独的类,而是一个类的集合。SubSystem并不知道Facade的存在,对于SubSystem而言,Facade只是另一个客户端而已(即Facade对与SubSystem透明)

通用写法:

package com.design.pattern.facade;
​
public class Client {
    public static void main(String[] args) {
        Facade facade = new Facade();
        facade.doA();
        facade.doB();
        facade.doC();
    }
    //子系统A
    static class SystemA{
        public void doA(){
            System.out.println("doing A stuff");
        }
    }
    //子系统B
    static class SystemB{
        public void doB(){
            System.out.println("doing B stuff");
        }
    }
    //子系统C
    static class SystemC{
        public void doC(){
            System.out.println("doing C stuff");
        }
    }
    //外观角色
    static class Facade{
        private SystemA a= new SystemA();
        private SystemB b= new SystemB();
        private SystemC c= new SystemC();
        //对外接口
        public void doA(){
            this.a.doA();
        }
        public void doB(){
            this.b.doB();
        }
        public void doC(){
            this.c.doC();
        }
    }
}

实例:

例如一个积分商城,可能涉及到积分系统,支付系统,物流系统的接口调用。如果所有接口调用全部由前端发送网络请求去调用现有接口,一则会增加前端开发人员的难度,二是会增加一些网络请求,影响页面性能。此时就可以发挥门面模式的优势了。将所有现成接口全部整合到一个类中,由后端提供统一的接口供前端调用,这样前端开发人员就不需要关心各接口的业务关系,只需要把精力集中在页面交互上。我们用代码来模拟场景

首先创建礼品的实体类GifyInfo

package com.design.pattern.facade;
​
public class GiftInfo {
    private String name;
​
    public GiftInfo(String name) {
        this.name = name;
    }
​
    public String getName() {
        return name;
    }
}

创建积分系统

package com.design.pattern.facade;
​
public class QualifyService {
    public boolean isAvailable(GiftInfo giftInfo){
        System.out.println("校验" + giftInfo.getName() + "积分资格通过,库存通过");
        return true;
    }
}

创建支付系统

package com.design.pattern.facade;
​
public class PaymentService {
    public boolean pay(GiftInfo giftInfo){
        System.out.println("支付" + giftInfo.getName() + "积分成功");
        return true;
    }
}

创建物流系统

package com.design.pattern.facade;
​
public class ShippingService {
    public String delivery(GiftInfo giftInfo){
        System.out.println(giftInfo.getName() + "进入物流系统");
        String shippingOrderNo = "666";
        return shippingOrderNo;
    }
}

创建门面系统,对外只开放exchange()方法:

package com.design.pattern.facade;
​
public class GiftFacadeService {
    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 delivery = shippingService.delivery(giftInfo);
                System.out.println("物流系统下单成功,订单号是:" + delivery);
            }
        }
    }
}

客户端代码:

package com.design.pattern.facade;
​
public class ClientTest {
    public static void main(String[] args) {
        GiftInfo giftInfo = new GiftInfo("java设计模式");
        GiftFacadeService f = new GiftFacadeService();
        f.exchange(giftInfo);
    }
}

运行结果:

校验java设计模式积分资格通过,库存通过
支付java设计模式积分成功
java设计模式进入物流系统
物流系统下单成功,订单号是:666

门面模式的优点:

  1. 简化了调用过程,不用深入了解子系统,以防给子系统带来风险

  2. 减少系统依赖,松散耦合

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

  4. 遵循迪米特法则

门面模式的缺点:

  1. 当增加子系统和扩展子系统行为时,可能同意带来未知的风险

  2. 不符合开闭原则

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

你可能感兴趣的:(java,设计模式,uml)