在咱们刚开始学习编程的时候,一般会将全部的方法都声明为public,例如:html
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("酸辣土豆丝");
}
}
复制代码
客人类。编程
这样作好很差?bash
你们能够先思考下。app
咱们先来看一下迪米特法则的定义。学习
又称为最少知识原则。优化
一个软件实体应当尽量少地与其余实体发生相互做用。ui
这个比较好理解,一个类尽量少的与其余的类产生关联,低耦合,高内聚嘛。spa
迪米特法则包含两种角色:依赖者与被依赖者。code
咱们回到疑惑中的问题,Chef类好很差?
首先,Chef类的角色是被依赖者。
它暴露了flavour属性,这是存在问题的,有哪一个厨师愿意把本身的独家配方公开出去啊。
并且它还暴露了依赖者并不关心cookingTomato、cookingPotato两个方法。
对于依赖者来讲,我只须要调用cooking方法就能够了,至于菜具体怎么作,就与我无关了。
而且暴露的话,程序员也容易懵逼,这两个方法是干吗的?我要不要研究下?
因此,
从被依赖者的角度来讲:只暴露应该暴露的方法或者属性。
有个简单的套路:
能够用private就毫不用protected,能够用protected就毫不用public。
那Client类总没什么问题了吧。
确实,乍一看感受没有任何问题的,再乍乍一看仍是感受没有问题。。。
它的不合适不是从语法调用方面看的,而是从依赖关系。
客人是不能够直接依赖厨师的,而应该依赖服务员。
在实际项目中,极可能会存在客人类依赖了厨师类、服务员类,而服务员类又依赖了厨师类。
这会让代码很是混乱,也违背了迪米特法则。
因此,
从依赖者的角度来讲:只依赖应该依赖的对象。
咱们按照迪米特法则优化下代码。
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
先放葱姜蒜
再放土豆丝
...
酸辣土豆丝出锅
酸辣土豆丝上桌啦,请您品尝!
复制代码
运行结果。
下降风险
避免不应暴露的方法或者属性暴露,从而规避风险。
避免依赖关系过于混乱。
接下来,请您欣赏迪米特法则的原创歌曲。
嘻哈说:迪米特法则
做曲:懒人
做词:懒人
Rapper:懒人
哥们是个大厨
身材有些发福
您可让我作饭甚至是打卤
但您无权知晓我具体是油煎炸煮
这是个人秘密才能把客人抓住
这就是最小知识原则的迪米特法则
一个实体尽少与其余产生瓜葛
依赖者只依赖应该依赖的对象绝对能够减小bug
被依赖者只暴露该暴露的属性还有方法呢
把风险被下降绝对不多是假的
复制代码
闲来无事听听曲,知识已填脑中去;
学习复习新方式,头戴耳机不小觑。
番茄课堂,学习也要酷。