设计模式6大原则-迪米特法则

设计模式6大原则-迪米特法则

定义:迪米特法则也称为最少知识原则,一个对象应该对其他对象有最少的了解,迪米特法则的一个英文解释为: Only talk to your immediate friends (只和你最亲近的朋友交谈)。

一个类应该对自己需要耦合的类或者调用的类知道的最少,被耦合或调用的类内部逻辑跟自身无关,也不需要关心,只需要知道被耦合或者调用类提供的 public 方法或者属性变量。

迪米特法则的核心观念就是降低类间耦合。每个类尽量减少对其他类的依赖,因此,很容易使得系统的功能模块功能独立,相互之间不存在(或很少)依赖关系。

狭义的迪米特法则
如果两个类不必彼此直接通信,那么两个类就不应该发生直接的相互作用,如果其中一个类必须调用另一个类的某些方法,可以通过第三者转发这个调用。

尽量减少 GetA().GetB().GetC() 此种调用。

朋友界定
(1) 当前对象自身(this)
(2) 以参数形式传入到当前对象方法中的对象
如下 B b 是 A 的朋友

    public class A
    {
        public void SetB(B b)
        {   }
    }

    public class B
    {   }

(3) 当前对象的实例变量直接引用的对象
如下 C 引用 B对象, B b 是 C 的朋友

    public class B
    {
    }

    public class C
    {
        private B b;
    }

(4) 当前对象的实例变量如果是一个聚集,那么聚集中的元素也都是朋友
D 类中变量 cList 是C类的一个聚集,则聚集中的所有C类对象都是D类对象的朋友

    public class C
    {
        private B b;
    }

    public class D
    {
        private List<C> cList = new List<C>();
    }

(5) 当前对象所创建的对象
E 类对象方法 CreateD() 创建的是 D 类对象,创建的 D类对象 d 是 E 类对象的朋友

    public class D
    {
        private List<C> cList = new List<C>();
    }

    public class E
    {
        public D CreateD()
        {
            D d = new D();
            return d;
        }
    }

狭义迪米特法则的缺点:
(1) 系统中出现大量小方法,这些方法仅仅是传递间接的调用,与系统的业务逻辑无关
(2) 遵循类之间的迪米特法则会是一个系统的局部设计简化,因为每一个局部都不会和远距离的对象有之间的交互,但是这也造成系统的不同模块间的通讯效率降低,也会是系统的不同模块之间不容易协调。

外观模式、中介者模式就是迪米特法则的应用

广义的迪米特法则在类的设计上的体现:
(1) 优先考虑将一个类设计成不变类
(2) 尽量降低一个类的访问权限:如将类的访问权限限定在一个包、命名空间内
(3) 尽量降低成员的访问权限:如合理使用public、protected、private

下面以一个实例展示如何遵循迪米特法则
有一个设计公司
一个部门的负责人是 项目经理,项目经理管理部门内的 程序人员、美术人员、产品设计人员
一个客户,客户应该只负责跟项目经理提需求,项目经理根据需求将工作任务安排给不同人员

类比到迪米特法则中
项目经理的朋友们: 程序人员、美术人员、产品设计人员
客户的朋友:项目经理
客户 跟 程序人员、美术人员、产品设计人员 是陌生人
正常情况下,客户类对象是不允许访问、调用 程序人员、美术人员、产品设计人员 对象的

代码实现如下

// 添加命名空间,限制访问权限
namespace Company
{
    // 项目经理
    public class PM
    {
        // 引用程序人员,不允许通过 PM 对象访问该变量
        private Program _program;
        // 引用美术人员,不允许通过 PM 对象访问该变量
        private Art _art;
        // 引用产品人员,不允许通过 PM 对象访问该变量
        private Product _product;

        public PM()
        {
            // 直接在内部创建对象了
            Program program = new Program();
            SetProgram(program);

            Art art = new Art();
            SetArt(art);

            Product product = new Product();
            SetProduct(product);
        }

        // 添加引用对象
        public void SetProgram(Program program)
        {
            _program = program;
        }

        // 添加引用对象
        public void SetArt(Art art)
        {
            _art = art;
        }

        // 添加引用对象
        public void SetProduct(Product product)
        {
            _product = product;
        }

        // 需求调用
        public void DoSomething(string msg)
        {
            if (msg.CompareTo("programDemand") == 0)
            {
                _program.DoSomething(msg);
            }
            else if (msg.CompareTo("artDemand") == 0)
            {
                _art.DoSomething(msg);
            }
            else if (msg.CompareTo("productDemand") == 0)
            {
                _product.DoSomething(msg);
            }
        }
    }

    // 程序人员
    public class Program
    {
        // 需求调用
        public void DoSomething(string msg)
        {
            Console.WriteLine("程序人员:" + msg);
        }
    }

    // 美术人员
    public class Art
    {
        // 需求调用
        public void DoSomething(string msg)
        {
            Console.WriteLine("美术人员:" + msg);
        }
    }

    // 产品设计人员
    public class Product
    {
        // 需求调用
        public void DoSomething(string msg)
        {
            Console.WriteLine("产品设计人员:" + msg);
        }
    }
}

客户类实现如下

// 添加命名空间,限制访问权限
namespace Client
{
    public class Client
    {
        public Client()
        {
            Company.PM pM = new Company.PM();

            pM.DoSomething("programDemand");
            pM.DoSomething("artDemand");
            pM.DoSomething("productDemand");
        }
    }
}

测试结果如下
设计模式6大原则-迪米特法则_第1张图片

你可能感兴趣的:(设计模式,迪米特法则,最少知识原则,设计模式6大原则)