Java设计模式之结构型-外观模式(UML类图+案例分析)

目录

一、基础概念

二、UML类图

三、角色设计

四、案例分析

五、总结


一、基础概念

外观模式,为子系统中的一组接口提供一个一致的界面,此模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。

二、UML类图

Java设计模式之结构型-外观模式(UML类图+案例分析)_第1张图片

三、角色设计

角色 描述
外观角色 为多个子系统对外提供一个统一的接口,外观模式的核心,客户端可以调用这个接口实现对各个子系统的访问
子系统角色 实现系统的部分功能,客户可以通过外观角色访问它们,子系统对外界隐藏了内部的复杂性
客户端角色 通过一个外观角色访问各个子系统的功能,客户可以根据需要直接访问子系统类

四、案例分析

外观模式就像一个遥控器,它把许多电器的开关集中到了一个遥控器上,你只需要按遥控器上简单的按钮就可以控制电视、空调等电器开关。

1、电视、空调等电器就是不同的子系统。

2、遥控器是外观类,它将电视、空调的开关简单封装起来,提供了简单的接口(按钮)。

3、用户(客户端)只需要按遥控器的按钮,而不需要去操作每一个电器的开关。

4、如果需要替换一个新的电视,只要修改遥控器上的电视按钮对应代码,对客户端无影响。这样通过遥控器(外观类)把复杂的子系统简化和封装起来,用户就只需要操作简单的接口,大大降低了系统的复杂性。同时在修改子系统时,也只会影响外观类而不会影响到客户端。

总之,外观模式提供了一个简单入口来访问和使用复杂子系统,它对客户屏蔽了子系统组件,减少系统相互依赖,实现解耦。

假设现在有一个简单的例子:平日我们网上购物一般会分为4个步骤,挑选物品,添加购物车,填写收获信息和支付,下面我们就通过代码来实现上述功能。

定义一个网上购物的流程接口:

public interface PurchaseProcess {

    //挑选物品
    void pickGoods(String goodName);

    //添加到购物车
    void addCart(String goodName);

    //填写收货信息
    void addConsigneeInformation(String consigneeInformation);

    //支付
    void pay();


}

购物接口对应的实现类:

public class PurchaseProcessImpl implements PurchaseProcess {
    @Override
    public void pickGoods(String goodName) {
        System.out.println("挑选的商品:"+goodName);
    }

    @Override
    public void addCart(String goodName) {
        System.out.println("将《"+goodName+"》添加到购物车!");
    }

    @Override
    public void addConsigneeInformation(String consigneeInformation) {
        System.out.println("您填写的收货地址:"+consigneeInformation);
    }

    @Override
    public void pay() {
        System.out.println("支付完成...");
    }
}

提供一个统一的方法进行购物:

public class Shopping {

    private PurchaseProcessImpl purchaseProcess = new PurchaseProcessImpl();

    public void purchaseGoods(String goodName,String consigneeInformation) {
        purchaseProcess.pickGoods(goodName);
        purchaseProcess.addCart(goodName);
        purchaseProcess.addConsigneeInformation(consigneeInformation);
        purchaseProcess.pay();
    }
}

客户端:

public class Client{
    public static void main(String[] args) {
        Shopping shopping = new Shopping();
        shopping.purchaseGoods("华为Mate40 Pro","上海");
    }
}

运行结果如下:

Java设计模式之结构型-外观模式(UML类图+案例分析)_第2张图片

如果需要添加支付方式呢,我们还需要重新设计购买的步骤,具体的代码实现如下:

定义一个支付方式实现类: 

public class PayMode {
    public void payMode(String payMode){
        System.out.println("支付方式:"+payMode);
    }
}

改造购物方式方法中的代码,新增一个支付方式:

public class Shopping {

    private PurchaseProcessImpl purchaseProcess = new PurchaseProcessImpl();

    private PayMode mode = new PayMode();

    public void purchaseGoods(String goodName,String consigneeInformation,String payMode) {
        purchaseProcess.pickGoods(goodName);
        purchaseProcess.addCart(goodName);
        purchaseProcess.addConsigneeInformation(consigneeInformation);
        mode.payMode(payMode);
        purchaseProcess.pay();
    }
}

客户端:

public class Client{
    public static void main(String[] args) {
        Shopping shopping = new Shopping();
        shopping.purchaseGoods("华为Mate40 Pro","上海","支付宝");
    }
}

运行结果如下:

Java设计模式之结构型-外观模式(UML类图+案例分析)_第3张图片

五、总结

优点:

1、减少系统相互依赖:外观模式使得客户端和子系统的复杂关系放在外观类中,外界仅需面对一个简单的外观类,大大降低了客户与子系统间的耦合关系。

2、提高灵活性:通过引入外观类,可以在不影响其他子系统的情况下修改子系统。

3、更好的层次结构:外观模式可以更好地定义系统不同层次的功能

缺点:

1、不符合开闭原则。如果需要修改外观类,有可能需要修改所有客户端代码。

使用场景:

1、提供一个简单的接口以屏蔽子系统组件的复杂性。

2、在层次化结构中定义入口点。

符合的设计原则:

1 依赖倒转原则(Dependence Inversion Principle)

外观类与子系统之间形成了一种逆向的依赖关系,外观类依赖于抽象接口,而子系统则实现这些抽象接口,这个依赖关系是倒置的,降低了外观类与子系统的耦合度。

2 迪米特法则(Law of Demeter)

外观类与子系统之间遵循最小知识原则,外观类只与需要交互的子系统直接通信,而不关心子系统内部的实现细节,降低了耦合度。

简单来说,外观模式通过提供一个高层接口来封装细节,简化子系统使用,使子系统之间解耦,它提高了程序的灵活性和可维护性。 

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