什么是迪米特法则
迪米特法则(Law of Demeter)又叫作最少知识原则(The Least Knowledge Principle),一个类对于其他类知道的越少越好,就是说一个对象应当对其他对象有尽可能少的了解,只和朋友通信,不和陌生人说话。英文简写为: LOD。
迪米特法则在工厂模式的应用
先来看一个简单的列子,咖啡和咖啡馆,咖啡馆可以点很多种类的咖啡,有美式咖啡,拿铁咖啡等。万物皆对象,咖啡是一个抽象对象,咖啡馆以及不同种类的咖啡是一个具体的对象,而咖啡馆负责包装好咖啡在把咖啡送上去,我们用代码来实现这个过程吧!
public abstract class Caffee {
public abstract void GetCoffeMsg();//获取咖啡信息
}
public class CaffeeAmeric extends Caffee{
@Override
public void GetCoffeMsg() {
System.out.println("这是美式咖啡");
}
}
public class CafeeLatte extends Caffee{
@Override
public void GetCoffeMsg() {
System.out.println("这是拿铁咖啡");
}
}
public class CaffeeStore {
/**
* 模拟咖啡店对咖啡的包装
* @param caffee
*/
public void addSugar(Caffee caffee){
System.out.println("咖啡店正在给咖啡加糖");
}
/**
* 点咖啡
* @param name 咖啡种类,这里用字符串代替
*/
public void OrderCaffee(String name){
Caffee caffee=null;
if("美式".equals(name)){
caffee=new CaffeeAmeric();
}else if("拿铁".equals(name)){
caffee=new CafeeLatte();
}else{
System.out.println("抱歉,没有这种咖啡 Exception");
return;
}
this.addSugar(caffee);
caffee.GetCoffeMsg();
}
//测试代码
public static void main(String[] args) {
CaffeeStore caffeeStore=new CaffeeStore();
caffeeStore.OrderCaffee("美式");
caffeeStore.OrderCaffee("拿铁");
}
}
代码能正常运行,但是这样有一种弊端,万一我们要引入一种新种类咖啡,就得修改CaffeeStore的代码,很容易看出来咖啡店和咖啡之间的耦合很高,如果代码量大了,程序员也很难进行扩展。农夫山泉不是有一句名言吗—我们不生产水,我们只是大自然的搬运工,同理咖啡店不应该生产咖啡,咖啡店只负责搬运咖啡(很少有饭店会自己产量,然后出来卖吧),所以生产咖啡的活,就应该交给工厂
public class CaffeFactory {
public static Caffee getCaffee(String name){
Caffee caffee=null;
if("美式".equals(name)){
caffee=new CaffeeAmeric();
}else if("拿铁".equals(name)){
caffee=new CafeeLatte();
}else{
System.out.println("抱歉,没有这种咖啡 Exception");
return null;
}
return caffee;
}
}
public class CaffeeStore {
/**
* 模拟咖啡店对咖啡的包装
* @param caffee
*/
public void addSugar(Caffee caffee){
System.out.println("咖啡店正在给咖啡加糖");
}
/**
* 点咖啡
* @param name 咖啡种类,这里用字符串代替
*/
public void OrderCaffee(String name){
Caffee caffee=CaffeFactory.getCaffee(name);
this.addSugar(caffee);
caffee.GetCoffeMsg();
}
//测试代码
public static void main(String[] args) {
CaffeeStore caffeeStore=new CaffeeStore();
caffeeStore.OrderCaffee("美式");
caffeeStore.OrderCaffee("拿铁");
}
}
这样我们就把耦合转移给工厂了,生产咖啡的事,就交给工厂,这样还是有弊端,虽然遵守了迪米特法则,但是违背了开闭原则:只扩展,不修改,我们加种类,还是要修改工厂的代码,我们联系生活实际想想,一个大厂是许许多多小厂组成的,工厂只是一个抽象的概念,比如一个汽车工厂,他就有螺丝钉工厂,引擎工厂等,让一个厂干那么多事,资本家看了都说资本家。直接上代码吧!
public interface CaffeFactory {
Caffee getCaffee();
}
public class CaffeeAmericFactory implements CaffeFactory{
@Override
public Caffee getCaffee() {
return new CaffeeAmeric();
}
}
public class CafeeLatteFactory implements CaffeFactory{
@Override
public Caffee getCaffee() {
return new CafeeLatte();
}
}
public class CaffeeStore {
CaffeFactory caffeFactory;
public void setCaffeFactory(CaffeFactory caffeFactory) {
this.caffeFactory = caffeFactory;
}
/**
* 模拟咖啡店对咖啡的包装
* @param caffee
*/
public void addSugar(Caffee caffee){
System.out.println("咖啡店正在给咖啡加糖");
}
/**
* 点咖啡
*/
public void OrderCaffee(){
Caffee caffee=caffeFactory.getCaffee();
this.addSugar(caffee);
caffee.GetCoffeMsg();
}
//测试代码
public static void main(String[] args) {
CaffeeStore caffeeStore=new CaffeeStore();
CafeeLatteFactory cafeeLatteFactory=new CafeeLatteFactory();
CaffeeAmericFactory caffeeAmericFactory=new CaffeeAmericFactory();
caffeeStore.setCaffeFactory(cafeeLatteFactory);
caffeeStore.OrderCaffee();
caffeeStore.setCaffeFactory(caffeeAmericFactory);
caffeeStore.OrderCaffee();
}
}
这样构建,程序员就只需要扩展类和工厂就行了,不用为了添加新品种,而去修改太多代码,看起来是多此一举,但实际上提供了许多便利,使咖啡和咖啡馆的耦合度大大降低