Facade Pattern

Facade pattern:外观模式(门面模式)

  1. The definition of facade pattern.
  2. How to use?
  3. Advantages and disadvantages.

Definition:隐藏子系统的复杂性,并向客户端提供了一个可以访问系统的接口。
外部与子系统的通信必须通过一个统一的门面对象进行。既提供了一个高层次的接口,使得子系统更容易使用。
这个对象知晓一个或多个子系统的功能和责任,在正常情况下,该对象会将所有从客户端发来的请求委派到相应的子系统。

Facade在客户端与子系统的关系

现在有一个需求,画不同的形状。
1.我们创建一个画图的接口

public interface Shape{
    void draw();
}

2.实现接口的实体类

public class Rectangle implements Shape{
    public void draw(){
        System.out.println("Rectangle:draw()");
    }
}
public class Square implements Shape{
    public void draw(){
        System.out.println("Square:draw()");
    }
}
public class Circle implements Shape{
    public void draw(){
        System.out.println("Circle:draw()");
    }
}

3.画出各种类型的形状

Public class Client{
    public static void main(String[] args){
        Rectangle rectangle = new Rectangle();
        Square square = new Square();
        Circle circle = new Circle();

        rectangle.draw();
        square.draw();
        circle.draw();
    }
}

外界访问直接深入到子系统内部,相互之间是一种强耦合的关系,你死我就死,你活我才能活。
而门面模式所有的依赖都是对门面对象的依赖,与子系统无关。

外观模式:
创建一个外观类,这个类知晓子系统的所有功能和责任,它自己并没有实际的业务逻辑,只是一个委托类。

public class ShapeMaker { 
     private Shape circle; 
     private Shape rectangle;
     private Shape square; 
     public ShapeMaker() { 
           circle = new Circle(); 
           rectangle = new Rectangle(); 
           square = new Square();
     } 
     public void drawCircle(){
           circle.draw(); 
     } 
     public void drawRectangle(){ 
           rectangle.draw();
     } 
     public void drawSquare(){
           square.draw(); 
     }
}

然后客户端在与外观类交互。

public class FacadePatternDemo {
      public static void main(String[] args) { 
            ShapeMaker shapeMaker = new ShapeMaker(); 

            shapeMaker.drawCircle();
            shapeMaker.drawRectangle(); 
            shapeMaker.drawSquare(); 
      } 
}

客户端不需要知道系统内部的复杂联系,整个系统只需要提供一个”接待员”即可。
这个例子可能不能很好的描述facade。我们来看下一个。

比如我们现实中写信,首先我们写信的内容,然后写地址和邮编,接着把信装进信封中,最后要投递在信箱中。这4个步骤,缺一不可,而且顺序不能颠倒,否则就会失败。

普通写法
1.写信的接口

public interface ILetterProcess{
    public void writeContext(String context);
    public void fillEnvelope(String address,String zipCode);
    public void letterInotoEnvelope();
    public void sendLetter();
}

2.接口的实现

public class LetterProcessImpl implements ILetterProcess{
     public void writeContext(String context){
            System.out.println(“填写信的内容…” + context);
     }
     public void fillEnvelope(String address,String zipCode){
            System.out.println(“填写收件人地址及邮编…” + address + "&&" + zupCode);
     }
     public void letterInotoEnvelope(){
            System.out.println(“把信放到信封中…”);
     }
     public void sendLetter(){
            System.out.println(“邮递信件…” );
     }
}

3.场景类

public class Client{
    public static void main(){
        ILetterProcess letterProcess = new LetterProcessImpl();
        letterProcess.writeContext("Hello,It’s me,do you know who I am?I’m your old lover.I’d like to …");
        letterProcess.fillEnvelope("Happy Road NO.666,God Province.Heaven","888");
        letterProcess.letterInotoEnvelope();
        letterProcess.sendLetter();
    }
}

运行结果:
填写信的内容… Hello,It’s me,do you know who I am?I’m your old lover.I’d like to …
填写收件人的地址及姓名… Happy Road NO.666,God Province,Heaven&&888
把信放到信封中…
邮递信件…

普通的写法与高内聚的要求相差甚远,更不用说迪米特法则、接口隔离原则了。它根本没有完成一个类所具有的单一职责。
如果信件多了就非常麻烦,每封信都要运转一遍。

