设计模式:迪米特法则 - 最少依赖,实现高内聚低耦合

一、迪米特法则简介

迪米特法则(Law of Demeter,简称 LoD),也称为"最少知识法则",核心思想是:一个对象应当对其他对象有最少的了解,仅与直接相关的对象交互。通过减少对象之间的耦合度,避免直接操作对象的内部结构,可以提高系统的灵活性和可维护性。

二、迪米特法则的核心原则

1.只与直接朋友交互:一个对象应只和直接依赖的对象交互,而避免操作其他对象的内部属性或方法。

2.避免链式调用:链式调用会加深对象间的依赖关系,增加系统复杂度和耦合度。

3.最小化接口暴露:隐藏实现细节,只对外提供必要的功能接口。

三、反例:违反迪米特法则的设计

场景:发动机 ,车 和 司机 3个类间的调用关系。

在反例中,Driver类直接依赖了Car和Engine,破坏了迪米特法则的核心思想。

1.Engine 类

java 复制代码
public class Engine {
    private String model;

    // 构造器,初始化发动机模型
    public Engine(String model) {
        this.model = model;
    }

    // 获取发动机模型
    public String getModel() {
        return model;
    }
}

2.Car 类

此类暴露了Enginer 类。

java 复制代码
public class Car {
    private Engine engine;

    public Car(Engine engine) {
        this.engine = engine;
    }

    public Engine getEngine() {
        return engine; // 直接暴露 Engine 对象
    }
}

3.Driver 类

此类直接访问了Engine 类和 Car类。

java 复制代码
public class Driver {
    private Car car;

    public Driver(Car car) {
        this.car = car;
    }

    public void drive() {
        // Driver 直接访问 Engine
        Engine engine = car.getEngine();
        System.out.println("Driving a car with engine: " + engine.getModel());
    }
}

4.Main 类(测试代码)

java 复制代码
public class Main {
    public static void main(String[] args) {
        Engine engine = new Engine("V8");
        Car car = new Car(engine);
        Driver driver = new Driver(car);

        driver.drive(); // 输出: Driving a car with engine: V8
    }
}

问题分析

1.违反迪米特法则

• Driver类直接操作了Engine,依赖了Car的内部实现细节。

• 如果Car类的实现发生变化(如更换发动机),Driver类也需要随之修改。

2.高耦合

• Driver同时依赖了Car和Engine,可维护性和扩展性降低。

3.职责分散

• Driver类承担了过多的职责,本应由Car提供的行为被Driver部分替代,导致职责不明确。

四、正例:符合迪米特法则的设计

在正例中,Driver类只与Car类交互,不直接访问Engine的内部实现。

1.Engine 类

(与反例相同,省略重复代码)

2.Car 类

与反例的差别是Car类不暴露Engine类。

java 复制代码
public class Car {
    private Engine engine;

    public Car(Engine engine) {
        this.engine = engine;
    }

    // 隐藏内部实现细节,提供外部接口
    public void startCar() {
        System.out.println("Starting car with engine: " + engine.getModel());
    }
}

3.Driver 类

与反例的差异是 Driver类只与Car 交互。

java 复制代码
public class Driver {
    private Car car;

    public Driver(Car car) {
        this.car = car;
    }

    public void drive() {
        // 只与 Car 类交互,避免直接访问 Engine
        car.startCar();
    }
}

4.Main 类(测试代码)

java 复制代码
public class Main {
    public static void main(String[] args) {
        Engine engine = new Engine("V8");
        Car car = new Car(engine);
        Driver driver = new Driver(car);

        driver.drive(); // 输出: Starting car with engine: V8
    }
}

说明:

• Engine类:负责管理发动机的属性(如模型)。

• Car类:负责管理汽车及其相关操作(如启动汽车)。

• Driver类:负责模拟司机与汽车的互动。

• Main类:测试和展示程序的执行过程。

优化分析

1.遵循迪米特法则:

• Driver类只与Car交互,而不直接访问Engine的内部实现。

• 如果Car类内部实现发生变化(如更换发动机类型),Driver类无需修改。

2.低耦合:

• Driver和Engine之间没有直接依赖,代码更易维护。

3.职责单一:

• Car负责与Engine的交互,Driver只负责操作Car。

4.扩展性高:

• 如果需要为Car增加新功能(如油耗管理),只需修改Car类,无需更改Driver。

五、正反例对比

通过清晰的职责划分和依赖关系解耦,正例设计严格遵循迪米特法则,避免了不必要的实现细节暴露,显著降低了系统的耦合度,提升了代码的可维护性和扩展性。

六、总结

迪米特法则通过限制类与类之间的直接依赖,使系统设计更加松耦合,显著提升代码的可维护性和扩展性。遵循这一法则,开发者可以减少因需求变更而引发的代码改动范围,从而保持系统的稳定性和灵活性。

在设计时,应优先隐藏实现细节,确保类之间职责单一、依赖清晰,以构建灵活易维护的高质量系统。

相关推荐
yangyang_z8 小时前
【C++设计模式之Template Method Pattern】
设计模式
源远流长jerry9 小时前
常用设计模式
设计模式
z26373056119 小时前
六大设计模式--OCP(开闭原则):构建可扩展软件的基石
设计模式·开闭原则
01空间16 小时前
设计模式简述(十八)享元模式
设计模式·享元模式
秋名RG19 小时前
深入理解设计模式之原型模式(Prototype Pattern)
设计模式·原型模式
Li小李同学Li1 天前
设计模式【cpp实现版本】
单例模式·设计模式
周努力.2 天前
设计模式之状态模式
设计模式·状态模式
268572592 天前
Java 23种设计模式 - 行为型模式11种
java·开发语言·设计模式
摘星编程2 天前
并发设计模式实战系列(19):监视器(Monitor)
设计模式·并发编程
yangyang_z2 天前
【C++设计模式之Strategy策略模式】
c++·设计模式·策略模式