美文网首页
嘻哈说:设计模式之迪米特法则

嘻哈说:设计模式之迪米特法则

作者: 番茄课堂_懒人 | 来源:发表于2018-08-30 08:53 被阅读0次
    嘻哈说-设计模式

    1、疑惑

    在我们刚开始学习编程的时候,通常会将所有的方法都声明为public,例如:

    package com.fanqiekt.principle.lod;
    
    /**
     * 厨师
     *
     * @author 番茄课堂-懒人
     */
    public class Chef{
        public String flavour = "秘制调料XXX";
    
        /**
         * 做饭
         * @param dishName 下单的菜名
         */
        public void cooking(String dishName) {
            System.out.println("开始烹饪:"+dishName);
    
            switch (dishName){
                case "西红柿炒鸡蛋":
                    cookingTomato();
                    break;
                case "酸辣土豆丝":
                    cookingPotato();
                    break;
            }
    
            System.out.println(dishName + "出锅");
        }
    
        /**
         * 炒西红柿鸡蛋
         */
        public void cookingTomato() {
            System.out.println("放入调料:" + flavour);
            System.out.println("先炒鸡蛋");
            System.out.println("再炒西红柿");
            System.out.println("...");
        }
    
        /**
         * 炒酸辣土豆丝
         */
        public void cookingPotato() {
            System.out.println("放入调料:" + flavour);
            System.out.println("先放葱姜蒜");
            System.out.println("再放土豆丝");
            System.out.println("...");
        }
    }
    

    厨师类。

    package com.fanqiekt.principle.lod;
    
    /**
     * 客人
     * @Author: 番茄课堂-懒人
     */
    public class Client {
        public static void main(String[] args){
            Chef chef = new Chef();
            chef.cooking("西红柿炒鸡蛋");
            System.out.println("-------");
            chef.cooking("酸辣土豆丝");
        }
    }
    

    客人类。

    这样做好不好?

    大家可以先思考下。

    2、定义

    我们先来看一下迪米特法则的定义。

    又称为最少知识原则

    一个软件实体应当尽可能少地与其他实体发生相互作用。

    这个比较好理解,一个类尽可能少的与其他的类产生关联,低耦合,高内聚嘛。

    迪米特法则包含两种角色:依赖者与被依赖者。

    3、含义

    我们回到疑惑中的问题,Chef类好不好?

    首先,Chef类的角色是被依赖者。

    它暴露了flavour属性,这是存在问题的,有哪个厨师愿意把自己的独家配方公开出去啊。

    而且它还暴露了依赖者并不关心cookingTomato、cookingPotato两个方法。

    对于依赖者来说,我只需要调用cooking方法就可以了,至于菜具体怎么做,就与我无关了。

    并且暴露的话,程序员也容易懵逼,这两个方法是干嘛的?我要不要研究下?

    所以,

    从被依赖者的角度来说:只暴露应该暴露的方法或者属性。

    有个简单的套路:

    可以用private就绝不用protected,可以用protected就绝不用public

    那Client类总没什么问题了吧。

    确实,乍一看感觉没有任何问题的,再乍乍一看还是感觉没有问题。。。

    它的不合适不是从语法调用方面看的,而是从依赖关系。

    客人是不可以直接依赖厨师的,而应该依赖服务员。

    在实际项目中,很可能会存在客人类依赖了厨师类、服务员类,而服务员类又依赖了厨师类。

    这会让代码非常混乱,也违背了迪米特法则。

    所以,

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

    4、代码

    我们按照迪米特法则优化下代码。

    package com.fanqiekt.principle.lod;
    
    /**
     * 厨师
     *
     * @author 番茄课堂-懒人
     */
    public class Chef{
        private String flavour = "秘制调料XXX";
    
        /**
         * 做饭
         * @param dishName 下单的菜名
         */
        public void cooking(String dishName) {
            System.out.println("开始烹饪:"+dishName);
    
            switch (dishName){
                case "西红柿炒鸡蛋":
                    cookingTomato();
                    break;
                case "酸辣土豆丝":
                    cookingPotato();
                    break;
            }
    
            System.out.println(dishName + "出锅");
        }
    
        /**
         * 炒西红柿鸡蛋
         */
        private void cookingTomato() {
            System.out.println("放入调料:" + flavour);
            System.out.println("先炒鸡蛋");
            System.out.println("再炒西红柿");
            System.out.println("...");
        }
    
        /**
         * 炒酸辣土豆丝
         */
        private void cookingPotato() {
            System.out.println("放入调料:" + flavour);
            System.out.println("先放葱姜蒜");
            System.out.println("再放土豆丝");
            System.out.println("...");
        }
    }
    

    flavour声明为private,其他类就不可访问了,避免泄漏秘制调料。

    cookingTomato、cookingPotato声明为private

    cooking需要依赖者调用,所以依旧为public。

    package com.fanqiekt.principle.lod;
    
    /**
     * 服务员
     *
     * @author 番茄课堂-懒人
     */
    public class Waiter {
        private Chef chef = new Chef();
    
        /**
         * 点餐
         * @param dishName 餐名
         */
        public void order(String dishName) {
            System.out.println("客人点餐:"+dishName);
    
            chef.cooking(dishName);
    
            System.out.println(dishName+"上桌啦,请您品尝!");
        }
    }
    

    服务员类,依赖了Chef对象,并声明为private。

    package com.fanqiekt.principle.lod;
    
    /**
     * 客人
     * @Author: 番茄课堂-懒人
     */
    public class Client {
        public static void main(String[] args){
            Waiter waiter = new Waiter();
            waiter.order("西红柿炒鸡蛋");
            System.out.println("-------");
            waiter.order("酸辣土豆丝");
        }
    
    }
    

    客人类,依赖了Waiter类。。

    客人点餐:西红柿炒鸡蛋
    开始烹饪:西红柿炒鸡蛋
    放入调料:秘制调料XXX
    先炒鸡蛋
    再炒西红柿
    ...
    西红柿炒鸡蛋出锅
    西红柿炒鸡蛋上桌啦,请您品尝!
    -------
    客人点餐:酸辣土豆丝
    开始烹饪:酸辣土豆丝
    放入调料:秘制调料XXX
    先放葱姜蒜
    再放土豆丝
    ...
    酸辣土豆丝出锅
    酸辣土豆丝上桌啦,请您品尝!
    

    运行结果。

    5、优点

    降低风险

    避免不该暴露的方法或者属性暴露,从而规避风险。

    避免依赖关系过于混乱。

    6、嘻哈说

    接下来,请您欣赏懒人为迪米特法则创作的歌曲。

    嘻哈说:迪米特法则
    作曲:懒人
    作词:懒人
    Rapper:懒人
    
    哥们是个大厨
    身材有些发福
    您可以让我做饭甚至是打卤
    但您无权知晓我具体是油煎炸煮
    这是我的秘密才能把客人抓住
    这就是最小知识原则的迪米特法则
    一个实体尽少与其他产生瓜葛
    依赖者只依赖应该依赖的对象绝对可以减少bug
    被依赖者只暴露该暴露的属性还有方法呢
    把风险被降低绝对不可能是假的
    

    试听请点击这里

    闲来无事听听曲,知识已填脑中去;

    学习复习新方式,头戴耳机不小觑。

    番茄课堂,学习也要酷。

    相关文章

      网友评论

          本文标题:嘻哈说:设计模式之迪米特法则

          本文链接:https://www.haomeiwen.com/subject/qdjkwftx.html