zoukankan      html  css  js  c++  java
  • 外观模式

    1.外观模式是什么

    1.百度百科

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

    2.维基百科

    The facade pattern (also spelled façade) is a software design pattern commonly used with object-oriented programming. The name is an analogy to an architectural façade.
    A facade is an object that provides a simplified interface to a larger body of code, such as a class library. A facade can
    make a software library easier to use, understand, and test, since the facade has convenient methods for common tasks,
    make the library more readable, for the same reason,
    reduce dependencies of outside code on the inner workings of a library, since most code uses the facade, thus allowing more flexibility in developing the system,
    wrap a poorly designed collection of APIs with a single well-designed API.
    The Facade design pattern is often used when a system is very complex or difficult to understand because the system has a large number of interdependent classes or its source code is unavailable. This pattern hides the complexities of the larger system and provides a simpler interface to the client. It typically involves a single wrapper class that contains a set of members required by the client. These members access the system on behalf of the facade client and hide the implementation details.

    3.lz理解

    将一组接口通过更高一层的接口有序的组织起来。就像DAO ServiceImpl Service 的关系一样。
    多个DAO接口由ServiceImpl组织在一起通过Service提供给客户端调用。

    4.核心角色

    外观角色类(Facade) :客户端可以调用这个角色的方法。该角色知晓子系统的所有功能和责任。该角色会将客户端发送过来的请求委派到相应的子系统中,该角色一般没有实际的业务逻辑,只是一个委托类。

    子系统角色(SubsystemClass) :可以同时有1个或多个子系统。每个子系统都不是一个单独的类,而是一个类的集合。子系统并不知道Facade的存在,对于子系统而言,Facade只是一个客户端而已。
    下面是外观模式的通用代码

    2.外观模式解决了什么问题

    对外封装 减少系统的相互依赖。外部访问不会直接深入到子系统,而是通过Facade类,使得外部系统和子系统直接松耦合。

    减少依赖 提高了灵活性。依赖少了,灵活性自然高了。

    提高安全性 Facade决定了外部系统只能访问到哪些子系统的业务逻辑,其他的一概无法访问。

    3.外观模式用法

    做红烧肉举例子。想吃红烧肉,但是呢又不想自己做那么我们该怎么办呢。

    当然是去饭馆吃啦。饭店则需去各个市场购买材料。

    首先是子系统的角色,就是买材料的市场

    //调味品市场
    public interface SeasonedMarket {
    	//购买八角
    	void buyAnise();
    	//桂皮
    	void buyCinnamon();
    	//冰糖
    	void buysugar();
    }
    //屠宰场
    public interface SlaughterMarkt {
    
    	//购买猪肉
    	void buyPork();
    
    }
    //菜市场
    public interface VegetableMarket {
    	//买葱
    	void buyShallot();
    	//买姜
    	void buyGinger();
    	//买蒜
    	void buyGarlic();
    
    }
    
    

    子系统角色的实现类

    public class SeasonedMarketImpl implements SeasonedMarket {
    
    	@Override
    	public void buyAnise() {
    		System.out.println("购买八角");
    	}
    
    	@Override
    	public void buyCinnamon() {
    		System.out.println("购买桂皮");
    	}
    
    	@Override
    	public void buysugar() {
    		System.out.println("购买糖");
    	}
    
    }
    
    public class SlaughterMarktImpl implements SlaughterMarkt {
    
    	@Override
    	public void buyPork() {
    		System.out.println("购买猪肉");
    	}
    
    }
    
    public class VegetableMarketImpl implements VegetableMarket {
    
    	@Override
    	public void buyShallot() {
    		System.out.println("购买大葱");
    	}
    
    	@Override
    	public void buyGinger() {
    		System.out.println("购买生姜");
    	}
    
    	@Override
    	public void buyGarlic() {
    		System.out.println("购买大蒜");
    	}
    
    }
    

    外观角色 也就是饭店。饭馆这个角色其实不必抽象,这里抽象只是为了更高的封装。比如美食节大赛各个饭馆的红烧肉大比拼。

    //能做红烧肉的饭店
    public interface Restaurant {
    
    	void braisedPork();
    
    }
    

    饭店的实现,我们去饭店吃饭基本不必关心食材去哪里购买。都是由饭店自己决定。我们只要吃就好。

    public class ChineseRestaurant implements Restaurant {
    
    	private SeasonedMarket seasonedMarket;
    	private SlaughterMarkt slaughterMarkt;
    	private VegetableMarket vegetableMarket;
    
    	//饭馆自己选择购买市场
    	public ChineseRestaurant() {
    		this.seasonedMarket = new SeasonedMarketImpl();
    		this.slaughterMarkt = new SlaughterMarktImpl();
    		this.vegetableMarket = new VegetableMarketImpl();
    	}
      //制作饭
    	@Override
    	public void braisedPork() {
    		System.out.println("购买红烧肉材料");
    		seasonedMarket.buyAnise();
    		seasonedMarket.buyCinnamon();
    		seasonedMarket.buysugar();
    		slaughterMarkt.buyPork();
    		vegetableMarket.buyGarlic();
    		vegetableMarket.buyGinger();
    		vegetableMarket.buyShallot();
    		System.out.println("红烧肉制作中。。。");
    		System.out.println("红烧肉制作完成");
    	}
    }
    
    

    客户端,也就是食客。找到一家饭店然后吃红烧肉。其他的都不用关心、

    public class Customer {
    
    	public static void main(String[] args) {
    		//找到一家饭店
    		Restaurant cr = new ChineseRestaurant();
    		//吃红烧肉
    		cr.braisedPork();
    	}
    
    }
    

    4.外观模式的问题

    违背开闭原则 增加新的子系统可能需要修改外观类或客户端,违背了“开闭原则”。

    外观类膨胀 外观类接口膨胀。由于子系统的接口都有外观类统一暴露,使得外观类的API接口过多

    5.外观模式总结

    应用场景:

    1. 设计初期阶段,应该有意识的将不同层分离,层与层之间建立外观模式。
    2. 开发阶段,子系统越来越复杂,增加外观模式提供一个简单的调用接口。
    3. 维护一个大型遗留系统的时候,可能这个系统已经非常难以维护和扩展,但又包含非常重要的功能,为其开发一个外观类,以便新系统与其交互。

    外观模式是一个框架级别的设计模式。如我们常用的MVC都是使用外观模式。当我悬系完了外观模式后才恍然大悟。原来外观模式我们天天在用,只是不知道这种编码方式叫外观模式。其实现在所谓的微服务从整体上来说也是外观模式的一种实践方式。

  • 相关阅读:
    【BZOJ3670】【NOI2014】动物园(KMP算法)
    【BZOJ4372】烁烁的游戏(动态点分治)
    【BZOJ3730】震波(动态点分治)
    【BZOJ3924】幻想乡战略游戏(动态点分治)
    【BZOJ1095】捉迷藏(动态点分治)
    动态点分治
    【BZOJ2333】棘手的操作(左偏树,STL)
    【BZOJ4816】数字表格(莫比乌斯反演)
    【BZOJ3506】排序机械臂(Splay)
    【BZOJ2693】jzptab(莫比乌斯反演)
  • 原文地址:https://www.cnblogs.com/yanlong300/p/8398635.html
Copyright © 2011-2022 走看看