Integrate functionality of known apis using facade patterns

General electric business platform is the integration of numerous subsystem converge to form a large shopping platform, in general, there are a lot of ready-made functions are not redevelopment, but going to butt joint of the existing various subsystems, these subsystems may involve integral system, payment system and the interface of logistics system calls. If all the interface calls are made by the front-end to send network requests to call the existing interface, on the one hand, it will increase the difficulty of the front-end developer, on the other hand, it will increase some network requests and affect the page performance. At this point, you can play the advantages of the facade mode. All existing interfaces are integrated into one class, and the back-end provides a unified interface for the front end to call, so that the front end developers do not need to care about the business relationship of each interface and only need to focus on the page interaction. We use code to simulate a business scenario where points are exchanged for gifts. First create the entity class GiftInfo for the gift.


public class GiftInfo {
    private String name;

    public GiftInfo(String name) {
        this.name = name;
    }

    public String getName(a) {
        returnname; }}Copy the code

Then write the business logic code of each subsystem and create the QualifyService class of integral system.


public class QualifyService {
    public boolean isAvailable(GiftInfo giftInfo){
        System.out.println("Check" + giftInfo.getName() + "Points qualification passed, inventory passed.");
        return true; }}Copy the code

Create the Payment system PaymentService class.


public class PaymentService {
    public boolean pay(GiftInfo pointsGift){
        // Subtract the integral
        System.out.println("Pay" + pointsGift.getName() + "Integral successful");
        return true; }}Copy the code

Create the ShippingService class for the logistics system.


public class ShippingService {

    / / delivery
    public String delivery(GiftInfo giftInfo){
        // Logistics system docking logic
        System.out.println(giftInfo.getName() + "Access to the logistics system");
        String shippingOrderNo = "666";
        returnshippingOrderNo; }}Copy the code

Next, create the GiftFacadeService class, open only an Exchange () method to exchange gifts, and integrate all the functions of the three subsystems inside the Exchange () method.


public class GiftFacadeService {
    private QualifyService qualifyService = new QualifyService();
    private PaymentService pointsPaymentService = new PaymentService();
    private ShippingService shippingService = new ShippingService();

    / / change
    public void exchange(GiftInfo giftInfo){
        if(qualifyService.isAvailable(giftInfo)){
            // Pass the qualification check
            if(pointsPaymentService.pay(giftInfo)){
                // If the credits are paid successfully
                String shippingOrderNo = shippingService.delivery(giftInfo);
                System.out.println("Logistics system order successfully, the order number is :"+shippingOrderNo); }}}}Copy the code

Finally, look at the client code.


public static void main(String[] args) {
        GiftInfo giftInfo = new GiftInfo("Spring 5 Core Principles");
        GiftFacadeService giftFacadeService = new GiftFacadeService();
        giftFacadeService.exchange(giftInfo);
}

Copy the code

The running result is shown in the figure below.

Through such a case comparison, I believe that we have a very deep impression on the facade model.

Application of facade mode in Spring source code

Take a look at the JdbcUtils class in the Spring JDBC module, which encapsulates all JDBC-related operations, as shown in the following code snippet.


public abstract class JdbcUtils {
    public static final int TYPE_UNKNOWN = -2147483648;
    private static final Log logger = LogFactory.getLog(JdbcUtils.class);

    public JdbcUtils(a) {}public static void closeConnection(Connection con) {
        if(con ! =null) {
            try {
                con.close();
            } catch (SQLException var2) {
                logger.debug("Could not close JDBC Connection", var2);
            } catch (Throwable var3) {
                logger.debug("Unexpected exception on closing JDBC Connection", var3); }}}public static void closeStatement(Statement stmt) {
        if(stmt ! =null) {
            try {
                stmt.close();
            } catch (SQLException var2) {
                logger.trace("Could not close JDBC Statement", var2);
            } catch (Throwable var3) {
                logger.trace("Unexpected exception on closing JDBC Statement", var3); }}}public static void closeResultSet(ResultSet rs) {
        if(rs ! =null) {
            try {
                rs.close();
            } catch (SQLException var2) {
                logger.trace("Could not close JDBC ResultSet", var2);
            } catch (Throwable var3) {
                logger.trace("Unexpected exception on closing JDBC ResultSet", var3); }}}... }Copy the code

