书接上回,本篇继续讲一下设计模式六大原则(有些书认为是7大原则)

原则定义

迪米特法则(Law of Demeter,LoD)的定义有点意思,有2种表述

1> 最少知道原则,指一个对象应当对其他对象有尽可能少的了解。

2> 只和直接的朋友交流(也有说法:不要与陌生人说话)

初看有点令人摸不着头脑,细细品品,好像是那么一回事,说下个人理解:

1> 最少知道原则,指一个对象应当对其他对象有尽可能少的了解。

其实可以理解为,在符合设计(开发)规范前提下,对象与对象间能不交互就不要交互,保持对象的独立性,降低类间耦合度,提高模块的复用性。

2>只和直接的朋友交流(也有说法:不要与陌生人说话)

这里的朋友,是朋友类的意思,理解起来有点抽象,因为我们对象朋友类这词有点陌生。迪米特法则提出者给出朋友类定义:A类如果被B类依赖,那A类就是B类的朋友类。下面都是B类的朋友类存在形式

public class A{//....
}

成员变量:

public class B{private A a;
}

方法参数:

public class B{public void someMethod(A a){...}
}

方法返回值:

public class B{public A someMethod(){return a;}
}

需要注意,这种形式存在时,A类不算是B类的朋友类,而是陌生人

方法中,A类左右局部变量/对象

public class B{public void someMethod(){A a = new A();}
}

理想状态就是这样啦,但真实操作哪有那么理想,类多之后肯定存在或多或少类间直接较互,特别是上面讲的与陌生类交互,该怎么办?迪米特法则建议通过友元类的方式类避免。这里的友元类可以理解为:中介类,也可以理解为一种统一调配的类。下面例子:

public class C{void doWork(){...}
}//A不方便直接与C交互
public class A{public void doWork(){C c = new C();c.doWork();}
}//可以借助B
public class B{public void doWork(){this.getC().doWork();}public C  getC(){return new C();}
}//改造后的A
public class A{public void doWork(B b){b.doWork();}
}

B为友元类,A借助B类实现与C类的间接交互。

案例分析

需求:乘客预约出租车去上班

//出租车
public class TaxiCar {public void run() {System.out.println("司机大叔开始达到目的地....");}
}
//司机
public class Driver {public TaxiCar getCar() {System.out.println("司机大叔按约定时间达到约定地点等待客户...");return  new TaxiCar();}
}
//乘客
public class Passenger {public void goToWork(Driver driver) {TaxiCar car = driver.getCar();car.run();}
}

测试:

//测试
public class App {public static void main(String[] args) {//客人Passenger p = new Passenger();//司机Driver driver = new Driver();//上班p.goToWork(driver);}
}
结果:
司机大叔按约定时间达到约定地点等待客户...
司机大叔开始达到目的地....

解析

上面模拟乘客上班场景,乘客预约司机,司机使用出租车送乘客上班。咋一看毛事没有啥问题,细看有点怪怪的,比如Passenger类goToWork方法,传入Driver类之后,通过Driver类的getCar方法,然后在使用TaxiCar类的run方法完成goToWork功能。这里的TaxiCar对于Passenger类是陌生类,违背了迪米特法则不与陌生人交流的要求。

改进版

修改后Drvier类

//司机
public class Driver {//私有private TaxiCar getCar() {System.out.println("司机大叔按约定时间达到约定地点等待客户...");return  new TaxiCar();}//新增驾车方法public void drive(){TaxiCar car = getCar();car.run();}
}

修改后Passenger类

//乘客
public class Passenger {public void goToWork(Driver driver) {driver.drive();}
}

解析:

改进后的案例就合理多了。Passenger类不需要在意TaxiCar类怎么操作,只需要Driver能完成driver功能即可。Driver使用drive方法遮蔽Passenger类对TaxiCar类直接引用,这符合迪米特法则。

使用注意

迪米特法则,对类之间交互的宽度与深度进行限制,正确使用可以提高系统架构复用率跟拓展性。但过度使用迪米特方法,会使用系统产生大量的友元类,从而增加系统的复杂性,使模块之间的通信效率降低。所以,在釆用迪米特法则时要反复权衡,在确保高内聚和低耦合同时,保证系统的结构清晰。

那实际编码时,需要注意什么呢?一下几点:

1:设计类时,考虑类间的耦合情况,合理减少类间交互,如果必要可以尝试使用内部类

2:尽可能使用private访问权限修饰属性成员,不外泄内部信息

3:满足需求设计前提,可以将类设置成final类

4:使用JavaBean规范,合理暴露属性成员

运用

这次使用shrio身份验证为例子展开讲:

Shiro进行身份验证涉及到几个参与方:

Subject : 用户对象抽象类,里面封装用户信息与用户相关动作,比如鉴权与授权委托操作

UsernameAndPasswordToken:用户身份信息(username, password)封装对象

SecurityManager :shiro的大管家,负责资源调配

Realms:数据来源中间对象,负责与数据库,或者其他来源数据对接,转换成shiro可操作对象

Authentication:身份验证器

整个身份验证流程

UsernameAndPasswordToken

UsernameAndPasswordToken token = new UsernameAndPasswordToken("账号", "密码");

Subject类

public void login(AuthenticationToken token) throws AuthenticationException {Subject subject = securityManager.login(this, token);
}

SecurityManager 类

public Subject login(Subject subject, AuthenticationToken token) throws AuthenticationException {authenticate(token);
}public AuthenticationInfo authenticate(AuthenticationToken token) throws AuthenticationException {return this.authenticator.authenticate(token);
}

Authentication类

public final AuthenticationInfo authenticate(AuthenticationToken token){doAuthenticate(token);
}protected AuthenticationInfo doAuthenticate(AuthenticationToken authenticationToken)  {assertRealmsConfigured();Collection<Realm> realms = getRealms();if (realms.size() == 1) {return doSingleRealmAuthentication(realms.iterator().next(), authenticationToken);} else {return doMultiRealmAuthentication(realms, authenticationToken);}
}

结合上面核心代码,看下,一层一层委托下去,subject的login操作只需要委托给SecurityManager 类操作即可,不需要关注背后如何实现,只跟它朋友类SecurityManager 交互,这就是典型的迪米特法则使用。有兴趣大家跟踪下shiro鉴权操作,大同小异。

总结

迪米特法则使用过程中要明确的:

1:最少知道原则: A类减少与其他类的交互,其他类仅暴露A类需要方法或属性

2:不与陌生类交互:A类不可避免与陌生类交互,需要合理使用友元类(中介类)

浅谈设计模式-迪米特法则相关推荐

