设计模式6大原则(5):迪米特法则

迪米特法则

迪米特法则:Law of Demeter(LoD)

       设计模式6大原则中,怎么出现一个法则呢?原则强调说话行事的准则,规则;法则强调规律,法度规范。不过这里我们不讨论文字,1987年秋天由美国Northeastern University的Ian Holland提出,被UML的创始者之一Booch等普及。后来,因为在经典著作《 The Pragmatic Programmer》而广为人知。迪米特法则还有一个别名:

最少知识原则:Least Knowledge Principle(LKP)

       这下就清晰多了,意思就是一个对象应该对其他对象尽可能的少了解,不和陌生人说话。简单的说,就是我知道你提供的这几个public方法,我就调用这几个,其他的我不管,你内部怎么实现的我也不管。迪米特法则还包含了以下4层含义:

       1.只与朋友通信:Only talk to your immedate friends。

       什么意思呢?举例说明,比如想知道某人付钱时是否有足够的钱

  

  public void buy(Good good) {
       if (person.getWallet().getMoney()< good.getPrice()) {
           throw new Exception("钱不够");
       }
…………
    } 

       人先获得了钱包,然后获取钱,然后比价格,看似很正常,挺好的代码。确实很好,运行起来没有问题,但是却违反了迪米特法则,因为此处buy这个方法所在的类依赖了Wallet钱包这个类,其实他完全可以不需要知道钱包的。

       换正常生活中的例子,你去买东西,卖家要看你钱够不够,会去掏你钱包,然后看看钱是否够吗?当然不会,虽然结果一样,都可以完成,但是不符合正常人思维。况且,人不一定都有钱包呀,万一有个人没有钱包呢,但是却有钱,或者钱包类有一天改了,没有getMoney()方法了,改名叫money()怎么办,难道买东西这个方法也要改吗?想想正常生活中我们是怎么去决定是否有钱的。

    public void buy(Good good) {
       if (!person.isEnough(good.getPrice())){
           throw new Exception("钱不够");
       }
       …………
}


       这样是不是就符合实际多了,看着也好理解了,直接问人钱是否够,卖家不管你人内部怎么处理的,他只与人这个类有接触,所以他俩是朋友,他不关心钱包不钱包。

       只与朋友通信就是这个意思,代码中不要出现getA().getB().getC().getD()这种情况(如果返回结果是自身,那么是可以的),当然,此处说的朋友类之间,是指自己创建的类,JDK API提供的类除外。

       2.朋友间也是有距离的

       前面说了只与朋友通信,那么朋友间就可以无限制的通信吗,当然不是,朋友类之间也是有距离的,就像两个刺猬取暖,不能太远,也不能太近。也就是说即使是朋友间,也要知道的最少,我不需要知道你太多的东西,知道越少,耦合越小嘛。

       说白了,就是能不用public就不用public,多用private和protected,类一定要羞涩,public越多,维护成本越大,风险越大。

       3.是自己的就是自己的

       上面那个例子,就不如把buy放到Person类中,这样调用者就不用管是否钱够,只需person.buy(good)一下即可。这个buy()方法,放到person中也行,放到外边也行,那怎么决定呢?有一个原则:如果一个方法放在本类中,即不增加类间关系,也不对本类产生负面影响,那就可以放到本类中。

       ok,最后说一下,迪米特法则核心观念就是解耦、弱耦合,只有弱耦合后,类的复用率才可以提高。知道的少,不知道的不管,如果一个类跳转两次以上才能访问另一个类,那么就需要考虑重构了,因为跳转次数越多,系统越复杂,维护起来越困难,不过这个情况要具体分析。解耦和也是要有限度的,别为了套用原则而做项目,一味地追求解耦结果就是产生了大量的中转或跳转类,导致系统复杂性提高,维护困难,实际生产中应该反复权衡。

       总结一下

              ①在类的划分上,应该创建有弱耦合的类;

              ②在类的结构设计上,每一个类都应当尽量降低成员的访问权限;

              ③在类的设计上,只要有可能,一个类应当设计成不变类;

              ④在对其他类的引用上,一个对象对其它对象的引用应当降到最低;

              ⑤尽量降低类的访问权限;

              ⑥谨慎使用序列化功能;

              ⑦不要暴露类成员,而应该提供相应的访问器(属性)。


 


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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值