概述

迪米特法则(Law of Demeter )又叫做最少知识原则,即一个对象应该对另一个对象有最少的了解。
迪米特法则的目的在于降低类之间的耦合。由于每个类尽量减少对其他类的依赖,因此,很容易使得系统的功能模块功能独立,相互之间不存在(或很少有)依赖关系。
迪米特原则实际上就是一个类在创建方法和属性时要遵守的法则;

迪米特原则核心指导思想为只和直接朋友通信(成员对象、方法参数、方法返回值;值出现在局部变量的类 ,不是直接朋友)。

案例需求1

实现人关机电脑(人关机电脑一般最起码分为三个步骤,第一步先保存当前的任务,第二步关闭屏幕,第三步关机电源)。

未使用迪米特原则的代码

public class Computer{    public void SaveTask(){Console.WriteLine("保存当前电脑任务");}public void CloseScreen(){Console.WriteLine("关闭屏幕");}public void ShutDown(){Console.WriteLine("关闭电源");}      }public class Person{public void CloseComputer(Computer computer){computer.SaveTask();    computer.CloseScreen();computer.ShutDown();}}

上面person类中的CloseComputer方法中逻辑不符合迪米特原则,如果关机需要三十步,computer需要提供30个方法,每个方法之间都有相应的绝对顺序

使用迪米特原则的代码

public class Computer{public void SaveTask(){Console.WriteLine("保存当前电脑任务");}public void CloseScreen(){Console.WriteLine("关闭屏幕");}public void ShutDown(){Console.WriteLine("关闭电源");}public  void CloseComputer(){this.SaveTask();this.CloseScreen();this.ShutDown();}}//person类中closecomputer方法中的参数computer为直接朋友,符合迪米特原则public class Person{public void CloseComputer(Computer computer){           computer.CloseComputer();}}

上面person类中的CloseComputer方法只负责调用Computer中的CloseComputer方法,如果关机电脑这个需求有其他的变化,computer类里面添加方法或发生逻辑变化,person类始终不会发生改变。

关于迪米特原则很多人听到这个词,估计有点陌生,真实编程中可能这样用过,但不知道其名字,所以我们再来看一个案例需求,加深巩固理解。

案例需求2

分别打印总公司和分公司员工的编号;

未使用迪米特原则的代码

public class HeadOfficeEmployee{public int Id { get; set; }}/// <summary>/// 总公司管理者/// </summary>public class HeadOfficeManager{/// <summary>/// 获取员工数/// </summary>/// <returns></returns>public List<HeadOfficeEmployee> GetEmployees(){ List<HeadOfficeEmployee> headOffices = new List<HeadOfficeEmployee>();for (int i = 0; i < 10; i++){HeadOfficeEmployee headOfficeEmployee = new HeadOfficeEmployee();headOfficeEmployee.Id = i;headOffices.Add(headOfficeEmployee);}return headOffices;}/// <summary>/// 打印总公司员工id/// </summary>public void Print(BranchOfficeManager branchOfficeManager){var datas=  GetEmployees();Console.WriteLine("总公司员工Id分别是:" );foreach (var item in datas){Console.WriteLine(+item.Id);}//branchOfficeEmployes这个集合对象,是通过局部变量的形式出现在类中的,所以不是我们的直接朋友,故不符合迪米特原则。var branchOfficeEmployes= branchOfficeManager.GetEmployees();Console.WriteLine("分公司员工Id分别是:");foreach (var item in branchOfficeEmployes){Console.WriteLine(+item.Id);}}}
//C# 控制台调用
BranchOfficeManager branchOfficeManager = new BranchOfficeManager();new HeadOfficeManager().Print(branchOfficeManager);

以上HeadOfficeManager类中Print方法传递的参数branchOfficeManager是直接朋友,GetEmployee()中返回的集合对象也是直接朋友符合迪米特原则,但branchOfficeManager.GetEmployees()获取的集合branchOfficeEmployes是通过局部变量的形式出现在类中的,所以不符合迪米特原则。

使用迪米特原则改造后的代码

/// <summary>/// 总公司员工/// </summary>public class HeadOfficeEmployee{public int Id { get; set; }}/// <summary>/// 总公司管理者/// </summary>public class HeadOfficeManager{/// <summary>/// 获取员工数/// </summary>/// <returns></returns>public List<HeadOfficeEmployee> GetEmployees(){ List<HeadOfficeEmployee> headOffices = new List<HeadOfficeEmployee>();for (int i = 0; i < 10; i++){HeadOfficeEmployee headOfficeEmployee = new HeadOfficeEmployee();headOfficeEmployee.Id = i;headOffices.Add(headOfficeEmployee);}return headOffices;}/// <summary>/// 打印总公司员工id/// </summary>public void Print(){var datas=  GetEmployees();Console.WriteLine("总公司员工Id分别是:" );foreach (var item in datas){Console.WriteLine(+item.Id);}           }}
/// <summary>/// 分公司员工类/// </summary>public class BranchOfficeEmployee{public int Id { get; set; }}/// <summary>/// 分公司员工管理者/// </summary>public class BranchOfficeManager{public List<BranchOfficeEmployee> GetEmployees(){ List<BranchOfficeEmployee> headOffices = new List<BranchOfficeEmployee>();for (int i = 0; i < 10; i++){BranchOfficeEmployee headOfficeEmployee = new BranchOfficeEmployee();headOfficeEmployee.Id = i;headOffices.Add(headOfficeEmployee);}return headOffices;}/// <summary>/// 打印分公司每个员工Id/// </summary>public void Print(){var datas=  GetEmployees();Console.WriteLine("分公司公司员工Id分别是:" );foreach (var item in datas){Console.WriteLine(+item.Id);}}}
//C#控制台调用
new HeadOfficeManager().Print();
BranchOfficeManager branchOfficeManager = new BranchOfficeManager();
branchOfficeManager.Print();