  1. 设计模式 迪米特法则

    设计模式 迪米特法则 只和朋友交流 Only talk to your immediate friends 只与直接的朋友通信.即每个对象都有耦合关系,对象之间有耦合. 定义老师类 public cl ...

  2. 浅谈设计模式 | 先有鸡还是先有蛋?先有代码后有设计模式还是先有设计模式再写代码?

    前言 一.面向对象的三大特性 1. 封装 2.继承 3.多态 二.面向对象七个设计原则 1.单一职责原则 2.开放封闭原则 3.里氏替换原则 4.接口隔离原则 5.依赖倒置原则 6.合成复用原则 7. ...

  3. 【大话设计模式】——浅谈设计模式基础

    初学设计模式给我最大的感受是:人类真是伟大啊!单单是设计模式的基础课程就让我感受到了强烈的生活气息. 个人感觉<大话设计模式>这本书写的真好.让貌似非常晦涩难懂的设计模式变的生活化.趣味化 ...

  4. 浅谈设计模式及python实现

    设计模式及Python实现 设计模式是什么? Christopher Alexander:"每一个模式描述了一个在我们周围不断重复发生的问题,以及该问题的解决方案的核心.这样你就能一次又一次 ...

  5. 迪米特法则 java_java设计模式--迪米特法则

    基本介绍 1.一个对象应该对其他对象保持最少的了解 2.类与类关系越密切,耦合度越大 3.迪米特法则又叫最少知道原则,即一个类对自己依赖的类知道的越少越好.也就是说,对于被依赖的类不管多么复杂,都尽量 ...

  6. [设计模式]迪米特法则

    迪米特法则 又叫最少知识法则 类中的成员属性和成员方法,如果不需要对外暴露,就不要设成public. 代码如下: #include <iostream> #include <stri ...

  7. Java设计模式-迪米特法则

    迪米特法则 [Low Of Demeter]   定义:一个对象应该对其他对象保持最少的了解.   问题由来:类与类之间的关系越密切,耦合度越大,当一个类发生改变时,对另一个类的影响也越大.   解决 ...

  8. 23种设计模式-迪米特法则

    概念: 1) 一个对象应该对其他对象保持最少的了解 2) 类与类关系越密切,耦合度越大 3) 迪米特法则(Demeter Principle)又叫最少知道原则,即一个类对自己依赖的类知道的 越少越好. ...

  9. 浅谈设计模式在iOS开发实战项目中的应用

    在我们日常的开发中设计模式伴随着项目的各个模块,巧妙地使用设计模式可以让我们写出更高效,简洁,优美的代码.可是因为对于设计模式的不熟悉,很多高效的设计模式并没有被很好地使用起来,而最近也正好在revi ...

最新文章

  1. apache用户认证
  2. 设计模式总结(Java)—— 观察者模式
  3. linux防火墙添加端口并开闭防火墙
  4. MongoDB文档对象字段属性合并的2种转换方法
  5. 老鼠实验中老鼠的数量变化曲线
  6. python删除文件和linux删除文件区别_使用Python批量删除文件列表
  7. java for 线程_如何在for循环中使用多线程
  8. sql中全文检索的具体细节
  9. 3Dmax读取丢失的贴图的方法
  10. 小米笔记本 镜像_小米笔记本Air 13.3原装出厂WIN10 2004 ISO镜像下载
  11. Kaggle共享单车需求项目详解
  12. java电子通讯录毕业设计_JAVA电子通讯录(带系统托盘)009
  13. Bouncing Ball
  14. matlab中的灰色预测,灰色预测MATLAB程序
  15. SQLiteSpy下载安装
  16. 《提问的智慧》 - 懒人的脑图
  17. AHU-727 美妙音乐 【DP】
  18. QQ是怎么处理消息的
  19. 华为平板M3能用鸿蒙吗,华为平板M3怎么样 麒麟950处理器搭配快充只要1888!
  20. C语言程序设计第五章循环结构程序设计总结

热门文章

  1. 存贮论(一):基本概念、无约束的确定型存贮模型
  2. 有关java中equals()与hashCode()的探讨
  3. Python 生成圣诞树 Santa Tree Generator 不务正业系列#1
  4. 基于MSP430单片机风光互补控制路灯设计(毕业设计资料)
  5. java.lang.IllegalArgumentException: object is not an instance of declaring class
  6. Qtdesinger 去除 Text Browser边框
  7. validate表单验证的用法
  8. 小程序,快应用,心是够大,但胸不大
  9. 计算机软件3dmax在展览中的研究,博物馆3D扫描技术的应用及前景
  10. 手机腾讯云计算机广告怎么关,教你关闭烦人的电脑弹窗广告