(五)JAVA设计模式中的六大设计原则之迪米特原则

迪米特法则(最少知道原则)旨在降低类之间的耦合度,确保软件实体只与其直接朋友通信。博客通过购物车、牛奶、货架类的示例,展示了如何违反和遵循该原则,指出过度使用可能导致系统复杂性增加。实践中需权衡耦合度与系统复杂度。
摘要由CSDN通过智能技术生成

为什么叫最少知道原则,就是说:一个实体应当尽量少的与其他实体之间发生相互作用,使得系统功能模块相对独立。也就是说一个软件实体应当尽可能少的与其他实体发生相互作用。这样,当一个模块修改时,就会尽量少的影响其他的模块,扩展会相对容易,这是对软件实体之间通信的限制,它要求限制软件实体之间通信的宽度和深度。

 

定义:一个对象应该对其他对象保持最少的了解。

问题由来:类与类之间的关系越密切,耦合度越大,当一个类发生改变时,对另一个类的影响也越大。

解决方案:尽量降低类与类之间的耦合。

自从我们接触编程开始,就知道了软件编程的总的原则:低耦合,高内聚。无论是面向过程编程还是面向对象编程,只有使各个模块之间的耦合尽量的低,才能提高代码的复用率。低耦合的优点不言而喻,但是怎么样编程才能做到低耦合呢?那正是迪米特法则要去完成的。

迪米特法则又叫最少知道原则,最早是在1987年由美国Northeastern University的Ian Holland提出。通俗的来讲,就是一个类对自己依赖的类知道的越少越好。也就是说,对于被依赖的类来说,无论逻辑多么复杂,都尽量地的将逻辑封装在类的内部,对外除了提供的public方法,不对外泄漏任何信息。迪米特法则还有一个更简单的定义:只与直接的朋友通信。首先来解释一下什么是直接的朋友:每个对象都会与其他对象有耦合关系,只要两个对象之间有耦合关系,我们就说这两个对象之间是朋友关系。耦合的方式很多,依赖、关联、组合、聚合等。其中,我们称出现成员变量、方法参数、方法返回值中的类为直接的朋友,而出现在局部变量中的类则不是直接的朋友。也就是说,陌生的类最好不要作为局部变量的形式出现在类的内部。

demo


入口类

package principle.demeter_principle;

import org.junit.Test;

/**
 * 5.迪米特法则(最少知道原则) (Demeter Principle)
 *
 * 为什么叫最少知道原则,就是说:一个实体应当尽量少的与其他实体之间发生相互作用,使得系统功能模块相对独立。也就是说一个软件实体应当尽可能少的与其他实体发生相互作用。这样,当一个模块修改时,就会尽量少的影响其他的模块,扩展会相对容易,这是对软件实体之间通信的限制,它要求限制软件实体之间通信的宽度和深度。
 *
 * 定义:一个对象应该对其他对象保持最少的了解。
 *
 * 问题由来:类与类之间的关系越密切,耦合度越大,当一个类发生改变时,对另一个类的影响也越大。
 *
 * 解决方案:尽量降低类与类之间的耦合。
 *
 * 自从我们接触编程开始,就知道了软件编程的总的原则:低耦合,高内聚。无论是面向过程编程还是面向对象编程,只有使各个模块之间的耦合尽量的低,才能提高代码的复用率。低耦合的优点不言而喻,但是怎么样编程才能做到低耦合呢?那正是迪米特法则要去完成的。
 *
 * 迪米特法则又叫最少知道原则,最早是在1987年由美国Northeastern University的Ian Holland提出。通俗的来讲,就是一个类对自己依赖的类知道的越少越好。也就是说,对于被依赖的类来说,无论逻辑多么复杂,都尽量地的将逻辑封装在类的内部,对外除了提供的public方法,不对外泄漏任何信息。迪米特法则还有一个更简单的定义:只与直接的朋友通信。首先来解释一下什么是直接的朋友:每个对象都会与其他对象有耦合关系,只要两个对象之间有耦合关系,我们就说这两个对象之间是朋友关系。耦合的方式很多,依赖、关联、组合、聚合等。其中,我们称出现成员变量、方法参数、方法返回值中的类为直接的朋友,而出现在局部变量中的类则不是直接的朋友。也就是说,陌生的类最好不要作为局部变量的形式出现在类的内部。
 *
 * 举一个例子:有一个集团公司,下属单位有分公司和直属部门,现在要求打印出所有下属单位的员工ID。先来看一下违反迪米特法则的设计。
 */
