设计模式—迪米特原则(LOD)

1.背景

1987年秋天由美国Northeastern University的Ian Holland提出,被UML的创始者之一Booch等普及。后来,因为在经典著作《 The Pragmatic Programmer》而广为人知。

2.概念

迪米特法则(Law of Demeter)又叫作最少知识原则(The Least Knowledge Principle),一个类对于其他类知道的越少越好,就是说一个对象应当对其他对象有尽可能少的了解,只和朋友通信,不和陌生人说话。英文简写为: LOD。

通俗的讲:

  • 不该知道的不要知道;

  • 一个类应该保持对其它对象最少的了解,只和朋友通信,不和陌生人说话;

  • 降低类之间的耦合度;

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

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

设计原则:

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

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

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

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

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

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

3.案例

需求:租客想通过中介找房子,租客想要一个20平、2000一个月的。

方案一(不满足迪米特原则):把所有房源都给租客,租客自己选

/// <summary>
    /// 房源
    /// </summary>
    public class Room
    {
        private int are;
        private int pay;

        public int getAre()
        {
            return are;
        }

        public void setAre(int are)
        {
            this.are = are;
        }

        public int getPay()
        {
            return pay;
        }

        public void setPay(int pay)
        {
            this.pay = pay;
        }
    }


/// <summary>
    /// 中介
    /// </summary>
    public class Mediator
    {
        private List<Room> allRooms = new List<Room>();
        /// <summary>
        /// 初始化房源
        /// </summary>
        public Mediator()
        {
            for (int i = 0; i < 10; i++)
            {
                Room room = new Room();
                room.setAre((i + 1) * 5);
                room.setPay((i % 4 == 0 ? 1 : i % 4) * 1000);
                allRooms.Add(room);
            }
        }

        /// <summary>
        /// 获取所有房源
        /// </summary>
        /// <returns></returns>
        public List<Room> GetAllRooms()
        {
            return allRooms;
        }
    }


/// <summary>
    /// 租客
    /// </summary>
    public class Tenant
    {
        public static void RentRoom(Mediator mediator)
        {
            // 通过中介获取所有房屋
            List<Room> allRoom = mediator.GetAllRooms();
            foreach(Room room in allRoom)
            {
                if (IsSuitable(room))
                {
                    Console.WriteLine("房屋找到了");
                }
            }
        }

        /// <summary>
        /// 判断房子是否满足客户需求
        /// </summary>
        /// <param name="room"></param>
        /// <returns></returns>
        private static bool IsSuitable(Room room)
        {
            // 筛选房屋
            return true;
        }
    }

{
        //LOD:迪米特原则
        Tenant.RentRoom(new Mediator());
    }

代码分析:

以上的方案是中介直接把所有的房源全部提供给顾客,其中就包含不满足租客条件的房源,这就增加了租客和房源直接的耦合度。

方案二(满足迪米特原则):先按照要求把房源筛选出来,给租客

/// <summary>
    /// 房源
    /// </summary>
    public class Room
    {
        private int are;
        private int pay;

        public int getAre()
        {
            return are;
        }

        public void setAre(int are)
        {
            this.are = are;
        }

        public int getPay()
        {
            return pay;
        }

        public void setPay(int pay)
        {
            this.pay = pay;
        }
    }


 /// <summary>
    /// 中介
    /// </summary>
    public class MediatorLOD
    {
        private List<Room> allRooms = new List<Room>();
        public MediatorLOD()
        {
            for (int i = 0; i < 10; i++)
            {
                Room room = new Room();
                room.setAre((i + 1) * 5);
                room.setPay((i % 4 == 0 ? 1 : i % 4) * 1000);
                allRooms.Add(room);
            }
        }

        /// <summary>
        /// 找出符合租客要求的房子
        /// </summary>
        /// <param name="are"></param>
        /// <param name="pay"></param>
        /// <returns></returns>
        public Room RentRoom(int are, int pay)
        {
            // 通过中介获取所有房屋
            foreach(Room room in allRooms)
            {
                if (IsSuitable(room, are, pay))
                {
                    return room;
                }
            }
            return null;
        }

        /// <summary>
        /// 判断房源是否满足客户的要求
        /// </summary>
        /// <param name="room"></param>
        /// <param name="are"></param>
        /// <param name="pay"></param>
        /// <returns></returns>
        private bool IsSuitable(Room room, int are, int pay)
        {
            // 筛选房屋
            return true;
        }
    }

/// <summary>
    /// 租客
    /// </summary>
    public class TenantLOD
    {
        /// <summary>
        /// 获取满足条件的房源
        /// </summary>
        /// <param name="mediator"></param>
        public static void RentRoom(MediatorLOD mediator)
        {
            Console.WriteLine(mediator.RentRoom(20, 2000));
        }
    }

 {
        //LOD:迪米特原则
        Tenant.RentRoom(new Mediator());
    }

代码分析:

相比方案一,当前方案把筛选的过程放到了租客能联系到的中介身上,中介处理房源,而租客和房源的联系微乎其微,这就利用了LOD 原则,降低了租客和房源的耦合度,租客只看到符合条件的房源就可以了。

4.优缺点

优点:

  • 降低了类之间的耦合度,使类与类之间保持松散的耦合关系;

  • 由于耦合度降低,提高了模块的相对独立性;

  • 提高类的可复用性和系统的扩展性;

缺点:

  • 迪米特法则是一种面向对象系统设计风格的一种法则,尤其适合做大型复杂系统设计指导原则。但是也会造成系统的不同模块之间的通信效率降低,使系统的不同模块之间不容易协调等。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

吉量*

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值