【Design Pattern】Just three minutes of experience, you will understand Facade and Mediator patterns as much as I do

Facade Facade Pattern

Simulation scene

There Clientis one, which needs to be settled in the city, and the household registration needs to be transferred. Now the relevant departments require Clientthe preparation of a series of materials.

Let's simplify the department, assuming that we only need to run 材料部门, 核验盖章部门and 制证发证部门three departments.

Now you need Clientto 材料部门get the materials first, then fill them out , and finally get the certificate 核验部门盖章with the covered materials , so that the business can be counted as complete when the set is completed in order.制证部门

code simulation

Materials Department

/**
 * 材料部门,给办证者提供必要的材料
 * @author 行百里者
 */
public class StuffDept {
    public void makeStuff() {
        //处理业务逻辑
        System.out.println("制作相关材料,并发给Client填写");
    }
}

Stamp Department

/**
 * 检查核验部门,核验通过才给盖章
 * @author 行百里者
 */
public class CheckDept {
    public void checkStuff() {
        //处理业务逻辑
        System.out.println("核查材料的准确性,核查通过才给盖章");
    }
}

Certification Department

/**
 * 发证部门
 * @author 行百里者
 */
public class IssueDept {
    public void issueCert() {
        //处理业务逻辑
        System.out.println("发证部门检验材料是否盖章,然后制证发证");
    }
}

ClientProcessing scenarios that require certification :

public class Client {
    public static void main(String[] args) {
        //一定要按照这个顺序去办证,否则拿不到证
        StuffDept sd = new StuffDept();
        sd.makeStuff();
        CheckDept cd = new CheckDept();
        cd.checkStuff();
        IssueDept id = new IssueDept();
        id.issueCert();
    }
}

In fact, in real life, we may run far more than these three departments. If we shuttle back and Clientforth between N departments, the efficiency of work is not very garbage!

Solve this difficult problem with facade mode

Fortunately, many places now provide online channels to handle some business. ClientYou only need to run once, and you Clientonly need to deal with 网上通道- .NetApp

/**
 * “中国式办证”所需的“门面”部门,负责统一处理各部门的事情,
 * Client只需要调“门面”的doItJustOnce方法即可
 * @author 行百里者
 */
public class NetApp {
    private StuffDept stuffDept = new StuffDept();
    private CheckDept checkDept = new CheckDept();
    private IssueDept issueDept = new IssueDept();
    
    public void doItJustOnce() {
        stuffDept.makeStuff();
        checkDept.checkStuff();
        issueDept.issueCert();
    }
}

Clientcall up

public class Client {
    public static void main(String[] args) {
        NetApp facade = new NetApp();
        facade.doItJustOnce();
    }
}

For Client, isn't it refreshing!

Isn't this just another layer of encapsulation? That's right, this is the facade pattern , which solves the Clienttedious problem of making calls to various departments and calling them in the specified order.

Deja Vu Facade

Alipay payment API

The access party only needs to call, no matter how it is implemented internally, it only needs to exchange data according to its open API.

Alipay's open API can be understood as an application of the Facade model.

logging framework SLF4J

The SLF4J logging framework adopts the facade design pattern, which hides the complexity of the system from the outside, and provides a unified interface to the externally called client or program.

private static final Logger LOGGER = LoggerFactory.getLogger(Provider.class);

public String doSomething() {
    LOGGER.info("service name:{}", serviceName);
}

一句话就可以直接输出日志信息,而不管其内部是Log4j实现的还是logback实现的,用起来就是简单明了。

JDBC数据库操作

数据库JDBC的操作,例如:

@Component
public class DBUtil {

    private static String URL;

    private static String DRIVER;

    private static String USERNAME;

    private static String PASSWORD;

    private static Connection connection = null;

    private static final Logger LOGGER = LoggerFactory.getLogger(DBUtil.class);


    /**
     * 获取JDBC连接
     *
     */
    public static Connection getConnection() {
        try {
            //加载驱动程序:它通过反射创建一个driver对象。
            Class.forName(DRIVER);

            //获得数据连接对象。
            connection = DriverManager.getConnection(URL, USERNAME, PASSWORD);
            return connection;
        } catch (Exception e) {
            e.printStackTrace();
            LOGGER.error("获取JDBC连接异常, {}", e.getMessage());
        }
        return null;
    }

    @Value("${db.dburl}")
    public void setURL(String dburl) {
        URL = dburl;
    }

    @Value("${db.dbdriver}")
    public void setDRIVER(String dbdriver) {
        DRIVER = dbdriver;
    }

    @Value("${db.dbusername}")
    public void setUSERNAME(String dbusername) {
        USERNAME = dbusername;
    }

    @Value("${db.dbpassword}")
    public void setPASSWORD(String dbpassword) {
        PASSWORD = dbpassword;
    }
}

获取数据库连接的时候,只需要传入driver的驱动类名称即可,如果以后我们更换Class.forName中的 driver 非常方便,比如从MySQL数据库换到Oracle数据库,只要更换facade中的driver就可以。

Mediator 调停者模式

有的地方把它叫做中介者模式,名字不重要!!!

张三的烦恼

张三的老婆发现他最近有点异常,怀疑张三和他前女友藕断丝连,于是张老婆去找张三他妈评理,但是俩人很快吵起来了,此时小姑子出现了,又是一顿吵,是互相吵的那种。

张三恼了,和其他三人也吵起来了。

他很想结束现状,但是他已无能为力,甚至自己也陷入其中,要是居委会大妈在就好了!!!

居委会大妈的职责就是协调他们内部的事情,有什么事直接跟我说,保证把你们的事情都解决!!!

居委会大妈就是调停者,中介者。

模拟现场

调停者

加入了一个中介者作为四个模块的交流核心,每个模块之间不再相互交流,要交流就通过中介者居委会大妈进行。每个模块只负责自己的业务逻辑,不属于自己的则丢给中介者来处理,简化了各模块之间的耦合关系。

消息中间件

卧槽,中介处理各个模块的需求,而且各个模块之间不需要通信,消息中间件不就是这种模式吗?

对!MQ就可以理解为Mediator模式

调停者模式的优缺点

  • 优点

中介者模式的优点就是减少类间的依赖,把原有的一对多的依赖变成了一对一的依赖,减少了依赖,当然同时也降低了类间的耦合。

  • 缺点

中介者模式的缺点就是中介者会膨胀得很大,而且逻辑复杂,,中介者的逻辑就越复杂。

好了,你已经会门面模式调停者模式了。下一个!!!

Guess you like

Origin juejin.im/post/7118574813551001631