迪米特法则(LoD):如果两个类不必须彼此直接通信,那么这两个类就不应该发生直接的相互作用,如果一个类需要调用另一个类的某一个方法的话,可以通过第三者转发这个调用。
外观模式(Facade):为子系统中的一组接口提供一个一致的界面,此模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。
外观模式的适用场景:
- 在设计初期阶段,应该有意识的将不同的两个层分离,比如经典的三层架构,就需要考虑在数据访问层和业务逻辑层和表示层的层与层之间建立外观Facade,这样可以为复杂的子系统提供一个简单的接口,使得耦合性大大降低。
- 在开发阶段,子系统往往因为不断地重构演化而变得越来越复杂,大多数的模式使用时也会产生很多很小的类,这本是好事,但也给外部调用它们的用户程序带来了使用上的困难,增加Facade可以提供一个简单的接口,减少它们之间的依赖。
- 在维护一个遗留的大型系统时,可能这个系统已经非常难以维护和扩展了,但因为它包含非常重要的功能,新的需求必须依赖于它,此时使用外观模式Facade也是非常合适的,可以为新系统开发一个外观Facade类,来提供设计粗糙或高度复杂的遗留代码的比较清晰简单的接口,让新系统与Facade对象交互,Facade与遗留代码交互所有复杂的工作。
由购买股票与基金的情景进行模拟
客户端直接与子系统交互:
package chapter12;
public interface Financial {
public void sell();
public void buy();
}
package chapter12;
public class Stock1 implements Financial {
@Override
public void sell() {
System.out.println("股票1卖出");
}
@Override
public void buy() {
System.out.println("股票1买入");
}
}
package chapter12;
public class Stock2 implements Financial{
@Override
public void sell() {
System.out.println("股票2卖出");
}
@Override
public void buy() {
System.out.println("股票2买入");
}
}
package chapter12;
public class Stock3 implements Financial {
@Override
public void sell() {
System.out.println("股票3卖出");
}
@Override
public void buy() {
System.out.println("股票3买入");
}
}
package chapter12;
public class NationalDebt1 implements Financial {
@Override
public void sell() {
System.out.println("国债1卖出");
}
@Override
public void buy() {
System.out.println("国债1买入");
}
}
package chapter12;
public class Realty1 implements Financial {
@Override
public void sell() {
System.out.println("房地产1卖出");
}
@Override
public void buy() {
System.out.println("房地产1买入");
}
}
package chapter12;
public class Terminal1 {
public static void main(String[] args) {
Stock1 s1 = new Stock1();
Stock2 s2 = new Stock2();
Stock3 s3 = new Stock3();
NationalDebt1 nd1 = new NationalDebt1();
Realty1 ry1 = new Realty1();
s1.buy();
s2.buy();
s3.buy();
nd1.buy();
ry1.buy();
s1.sell();
s2.sell();
s3.sell();
nd1.sell();
ry1.sell();
}
}
增加Facade类,客户端通过Facade类与子系统交互,复用上面的股票类:
package chapter12;
public class Fund1 {
public Stock1 s1;
public Stock2 s2;
public Stock3 s3;
public Fund1() {
this.s1 = new Stock1();
this.s2 = new Stock2();
this.s3 = new Stock3();
}
public void buyFund1() {
System.out.println("买入基金1,买入了以下股票:");
s1.buy();
s2.buy();
s3.buy();
}
public void sellFund1() {
System.out.println("卖出基金1,卖出了以下股票:");
s1.sell();
s2.sell();
s3.sell();
}
}
package chapter12;
public class Terminal2 {
public static void main(String[] args) {
Fund1 f1 = new Fund1();
f1.buyFund1();
f1.sellFund1();
}
}