门面模式Facade
门面模式:统之间的接口、框架之间的衔接
(1)使用接口的形式来开发,不需要知道接口中内部方法的实现;
(2)门面模式就是为子系统对外提供的一组接口提供一个统一的界面,使得其他系统对该系统的访问都通过这个统一的界面来完成。
(3)当一个负载的系统需要对外提供接口时,就需要将对提供的接口统一封装在外观类里,供外系统使用。
门面模式原理图
门面模式原理图
不用门面设计模式的情况
Holiday.java
public class Holiday { public double getHoliday(String empno) { return 2; } }
Salary.java
public class Salary { public double getSalary(String empno){ return 2000; } }
Tax.java
public class Tax { public double getTax(String empno) { return 0; } }
客户端Client.java
public class Client { public static void main(String[] args) { Salary salary = new Salary(); Holiday holiday = new Holiday(); Tax tax = new Tax(); double money = salary.getSalary("100222") * holiday.getHoliday("100222")/30 - tax.getTax("100222"); System.out.println(money); } }
客户端会和几个类的联系程度较大;为使客户端程序尽量的减少,我们把计算薪水的代码块抽取到一个类里:
SalaryComputer.java
public class SalaryCoumputer { public double doSalary() { Salary salary = new Salary(); Holiday holiday = new Holiday(); Tax tax = new Tax(); double money = salary.getSalary("100222") * holiday.getHoliday("100222")/30 - tax.getTax("100222"); return money; } }
客户端程序变为:
public class Client { public static void main(String[] args) { SalaryCoumputer salaryCoumputer = new SalaryCoumputer(); System.out.println(salaryCoumputer.doSalary()); } }
如果有多个计算薪水,就不适合了,所以可以再把计算薪水的类换成一个接口
Computer.java
public interface Computer { public double doSalary(String empno); }
SalaryComputer.java
public class SalaryCoumputer implements Computer{ public double doSalary(String empno) { Salary salary = new Salary(); Holiday holiday = new Holiday(); Tax tax = new Tax(); double money = salary.getSalary("100222") * holiday.getHoliday("100222")/30 - tax.getTax("100222"); return money; } }
一个专门读取properties属性文件的类
public class PropertiesUtil { static Properties p = new Properties(); public static Object getInstance() { InputStream in = null; Object obj = null; try { in = PropertiesUtil.class.getClassLoader().getResourceAsStream("class.properties"); p.load(in); } catch (IOException e) { e.printStackTrace(); } finally{ try { in.close(); } catch (IOException e) { e.printStackTrace(); } } try { obj = (Object) Class.forName((String) PropertiesUtil.getValue("class")).newInstance(); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } return obj; } public static Object getValue(String key) { return p.get(key); } }
Client.java
public class Client { public static void main(String[] args) { Computer computer = (Computer)PropertiesUtil.getInstance(); System.out.println(computer.doSalary("100222")); } }
应用如:JDBC的封装springJDBC的封装。
使用环境和优点
《设计模式》给出了门面模式的使用环境:
(1)当你要为一个复杂子系统提供一个简单接口时。在上面已经描述了原因。
(2) 客户程序与抽象类的实现部分之间存在着很大的依赖性。引入 facade 将这个子系统与客户以及其他的子系统分离,可以提高子系统的独立性和可移植性(上面也提到了)。
(3)当你需要构建一个层次结构的子系统时,使用 facade 模式定义子系统中每层的入口点。如果子系统之间是相互依赖的,你可以让它们仅通过 facade 进行通讯,从而简化了它们之间的依赖关系。
优点:
(1)它对客户屏蔽子系统组件,因而减少了客户处理的对象的数目并使得子系统使用起来更加方便。
(2)它实现了子系统与客户之间的松耦合关系,而子系统内部的功能组件往往是紧耦合的。松耦合关系使得子系统的组件变化不会影响到它的客户。 Facade 模式有助于建立层次结构系统,也有助于对对象之间的依赖关系分层。 Facade 模式可以消除复杂的循环依赖关系。这一点在客户程序与子系统是分别实现的时候尤为重要。在大型软件系统中降低编译依赖性至关重要。在子系统类改变时,希望尽量减少重编译工作以节省时间。用
Facade 可以降低编译依赖性,限制重要系统中较小的变化所需的重编译工作。 Facade 模式同样也有利于简化系统在不同平台之间的移植过程,因为编译一个子系统一般不需要编译所有其他的子系统。
(3) 如果应用需要,它并不限制它们使用子系统类。因此你可以让客户程序在系统易用性和通用性之间加以选择。
原文地址:http://blog.csdn.net/dream_angel_z/article/details/45398699