[0] [七大原则] ( 3 ) 迪米特原则(最少知识原则) demeter

总结

  • 迪米特原则的目的?
    降低class之间的耦合性,
    提高模块的独立性,
    减少A类对B类的依赖.


  • 要点1
    只和直接朋友通信,
    不要和陌生人讲话.



  • 要点2
    减少对朋友的了解
    (减少暴露的方法)



  • 典型的反面例子
    objectA.getObjB().doSomething();
    objectA.getObjB().getObjC().doSomething();


  • 如何理解 "朋友" ?
    依赖/关联/组合/聚合


  • 哪些是直接的朋友?
    field
    method参数
    方法返回值的class


  • 哪些不是直接的朋友?
    局部变量


  • 陌生的类不要以局部变量的方式出现在类的内部,
    如果A类需要调用B类的某个method,
    最好通过第三者转发这个调用.


  • 用哪些模式实现迪米特原则?
    门面模式
    中介模式


  • 缺点
    过分的使用迪米特原则,
    会产生大量这样的中介和传递类,
    导致系统复杂度变大.




JAVA例子一

参考:
https://youtu.be/I4pua5eZvQU?si=C5H8E9zDjF6AZRXH


重构前

image


重构后

image




JAVA例子二

参考:
https://cloud.tencent.com/developer/article/1836752


重构前

/**
 * 咖啡机抽象接口
 */
public interface ICoffeeMachine {
    void addCoffeeBean();  // 加咖啡豆
    void addWater();       // 加水
    void makeCoffee();     // 制作咖啡
}

/**
 * 咖啡机实现类
 */
public class CoffeeMachine implements ICoffeeMachine{
    public void addCoffeeBean() {
        System.out.println("放咖啡豆");
    }
    public void addWater() {
        System.out.println("加水");
    }
    public void makeCoffee() {
        System.out.println("制作咖啡");
    }
}


/**
 * 人, 制作咖啡
 */
public interface IMan {
    void makeCoffee(); // 制作咖啡
}

/**
 * 人制作咖啡
 */
public class Man implements IMan {
    private ICoffeeMachine coffeeMachine;

    public Man(ICoffeeMachine coffeeMachine) {
        this.coffeeMachine = coffeeMachine;
    }

    public void makeCoffee() {
        coffeeMachine.addWater();
        coffeeMachine.addCoffeeBean();
        coffeeMachine.makeCoffee();
    }
}

/**
 * 客户端
 */
public class Client {
    public static void main(String[] args) {
        ICoffeeMachine coffeeMachine = new CoffeeMachine();
        IMan man = new Man(coffeeMachine);
        man.makeCoffee();
    }
}



重构后

public interface ICoffeeMachine {
    void work();
}

public class CoffeeMachine implements ICoffeeMachine {
    private void addCoffeeBean() {
        System.out.println("放咖啡豆");
    }
    private void addWater() {
        System.out.println("加水");
    }
    private void makeCoffee() {
        System.out.println("制作咖啡");
    }

    @Override
    public void work() {
        addCoffeeBean();
        addWater();
        makeCoffee();
    }
}

public interface IMan {
    void makeCoffee();
}

public class Man implements IMan {
    private ICoffeeMachine coffeeMachine;

    public Man(ICoffeeMachine coffeeMachine) {
        this.coffeeMachine = coffeeMachine;
    }
    public void makeCoffee() {
        coffeeMachine.work();
    }
}

public class Client {
    public static void main(String[] args) {
        ICoffeeMachine coffeeMachine = new CoffeeMachine();

        IMan man = new Man(coffeeMachine);
        man.makeCoffee();
    }
}



image


  • 代码存在的问题?
    CoffeeMachine是Man的直接好友,
    但Man对CoffeeMachine了解的太多了,
    其实人根本不关心咖啡机具体制作咖啡的过程。


  • 根据迪米特原则, 如何优化?
    我们应该优化后的咖啡机类,
    只暴露一个work方法,
    把制作咖啡的三个具体的方法addCoffeeBean、addWater、makeCoffee设为私有,
    通过减少CoffeeMachine对外暴露的方法,
    减少Man对CoffeeMachine的了解,
    从而降低了它们之间的耦合.
    (迪米特原则: 减少对朋友的了解)


    迪米特法则的目的,是把我们的类变成一个个"肥宅".
    "肥"在于一个类对外暴露的方法可能很少,但是它内部的实现可能非常复杂(这个解释有点牵强~)。
    "宅"在于它只和直接的朋友交流。


    在现实生活中“肥宅”是个贬义词,
    在日本"肥宅"已经成为社会问题.
    但是在程序中,
    一个"肥宅"的类却是优秀类的典范.




posted @ 2023-10-22 03:30  qwertzxc  阅读(43)  评论(0)    收藏  举报