您的位置:首页 > 其它

设计模式笔记(五)设计六大原则之五--迪米特法则

2017-11-09 20:58 615 查看
也叫最少知道原则,Least Knowledge Principle

定义

一个对象应该对其他对象有最少的了解,通俗的讲,一个类应该对自己需要耦合或调用的类知道得最少,被耦合或调用的类的内部是多么复杂和我没有关系,我只要知道提供的public方法,就知道这么多,其他的都不关心。

四层含义

迪米特法则对类的低耦合提出了明确的要求

只和直接的朋友交流

两个对象之间的耦合成为朋友关系。

举个栗子:

老师向体育委员发命令,让他清点女生人数

/*
* 老师类
*/
public class Teacher {
//老师对学生发布命令,清点一下女生
public void commond(GroupLeader groupLeader) {
List<Girl> listGirl = new ArrayList<Girl>();
//初始化女生
for (int i = 0;i<20;i++) {
listGirl.add(new Girl());

}

//告诉体育委员开始执行清查任务
groupLeader.countGirls(listGirl);
}
}


/*
* 体育委员
*/
public class GroupLeader {
//清查女生数量
public void countGirls(List<Girl> listGirls) {
System.out.println("女生的数量是:"+listGirls.size());
}
}


/*
* 女生
*/
public class Girl {

}


/*
* 模拟老师命令体育委员清点女生人数场景
*/
public class Client {
public static void main(String[] args) {
Teacher teacher = new Teacher();
//老师发布命令
teacher.commond(new GroupLeader());
}
}


发现Teacher的直接朋友是GroupLeader但是方法间却用了不是直接朋友的对象Girl,commond方法时teacher的方法,teacher却不知道自己与Girl有了依赖,这是不允许的。

现在要将这个依赖关系去掉。

/*
* 老师类
*/
public class Teacher {
//老师对学生发布命令,清点一下女生
public void commond(GroupLeader groupLeader) {
//告诉体育委员开始执行清查任务
groupLeader.countGirls();
}
}


/*
* 体育委员
*/
public class GroupLeader {
private List<Girl> listGirls ;
public GroupLeader(List<Girl> listGirls ) {
this.listGirls = listGirls;
}
//清查女生数量
public void countGirls() {
System.out.println("女生的数量是:"+this.listGirls.size());
}
}


/*
* 模拟老师命令体育委员清点女生人数场景
*/
public class Client {
public static void main(String[] args) {
//女生群体
List<Girl> listGirls = new ArrayList<Girl>();
Teacher teacher = new Teacher();
//老师发布命令
teacher.commond(new GroupLeader(listGirls));
}
}


避开了Teacher类对陌生类的访问,降低了耦合性,提高了系统的健壮性。

朋友间是有距离的

类之间的耦合关系不能过于牢固,即使是朋友之间也不能无话不说。

举个栗子:

/*
* 模拟安装软件动作,根据向导,第一个动作完毕下一个动作运行
*/
public class InstallSoftware {
public void installWizard(Wizard wizard) {
int first = wizard.first();
if(first > 50) {
int second = wizard.second();
if(second>50) {
int third = wizard.third();
if(third > 50) {
wizard.first();
}
}
}
}
}


/*
* 向导类
*/
public class Wizard {
private Random rand = new Random(System.currentTimeMillis());

//第一步
public int first() {
System.out.println("执行第一个方法");
return rand.nextInt(100);
}

//第二步
public int second() {
System.out.println("执行第二个方法");
return rand.nextInt(100);
}

//第三步
public int third() {
System.out.println("执行第三个方法");
return rand.nextInt(100);
}
}


/*
* 场景类
*/
public class ClientForInstall {
public static void main(String[] args) {
InstallSoftware invoker = new InstallSoftware();
invoker.installWizard(new Wizard());
}
}


如果Wizard类中first方法返回值变了,那么InstallSoftware类也要发生变化,这样过于依赖了。

可以让public的方法减少,让private或者protected的方法多一些。

修改后:

/*
* 模拟安装软件动作,根据向导,第一个动作完毕下一个动作运行
*/
public class InstallSoftware {
public void installWizard(Wizard wizard) {
wizard.installWizard();
}
}


/*
* 向导类
*/
public class Wizard {
private Random rand = new Random(System.currentTimeMillis());

//第一步
private int first() {
System.out.println("执行第一个方法");
return rand.nextInt(100);
}

//第二步
private int second() {
System.out.println("执行第二个方法");
return rand.nextInt(100);
}

//第三步
private int third() {
System.out.println("执行第三个方法");
return rand.nextInt(100);
}

//软件安装过程
public void installWizard() {
int first = this.first();
if(first > 50) {
int second = this.second();
if(second>50) {
int third = this.third();
if(third > 50) {
this.first();
}
}
}
}
}


是自己的就是自己的

如果一个方法放在本类中不增加类间关系,对本类不产生负面影响,那么就放在本类中。

谨慎使用Serializable

如果一个项目使用了远程方法调用,这个对象就必须实现Serializable接口,也就是需要把网络传输的对象序列化,否则就会出现异常。突然,客户端的VO修改了一个属性的访问权限,private变为public访问权限变大了,如果程序上没有变更,就会报序列化失败。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: