banner
jzman

jzman

Coding、思考、自觉。
github

Appearance Design Pattern

PS: Input drives output. If you want to continue outputting, you have to continue inputting. The persistence of everyday actions may seem small, but what if you persist for a year or even longer? The result may not necessarily be beautiful, but the process will definitely be fulfilling.

Today, let's review the design patterns in software engineering, specifically the Facade design pattern. When talking about the Facade design pattern, we cannot ignore one of the six principles of design patterns, which is the Law of Demeter. This article will introduce the Facade design pattern from the following aspects:

  1. The Law of Demeter
  2. Understanding the Facade design pattern
  3. Implementing the Facade design pattern

The Law of Demeter#

In software development, it is common to encounter classes that have increasingly close relationships and high coupling. This means that when one class changes, it can also affect other classes. The Law of Demeter is one of the six principles of design patterns that is used to regulate this phenomenon. So, what is the Law of Demeter?

The Law of Demeter, also known as the Least Knowledge Principle (LKP), states that an object should have the least knowledge about other objects.

There is a simpler definition of the Law of Demeter: only communicate with direct friends. Let me explain what direct friends are. If two objects have a coupling relationship, we say that they are friends. Coupling relationships can be dependencies, compositions, aggregations, etc. We call the classes that appear as member variables, method parameters, and method return values direct friends. Classes that appear in local variables are not direct friends, which means that unfamiliar classes should not appear in local variables.

Understanding the Facade Design Pattern#

The Facade design pattern is already being used in software development, but it is often used subconsciously without explicitly recognizing it as the Facade design pattern. For example, to facilitate calling certain functions, they are encapsulated and provided by a manager class. Most utility classes should use the Facade design pattern.

In essence, the Facade design pattern is about encapsulating widely used functions to avoid frequent coupling with other objects. By encapsulating and unifying the complexity of a subsystem, it provides a single entry point for other modules to call. This is the core of the Facade design pattern.

Implementing the Facade Design Pattern#

Scenario: In a tea house, customers A, B, C, etc. all want to brew and drink tea. Each customer needs to go through the following steps to brew a good cup of tea:

  1. Prepare the tea set
  2. Prepare the water
  3. Brew the tea

Each customer has direct contact with tea sets, tea leaves, boiling water, etc. This clearly violates the Law of Demeter. We can use the Facade design pattern to encapsulate the tea brewing process, which is like having a waiter in the tea house. Each time a customer wants to drink tea, they simply tell the waiter what kind of tea they want. The customer doesn't need to know the details of the tea brewing process, as long as they can drink the tea they want. Let's implement the Facade design pattern with this simple example. The tea brewing process is as follows:

/**
 * Prepare the tea set
 * Created by jzman
 * Powered by 2019/5/6.
 */
interface IPrepareTeaSet {
    void prepareTeaSet();
}

class PrepareTeaSet implements IPrepareTeaSet {
    @Override
    public void prepareTeaSet() {
        System.out.println("Preparing the tea set...");
    }
}

/**
 * Prepare the water
 * Created by jzman
 * Powered by 2019/5/6.
 */
interface IPrepareWater {
    void prepareWater();
}

class PrepareWater implements IPrepareWater {
    @Override
    public void prepareWater() {
        System.out.println("Preparing the water...");
    }
}

/**
 * Brew the tea
 * Created by jzman
 * Powered by 2019/5/6.
 */
interface IBrewMethod {
    void brewMethod(String tea);
}

class BrewMethod implements IBrewMethod {

    @Override
    public void brewMethod(String tea) {
        System.out.println("Brewing the tea: " + tea);
    }
}

We will encapsulate the tea brewing service and provide it as a unified service. Here is the implementation:

/**
 * Tea house tea brewing service
 * Created by jzman
 * Powered by 2019/5/6.
 */
class TeaHouse {
    // Unified tea brewing service
    public static void drinkTea(String tea){
        // Prepare the tea set
        new PrepareTeaSet().prepareTeaSet();
        // Prepare the water
        new PrepareWater().prepareWater();
        // Brew the tea
        new BrewMethod().brewMethod(tea);
    }
}

Finally, customers can order the tea they want. Here is an example:

/**
 * Test
 * Created by jzman
 * Powered by 2019/5/6.
 */
class FacadeMain {
    public static void main(String[] args) {
        // Customer A
        TeaHouse.drinkTea("Black tea");
        // Customer B
        TeaHouse.drinkTea("Oolong tea");
    }
}

The execution log is as follows:

Preparing the tea set...
Preparing the water...
Brewing the tea: Black tea

Preparing the tea set...
Preparing the water...
Brewing the tea: Oolong tea

That's all for learning about the Facade design pattern. Although we may write code like this in our daily business development, we may not be aware of the Law of Demeter and the Facade design pattern subconsciously. By introducing these concepts, we can practice these rules subconsciously and continuously improve our coding abilities.

Loading...
Ownership of this post data is guaranteed by blockchain and smart contracts to the creator alone.