设计模式-原理-迪米特原则

1.原文

  1. Each unit should have only limited knowledge about other units: only units "closely" related to the current unit. (每个单元对于其他的单元只能拥有有限的知识:只是与当前单元紧密联系的单元)
  2. Each unit should only talk to its friends; don't talk to strangers. (每个单元只能和它的朋友交谈:不能和陌生单元交谈)
  3. Only talk to your immediate friends. (只和自己直接的朋友交谈) (来自维基百科)

2.理解:

上面是我抄的原文和译文,感觉还可以.明确几个概念和理解

(1).这应该是一个窄接口替换宽接口的说法

<?php
/*
这是一个比较宽的接口,有3个方法
*/
interface Ia{
    function a();
    function b();
    function c();
}
/*
宽接口的具体实现类,实现了宽接口定义的功能,
注意这时候A的能力很多,client是用不了这么多的
*/
class A implements Ia{
    function a(){}
    function b(){}
    function c(){}
}
/*
定义一个窄接口,屏蔽掉Ia别的功能(知识),保证client了解的知识是有限的.
同时这也是一个closely的抽象,亲密的单元需要有a()功能
*/
interface Ib{
    function a();
    function b();
}
/*
实现Ib,目标是实现a方法,通过调用一个实现了Ia接口的具体实现类(面向接口编程)
为什么不拆分Ia呢?因为是还有别的调用类面向Ia编程,依赖Ia接口,拆分了Ia,别人怎么办
*/
class B implements Ib{
    protected $a;
    function __construct(Ia $a)
    {
        $this->a = $a;
    }

    function a(){
        $this->a->a();
    }
    function b(){
       $this->a->b();
    }
    //这个实现类还有别的能力(知识)
    function c(){}
}
/*
具体的调用类.逻辑上client是依赖一个实现了Ib接口的实现类的实例的.并且只了解这个实现类有一个a(),b()功能
*/
class Client{
    function doSomething(Ib $b){
        //弄点儿事儿干...
        //执行一个依赖调用
        $b ->a();
        //再弄我自己的事儿
        //如果有一个组合功能放在那儿?
        if(true){
            $b ->a();
            $b ->b();
        }else{
            $b ->b();
            $b ->a();
        }
    }
}

(2)(3)陌生朋友,直接朋友(亲密朋友) ,其实是依赖关系是怎么诞生的.

传参(方法,构造函数),返回值约定类型这些都是直接朋友

下面这种就是陌生朋友

function test(){

      $a = new A();

     $a ->doSomething();

}

说白了就是不要定义局部的变量,来引用依赖.这种依赖关系耦合度很深,除了改代码没办法做修改

3.有一种防腐层的感觉,有一个亲近的朋友能解决我的所有问题.这个亲近朋友不是具体实现,而是一个代理或者说传话的.

那这个代理里面应该实现一些组合功能的逻辑么?

我认为看情况,根据这个组合逻辑是client要求的,还是Ib提供的协议.区别就是这个组合是由提供的.我建议固化在中间代理里面,再定义一个组合的约束

interface Ib
{

    function a();

    function d();

}

/*
实现Ib,目标是实现a方法,通过调用一个实现了Ia接口的具体实现类(面向接口编程)
*/

class B implements Ib
{

    protected $a;

    function __construct(Ia $a)
    {

        $this->a = $a;

    }

    function a()
    {

        $this->a->a();

    }

    function d($param)
    {

        if ($param) {

            $this->a->a();

            $this->a->b();

        }
        esle{

        $this->a->b();

        $this->a->a();

    }

}

//这个实现类还有别的能力(知识)
    function c()
    {
    }

}
 

/*
具体的调用类.逻辑上client是依赖一个实现了Ib接口的实现类的实例的.并且只了解这个实现类有一个a()功能
*/

class Client
{
    function doSomething(Ib $b)
    { 
         //弄点儿事儿干...
         //执行一个依赖调用
         $b ->a(); 
         //再弄我自己的事儿
          //再调用这个组合能力
         $b ->d(true);
    }
}

4.抄了一段儿说法感觉更全一点儿

迪米特法则的实现方法

从迪米特法则的定义和特点可知,它强调以下两点:

从依赖者的角度来说,只依赖应该依赖的对象。

从被依赖者的角度说,只暴露应该暴露的方法。

所以,在运用迪米特法则时要注意以下 6 点。

在类的划分上,应该创建弱耦合的类。类与类之间的耦合越弱,就越有利于实现可复用的目标。

在类的结构设计上,尽量降低类成员的访问权限。

在类的设计上,优先考虑将一个类设置成不变类。

在对其他类的引用上,将引用其他对象的次数降到最低。

不暴露类的属性成员,而应该提供相应的访问器(set 和 get 方法)。

谨慎使用序列化(Serializable)功能。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值