For more, the structure is clear, as shown in the figure below.

3 Facade mode in MyBatis source code application

MyBatis Configuration class, which has a lot of new start method, source code as follows.


public MetaObject newMetaObject(Object object) {
        return MetaObject.forObject(object, this.objectFactory, this.objectWrapperFactory, this.reflectorFactory);
    }

public ParameterHandler newParameterHandler(MappedStatement mappedStatement, Object parameterObject, BoundSql boundSql) {
        ParameterHandler parameterHandler = 
                	mappedStatement.getLang().createParameterHandler(mappedStatement, 						parameterObject, boundSql);
        parameterHandler = (ParameterHandler)this.interceptorChain.pluginAll(parameterHandler);
        return parameterHandler;
    }

    public ResultSetHandler newResultSetHandler(Executor executor, MappedStatement mappedStatement, RowBounds rowBounds, ParameterHandler parameterHandler, ResultHandler resultHandler, BoundSql boundSql) {
        ResultSetHandler resultSetHandler = 
        new DefaultResultSetHandler(executor, mappedStatement, parameterHandler, resultHandler, boundSql, rowBounds);
        ResultSetHandler resultSetHandler = (ResultSetHandler)this.interceptorChain.pluginAll (resultSetHandler);
        return resultSetHandler;
    }

    public StatementHandler newStatementHandler(Executor executor, MappedStatement mappedStatement, Object parameterObject, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) {
        StatementHandler statementHandler = 
					new RoutingStatementHandler(executor, mappedStatement, parameterObject, 					rowBounds, resultHandler, boundSql);
        StatementHandler statementHandler = (StatementHandler)this.interceptorChain.pluginAll 						(statementHandler);
        return statementHandler;
    }

    public Executor newExecutor(Transaction transaction) {
        return this.newExecutor(transaction, this.defaultExecutorType);
}

Copy the code

These methods encapsulate key component operations in JDBC.

4 application of facade mode in Tomcat source code

In addition, the facade mode is also reflected in the Tomcat source code, which is also very interesting. Take the RequestFacade class as an example to see the source code.


public class RequestFacade implements HttpServletRequest {...@Override
    public String getContentType(a) {

        if (request == null) {
            throw new IllegalStateException(
                            sm.getString("requestFacade.nullRequest"));
        }

        return request.getContentType();
    }


    @Override
    public ServletInputStream getInputStream(a) throws IOException {

        if (request == null) {
            throw new IllegalStateException(
                            sm.getString("requestFacade.nullRequest"));
        }

        return request.getInputStream();
    }


    @Override
    public String getParameter(String name) {

        if (request == null) {
            throw new IllegalStateException(
                            sm.getString("requestFacade.nullRequest"));
        }

        if (Globals.IS_SECURITY_ENABLED){
            return AccessController.doPrivileged(
                new GetParameterPrivilegedAction(name));
        } else {
            returnrequest.getParameter(name); }}... }Copy the code

You can tell by the name that it uses facade mode. It encapsulates a lot of request operations and also incorporates a lot of content outside of servlet-API, making it very easy for users to use. Tomcat also wraps ResponseFacade and Standardssession Facade classes for Response and Session.

Are you surprised to learn that you’re in facade mode every day?

Pay attention to “Tom play architecture” reply to “design pattern” can obtain the complete source code.

Tom play architecture: 30 real cases of design patterns (attached source code), the challenge of annual salary 60W is not a dream

This article is “Tom play structure” original, reproduced please indicate the source. Technology is to share, I share my happiness! If this article is helpful to you, welcome to follow and like; If you have any suggestions can also leave a comment or private letter, your support is my motivation to adhere to the creation. Pay attention to “Tom bomb architecture” for more technical dry goods!