门面模式Facade
门面模式:统之间的接口、框架之间的衔接
(1)使用接口的情势来开发,不需要知道接口中内部方法的实现;
(2)门面模式就是为子系统对外提供的1组接口提供1个统1的界面,使得其他系统对该系统的访问都通过这个统1的界面来完成。
(3)当1个负载的系统需要对外提供接口时,就需要将对提供的接口统1封装在外观类里,供外系统使用。
门面模式原理图
门面模式原理图
不用门面设计模式的情况
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);
}
}
客户端会和几个类的联系程度较大;为使客户端程序尽可能的减少,我们把计算薪水的代码块抽取到1个类里:
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());
}
}
如果有多个计算薪水,就不合适了,所以可以再把计算薪水的类换成1个接口
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;
}
}
1个专门读取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)当你要为1个复杂子系统提供1个简单接口时。在上面已描写了缘由。
(2) 客户程序与抽象类的实现部份之间存在着很大的依赖性。引入 facade 将这个子系统与客户和其他的子系统分离,可以提高子系统的独立性和可移植性(上面也提到了)。
(3)当你需要构建1个层次结构的子系统时,使用 facade 模式定义子系统中每层的入口点。如果子系统之间是相互依赖的,你可让它们仅通过 facade 进行通讯,从而简化了它们之间的依赖关系。
优点:
(1)它对客户屏蔽子系统组件,因此减少了客户处理的对象的数目并使得子系统使用起来更加方便。
(2)它实现了子系统与客户之间的松耦合关系,而子系统内部的功能组件常常是紧耦合的。松耦合关系使得子系统的组件变化不会影响到它的客户。 Facade 模式有助于建立层次结构系统,也有助于对对象之间的依赖关系分层。 Facade 模式可以消除复杂的循环依赖关系。这1点在客户程序与子系统是分别实现的时候尤其重要。在大型软件系统中下降编译依赖性相当重要。在子系统类改变时,希望尽可能减少重编译工作以节省时间。用
Facade 可以下降编译依赖性,限制重要系统中较小的变化所需的重编译工作。 Facade 模式一样也有益于简化系统在不同平台之间的移植进程,由于编译1个子系统1般不需要编译所有其他的子系统。
(3) 如果利用需要,它其实不限制它们使用子系统类。因此你可让客户程序在系统易用性和通用性之间加以选择。