package wrapperFacadePatte;
/**
* 外观模式:
* 百度百科:
* ☆ 为子系统中的一组接口提供一个一致的界面,定义一个高层接口,这个接口使得这一子系统更加容易使用。
* 适用场景:
* (1) 设计初期阶段,应该有意识的将不同层分离,层与层之间建立外观模式。
* (2) 开发阶段,子系统越来越复杂,增加外观模式提供一个简单的调用接口。
* (3) 维护一个大型遗留系统的时候,可能这个系统已经非常难以维护和扩展,但又包含非常重要的功能,为其开发一个外观类,以便新系统与其交互。
*
* 优点:
* 1)对客户屏蔽子系统组件,减少了客户处理的对象数目并使得子系统使用起来更加容易。
* 通过引入外观模式,客户代码将变得很简单,与之关联的对象也很少。
2)实现了子系统与客户之间的松耦合关系,这使得子系统的组件变化不会影响到调用它的客户类,只需要调整外观类即可。
3)降低了大型软件系统中的编译依赖性,并简化了系统在不同平台之间的移植过程,
因为编译一个子系统一般不需要编译所有其他的子系统。一个子系统的修改对其他子系统没有任何影响,
而且子系统内部变化也不会影响到外观对象。
4)只是提供了一个访问子系统的统一入口,并不影响用户直接使用子系统类。

缺点:
1) 不能很好地限制客户使用子系统类,如果对客户访问子系统类做太多的限制则减少了可变性和灵活性。
2) 在不引入抽象外观类的情况下,增加新的子系统可能需要修改外观类或客户端的源代码,违背了“开放封闭原则”。


看不懂? 没关系 看代码就懂了!!
*
*@author LiMing E-mail:1151143484@qq.com
*@date 2017年6月15日 上午8:14:06
*/
public class WrapperFacadePatte {
public static void main(String[] args) {
Facade facade = new Facade();
//如果是一般的编写 这里需要new 三个对象 然后分别调用method方法 但是写了外观类之后 这里只需要调用外观类的方法就行了
//在这里客户端是不允许直接使用Original1 Original2 Original3 的 所以这也是缺点 不灵活
//而且增加、删除或更换与外观类交互的子系统类 必须修改外观类或客户端的源代码,这将违背开闭原则, 所以可以引入抽象外观类 对外观类进行升级
facade.Method();

//抽象外观类的正确打开方式 新增一个Original4 如果没有抽象外观的话 是需要修改Facade类的 但是现在不用 现在写一个NewFacade就行了
NewFacade facade2 = new NewFacade();
facade2.Method();

//其实最正确的打开方式是 通过xml 获取NewFacade 然后通过反射获取实例
NewFacade facade3;
try {
facade3 = (NewFacade) Class.forName("wrapperFacadePatte.NewFacade").newInstance();
facade3.Method();
} catch (InstantiationException | IllegalAccessException
| ClassNotFoundException e) {
e.printStackTrace();
}


/******,确保系统中有且仅有一个EncryptFacade类的实例,从而避免生成多个EncryptFacade对象,节约系统资源,提高程序性能。 单例模式********/
SimpleNewFacade facade4 = SimpleNewFacade.getInstance();
facade4.Method();

}

}

/*
* 这是功能类1 2 3
*/
class Original1{
public void Method(){
System.out.println("Original1 11的method");
}
}
class Original2{
public void Method(){
System.out.println("Original2 22的method");
}
}
class Original3{
public void Method(){
System.out.println("Original3 33的method");
}
}
/*
* 新增的类
*/
class Original4{
public void Method(){
System.out.println("Original4 44的method");
}
}

/*
* 这就是外观类 这个类刚开始没有 实现AbstractFacade 因为刚开始没有抽象外观类 如果在项目中刚开始应该设计抽象外观类 第一个实现应该要继承AbstractFacade的
*/
class Facade{
Original1 original1 = new Original1();
Original2 original2 = new Original2();
Original3 original3 = new Original3();
public void Method(){
original1.Method();
original2.Method();
original3.Method();
}
}

/*******************************************抽象外观类*********************************/

/*
* 抽象外观
*/
interface AbstractFacade{
public abstract void Method();
}
class NewFacade{
Original1 original1 = new Original1();
Original2 original2 = new Original2();
Original3 original3 = new Original3();
//新增的4 以前是没有的
Original4 original4 = new Original4();
public void Method(){
original1.Method();
original2.Method();
original3.Method();
original4.Method();
}
}

/*
* 在xml中配置具体的外观类对应的真实类 比如说facade 对应的是NewFacade 在使用的时候直接获取NewFacade 然后通过反射进行初始化
*
*
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key="facade" value="wrapperFacadePatte.NewFacade"/>
</appSettings>
</configuration> */






/**********************************单例抽象外观类*****************************************/
class SimpleNewFacade{
private static SimpleNewFacade instance = new SimpleNewFacade();
Original1 original1 ;
Original2 original2;
Original3 original3;
Original4 original4;
private SimpleNewFacade() {
original1 = new Original1();
original2 = new Original2();
original3 = new Original3();
original4 = new Original4();
}
public void Method(){
original1.Method();
original2.Method();
original3.Method();
original4.Method();
}
public static SimpleNewFacade getInstance() {
return instance;
}
}