public class Client {
    @Test
    public void test(){
        ShoppingCart shoppingCart = new ShoppingCart();

        Milk milk1 = new Milk("牛奶",150f,"新西兰","含锌量x微克");
        Milk milk2 = new Milk("羊奶",180f,"中国","含锌量x微克");
        Milk milk3 = new Milk("骆驼奶",280f,"埃及","含锌量x微克");

        Shelves shelves = new Shelves();
        shelves.add(milk1);
        shelves.add(milk2);//上架
        shelves.add(milk3);//上架


        shoppingCart.addMilk(milk1);
        shoppingCart.addMilk(milk2);

        //只需要 购买牛奶,价格为150.0,但是对象中还包含产地、微元素,违反 迪米特法则(最少知道原则)
        shoppingCart.buyMilk();

        //采用最少知道原则
        shoppingCart.addProduct(shelves.getProduct(0));
        shoppingCart.addProduct(shelves.getProduct(2));
        shoppingCart.buyProduct();
    }
}

购物车,客户选择购买产品,添加到购物车 

package principle.demeter_principle;

import java.util.ArrayList;
import java.util.List;

/**
 * 购物车
 */
public class ShoppingCart {
    List<Milk> milkList = new ArrayList<>();

    //正确使用
    List<Product> productList = new ArrayList<>();

    public void buyMilk(){
        milkList.forEach(
                milk -> System.out.println(String.format("购买%s,价格为%s",milk.getName(),milk.getPrice()))
        );
        System.out.println();

    }

    public void buyProduct(){
        milkList.forEach(
                product -> System.out.println(String.format("购买%s,价格为%s",product.getName(),product.getPrice()))
        );
        System.out.println();

    }

    public void addMilk(Milk milk){
        milkList.add(milk);
    }

    public void addProduct(Product product){
        productList.add(product);
    }

}

 店铺上线商品 牛奶

package principle.demeter_principle;

import java.util.List;

/**
 * 上线的产品 牛奶
 */
public class Milk {
    private String name;//产品名称
    private float price;//价格
    private String originPlace;//产地
    private String surfaceElement;//微元素含量


    public Milk(String name, float price, String originPlace, String surfaceElement) {
        this.name = name;
        this.price = price;
        this.originPlace = originPlace;
        this.surfaceElement = surfaceElement;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public float getPrice() {
        return price;
    }

    public void setPrice(float price) {
        this.price = price;
    }

    public String getOriginPlace() {
        return originPlace;
    }

    public void setOriginPlace(String originPlace) {
        this.originPlace = originPlace;
    }

    public String getSurfaceElement() {
        return surfaceElement;
    }

    public void setSurfaceElement(String surfaceElement) {
        this.surfaceElement = surfaceElement;
    }
}

选购的产品model 

package principle.demeter_principle;

/**
 * 选购的产品
 */
public class Product {
    private String name;//产品名称
    private float price;//价格

    public Product(String name, float price) {
        this.name = name;
        this.price = price;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public float getPrice() {
        return price;
    }

    public void setPrice(float price) {
        this.price = price;
    }
}

牛奶转换为购买产品 ,保留最少的信息,适用于迪米特原则

package principle.demeter_principle;

import java.util.ArrayList;
import java.util.List;

/**
 * 牛奶转换为选购产品清单 ,仅保留产品名称和价格,其他信息过滤掉
 * 适用于迪米特原则
 */
public class Shelves {
    List<Milk> milkList = new ArrayList<>();

    void add(Milk milk){
        milkList.add(milk);
    }

    Product getProduct(int index){
       return new Product(milkList.get(index).getName(),milkList.get(index).getPrice());
    }
}

 迪米特法则的初衷是降低类之间的耦合,由于每个类都减少了不必要的依赖,因此的确可以降低耦合关系。但是凡事都有度,虽然可以避免与非直接的类通信,但是要通信,必然会通过一个“中介”来发生联系。过分的使用迪米特原则,会产生大量这样的中介和传递类,导致系统复杂度变大。所以在采用迪米特法则时要反复权衡,既做到结构清晰,又要高内聚低耦合。

 六大设计原则:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值