外观模式:

public class ModenPostOffice{
    private ILetterProcess letterProcess = new ILetterProcess();
    public void sendLetter(String context,String address,String zipCode){
        letterProcess.writeContext(context);
        letterProcess.fillEvenlope(address,zipCode);
        letterProcess.letterInotoEnvelope();
        letterProcess.sendLetter();
    }
}

ModenPostOffice提供了一种新型服务,我们只要把信的内容和地址给他们,他们就会把信写好,封好,并发送出去。客户减少了很多工作。

我们来写门面模式下的场景类

public class Client{
    public static void main(String[] args){
        ModenPostOffice helloPostOffice = new ModenPostOffice();
        String address = "Happy Road NO.666,God Province,Heaven";
        String zipCode = "888";
        String context = "Hello,It’s me,do you know who I am?I’m your old lover.I’d like to …";
        helloPostOffice.sendLetter(context,address,zipCode);
    }
}

运行结果是相同的,我们只需要与ModenPostOffice交互就成了,写信和写地址都可以不管,只需要将信的内容和地址提交过去就行了,邮局保证会按照我们指定的地址把指定的内容发送出去。

现在我们有一个需求,在一个非常时期,寄望BJ的邮件必须进行检查。
增加一个Police类

public class Police{
    public void checkLetter(ILetterProcess letterProcess){
        System.out.println(letterProcess + "信件已经检查过了");
    }
}

对ModenPostOffice的扩展 即现代化的邮局

public class ModenPostOffice{
        private ILetterProcess letterProcess = new LetterProcessImpl();
        private Police letterPolice = new Police();
        //写信,封装,投递,一体化
        public void sendLetter(String context,String address){
                //帮你写信
                letterProcess.writeContext(context);
                //写好信封
                letterProcess.fillEnvelope(address);
                //检查信件
                letterPolice.checkLetter(letterProcess);
                //把信放在信封中
                letterPolice.letterInotoEnvelope();
                //邮递信件
                letterProcess,sendLetter();
        }
}

只是增加了一个letterPolice变量的声明以及一个方法的调用,增加了一个检查信件,对客户来说是透明的,他根本看不到有人在检查他的邮件,他也不用了解,反正现代化的邮件系统都帮他做了。
场景类还是完全相同,但是运行结果稍微不同。
高层模块没有任何的改动,但是信件却已经被检查过了。
这真是我们设计所需要的模式,不改变子系统对外暴露的接口、方法,只改变内部的处理逻辑,其他兄弟模块的调用产生了不同的结果,确实是一个非常棒的结果。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1. Composite Pattern:将对象组合成树形结构来表示“部分-整体”的层次结构,使得用户对单个对象和组合对象的使用具有一致性。常用于处理树形结构中的问题。 2. Decorator Pattern:动态地给对象添加一些额外的职责。可以通过包装一个装饰类来实现对原有类的功能扩展,而不需要修改原有类的代码。常用于需要在运行时动态地添加或删除对象的功能。 3. Strategy Pattern:定义一系列算法,将它们一个个封装起来,并且使它们可以相互替换。使得算法可以独立于使用它的客户端而变化。常用于需要在运行时动态地选择算法的情况。 4. Template Pattern:定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。使得子类可以不改变一个算法的结构即可重新定义该算法的某些特定步骤。常用于算法的框架已经确定,但某些步骤需要由子类来实现的情况。 5. Factory Pattern:定义一个用于创建对象的接口,让子类决定实例化哪一个类。使得一个类的实例化延迟到其子类。常用于需要根据不同的条件创建不同的对象的情况。 6. Observer Pattern:定义了对象之间的一对多依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并自动更新。常用于需要实现对象之间的消息传递或者事件触发机制的情况。 7. Builder Pattern:将一个复杂对象的构造过程分解为多个简单的对象构造过程,使得同样的构造过程可以创建不同的表示。常用于需要创建复杂对象的情况。 8. Facade Pattern:为子系统中的一组接口提供一个统一的接口,使得子系统更加容易使用。常用于需要简化复杂系统使用的情况。 9. Adapter Pattern:将一个类的接口转换成客户端希望的另一个接口,使得原本由于接口不兼容而不能一起工作的类可以在一起工作。常用于需要将旧接口转换成新接口的情况。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值