Typescript 门面模式

如果下面的代码你能轻易阅读,那么你已经熟悉门面模式,可以接着学习其他的设计模式。

 
facade

桥接模式:Facade(外观)模式为子系统中的各类(或结构与方法)提供一个简明一致的界面,隐藏子系统的复杂性,使子系统更加容易使用。它是为子系统中的一组接口所提供的一个一致的界面。

实际场景

进入医院之后我们会直接去前台挂号,然后前台人员帮我们联系医生,带我们去医生那里,医生看完后带我们去取药。进入饭店的时候我们也会找前台,然后前台帮我们拿餐号,帮我们准备用餐地点,点好餐后帮我们通知厨房,帮我们上餐。银行/学校....
当进入到比较大的场所时,我们似乎无处不见前台的身影。前台可以帮我们轻松的完成我们在各个地点需要完成的各种流程。
在系统中,当我们的系统比较大,子职能组件比较多的时候,为了方便自己和他人的调用。我们需要把一系列流程封装起来作为 ‘门面’ 函数。这也就是我们今天要讲到的门面模式。

门面模式的结构

  • 门面类
  • 多个子系统类

门面模式的例子

我们以一次医院之旅作为例子。

  • 门面类(医院的前台)
    前台会带领我们按照流程依次访问医院的子系统。方便我们使用。
/* facade.ts */
import Cashier from './cashier';
import DoctorOffice from './doctor-office';
import InternalMedicine from './internal-medicine';
import Pharmacy from './pharmacy';

export default class HospitalFacade {
    public static seeAStomachProblem(person, cases, money) {
        // InternalMedicine(子系统: 内科-拍胃镜)
        const isDepartmentBusy = InternalMedicine.instance.isDepartmentBusy();
        InternalMedicine.instance.doGastroscope(person);
        // DoctorOffice(子系统: 医生办公室-看医生)
        const isDoctorBusy = DoctorOffice.instance.isDoctorBusy();
        const prescription = DoctorOffice.instance.seeAStomachProblem(person, cases);
        // Pharmacy(子系统: 药房-取药)
        const medicine = Pharmacy.instance.takeMedicine(prescription);
        // Cashier(子系统: 收费处-收费)
        Cashier.instance.payTheBill(money);
    }
}
  • 子系统
    每一个子系统都是独立的,在子系统中不区分访问的人是病人还是前台
/* internal-medicine.ts */
export default class InternalMedicine {
    private static _instance: InternalMedicine;
    private isBusy: boolean;

    public static get instance() {
        if (!this._instance) {
            this._instance = new InternalMedicine();
        }
        return this._instance;
    }

    public isDepartmentBusy() {
        return this.isBusy;
    }

    public doGastroscope (person) {
        console.log('do gastroscope');
        return person
    }
}
/* docker-office.ts */
export default class DoctorOffice {
    private static _instance: DoctorOffice;
    private isBusy: boolean;

    public static get instance() {
        if (!this._instance) {
            this._instance = new DoctorOffice();
        }
        return this._instance;
    }

    public isDoctorBusy() {
        return this.isBusy;
    }

    public async seeAStomachProblem(person, cases) {
        return new Promise((resolve, reject) => {
            this.isBusy = true;
            console.log('check the condition');
            console.log('write report to cases', cases);
            console.log('list the prescription');
            this.isBusy = false;
            resolve('prescription');
        });
    }
}
/* pharmacy.ts */
export default class Pharmacy {
    private static _instance: Pharmacy;

    public static get instance() {
        if (!this._instance) {
            this._instance = new Pharmacy();
        }
        return this._instance;
    }

    public takeMedicine(prescription) {
        console.log('take the medicine in prescription');
        return 'medicine';
    }
}
/* cashier.ts */
export default class Cashier {
    private static _instance: Cashier;

    public static get instance() {
        if (!this._instance) {
            this._instance = new Cashier();
        }
        return this._instance;
    }

    public payTheBill (money) {
        return 'success'
    }
}

门面模式的利弊

利:隐藏了子系统内部的复杂性,可以通过门面轻松的调用。
弊:门面模式本身没有什么问题,但也不应该滥用。如果子系统不复杂,或者一个流程只需要访问一个子系统,没有必要过度设计。



作者:我不叫奇奇
链接:https://www.jianshu.com/p/9d5d14f89dc8
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
原文地址:https://www.cnblogs.com/wodehao0808/p/14103728.html