总结

迪米特原则在我们日常编码中可能往往最容易被忽略,像案例2这样的需求,尤其写第一种方案的代码的人估计不少,我也写过,慢慢掌握了设计原则后,可以和之前写地代码做下对比,心中会有另一番收获。


必知必会的设计原则——接口隔离原则

必知必会的设计原则——里氏替换原则

必知必会的设计原则——依赖倒置原则

必知必会的设计原则——开放封闭原则

必知必会的设计原则——单一职责原则

单例模式使用饿汉式和懒汉式创建一定安全?很多人不知

必知必会的设计原则——迪米特原则相关推荐

  1. mysql日期维表sql文件_《MySQL必知必会》笔记(SQL练习+建表语句)

    站在巨人的肩上 Standing On Shoulders Of Giants 部分转自:https://www.jianshu.com/p/294502893128 https://blog.csd ...

  2. 【系统分析师之路】系统分析师必知必会(需求分析篇)

    [系统分析师之路]系统分析师必知必会(需求分析篇) 系统分析师必知必会 需求分析篇 [系统分析师之路]系统分析师必知必会(需求分析篇) 1.什么是软件需求 2. 需求分类 2.1)业务需求 2.2)用 ...

  3. SQL必知必会读书笔记

    <SQL必知必会> 1.SQL概述(概念.优点.数据库术语) * 日常生活中的数据库案例举例(例如在网站搜索东西:登录账号密码:取钱:) * 数据库概念:数据库database(以一种有组 ...

  4. SQL必知必会第4版读书笔记

    SQL必知必会_4 前言 @author 鲁伟林 在读电子版<<SQL必知必会>> 第4版时,做了下笔记.供以后自己或者其他学习者参考. 电子版<<SQL必知必会& ...

  5. java面试必知必会

    java面试必知必会 面向对象 成员变量成员方法 Integer相关 double 和 Double相关 多态,向上转型 hashcode.==.equals比较 java中子类继承父类时是否继承构造 ...

  6. MySQL必知必会笔记(一)基础知识和基本操作

    第一章  了解MySQL     数据库       保存有组织的数据的容器.(通常是一个文件或一组文件) 人们经常使用数据库这个术语代替他们使用的软件.这是不正确的,确切的说,数据库软件应称为DBM ...

  7. 从《MySQL必知必会》中对MySQL的理解

    MySQL是一个开源的DBMS,是目前主流的关系型数据库DBMS之一.在<MySQL必知必会>中,作者通过简单实用的订单实例简而明要地介绍了MySQL,这里简单汇总. 查询 检索+过滤+排 ...

  8. 《渗透测试实践指南 必知必会的工具与方法 (原书第2版)》读书摘录

    ----------------------------------------------------------------------------分割线--------------------- ...

  9. 程序员必知必会之 word 篇

    程序员必知必会之 word 篇 网易广州 赖勇浩 程序员必知必会之blog篇 地址:http://blog.csdn.net/lanphaday/archive/2007/08/16/1746852. ...

最新文章

  1. CVPR2021 | 重新思考BiSeNet让语义分割模型速度起飞
  2. tcp协议缓冲区溢出_关于TCP 粘包拆包,你了解吗?
  3. 完整年份值必须介于_上 | 完整解释 Monad 程序员范畴论入门
  4. 负载均衡环境搭建实战之nginx和tomcat
  5. 图表相同数据会自动合并问题(finereport)
  6. 『实用』判断一个噩梦客户的7个预警信号
  7. python opencv3 圆检测
  8. sed与正则用法收集
  9. java截取utf8字符串_java中常用的字符串的截取方法
  10. 知乎:学习分布式系统需要怎样的知识?
  11. lepus监控mysql慢查询_天兔(Lepus 3.8)收集MySQL慢查询
  12. 动态二级下拉菜单html,jquery实现漂亮的二级下拉菜单代码
  13. 每日一书丨金融反欺诈的底层逻辑
  14. 利用turtle模块画一棵树,包括枝干和树叶,并涂上颜色
  15. 小红帽 oracle,Linux+5+红帽子企业版安装Oracle9
  16. Linux云计算好学吗?Linux云计算运维学习资料 文件的基本管理
  17. 智能化测试技术探索与实践——AAAS/IEEE Fellow、北京大学讲席教授谢涛阿里行
  18. PDF文件如何另存为
  19. 2014阿里巴巴秋季校园招聘-软件研发工程师笔试题/面试问题收集
  20. 终于好了,自动生成支付宝自定义收款码

热门文章

  1. 分布式架构--两阶段提交和三阶段提交
  2. C/C++ 动态内存分配
  3. 机器学习(五)——正规化
  4. java10安装步骤
  5. Linux动态查看时间
  6. web简单的整体测试
  7. hutool包下BeanUtil常用方法
  8. ZBrush - 四方连续贴图的制作
  9. 代码生成 NFT 后,艺术家能否躺着赚钱?# Art Block 生成艺术
  10. PHP 保留小数点后几位