前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >设计模式(五):最少知识原则

设计模式(五):最少知识原则

原创
作者头像
xujjj
修改2019-07-01 10:21:28
5620
修改2019-07-01 10:21:28
举报
文章被收录于专栏:IT界的泥石流

什么是最少知识原则?

定义:类需避免了解其协作类的内部结构,应直接与他们交互。

最少知识原则的主要思想是:类之间应松耦合。类之间耦合度越低,越有利于复用。当松耦合的类被修改时,不会影响到其他类的使用。

最少知识原则可以简单归纳为以下两点:

  • 依赖者应只依赖应该依赖的对象。
  • 被依赖者应只暴露应该暴露的方法。

最少知识原则的作用?

耦合度太高的代码在项目后期升级维护中,十分容易出现修复了一个 Bug 又冒出新的一个 Bug 的问题,且代码没有重用性可言,所以我们在项目开发过程中都会强调代码的耦合度问题。

最少知识原则提倡我们在设计类的时候,尽量降低每一个成员的访问权限,只公开不得不公开的成员,做到代码高内聚。高内聚的类有助于类之间松耦合,提升类与代码的可重用性和可维护性。

遵守最少知识原则具有以下优点:

  • 降低类之间的耦合度,有助于类之间、模块之间的相对独立性。
  • 有利于代码的可重用性以及系统的拓展性。

为什么要遵守最少知识原则?

3.1、只和直接的朋友交流想法

依旧拿程序员日常工作为例,场景如下:有客户、产品经理、程序员三个角色,产品经理根据客户提出的需求整理出需求文档,程序员根据需求文档进行开发。由此新手小白设计出如下的不友好代码:

PS:这里为了简单描述,先忽略依赖倒置原则!

代码语言:javascript
复制

//客户
class Customer {
  //提出需求
  public String supplyingRequirements() {
    return "客户的需求";
  }
}
//产品经理
class ProductManager {
  //制作需求文档
  public String makingRD(Customer customer) {
    String requirements = customer.supplyingRequirements();
    return requirements + "文档";
  }
}
//程序猿类
class Programmer {
  //编程
  public String programming(ProductManager productManager) {
    Customer customer = new Customer();
    String rd = productManager.makingRD(customer);
    return "面对"+rd+"编程";
  }
}
public class Test {
  public static void main(String[] args) {
    Programmer programmer = new Programmer();
    ProductManager productManager = new ProductManager();
    System.out.println(programmer.programming(productManager));
  }
}

这不正常执行吗?为什么不友好呢?我们可以看到 Programmer 类和 ProductManager 类都和 Customer 类强耦合了,也就意味着当 Customer 类的需要变动时,使用到它的地方都要变动,且如下代码,程序员就只能给客户进行开发项目,有时候我们的项目需求是来自领导上层的,上述代码一经需求改动就不行了,很脆弱!

回归到我们的小标题:只和直接的朋友交流想法,程序员的直接朋友可见是产品经理,用户是间接的朋友,程序员不需要知道用户怎么想的,只需要对着产品经理给来的需求文档。所以代码应如下改动:

代码语言:javascript
复制

//客户
class Customer {
  //提出需求
  public String supplyingRequirements() {
    return "客户的需求";
  }
}

//产品经理
class ProductManager {
  private Customer customer;
  public Customer getCustomer() {
    return customer;
  }

  public void setCustomer(Customer customer) {
    this.customer = customer;
  }
  //制作需求文档
  public String makingRD() {
    String requirements = getCustomer().supplyingRequirements();
    return requirements + "文档";
  }
}

//程序猿类
class Programmer {
  //编程
  public String programming(ProductManager productManager) {
    String rd = productManager.makingRD();
    return "面对"+rd+"编程";
  }
}

public class Test{
  public static void main(String[] args) {
    Customer customer = new Customer();
    Programmer programmer = new Programmer();
    ProductManager productManager = new ProductManager();
    productManager.setCustomer(customer);
    System.out.println(programmer.programming(productManager));
  }
}

Programmer 类只和 ProductManager 耦合,前者只需要后者提供的需求文档即可进行开发,无需知道该需求文档是来自哪里的!从而降低了系统间的耦合,提高了系统的健壮性。

3.2、朋友之间不可太亲密

朋友之间过于亲密,彼此了解太深,就容易产生不好的影响。从代码角度来看,朋友类之间过于亲密,则会导致耦合性太强,代码不健壮。举一个领导指挥程序员工作的例子。

代码语言:javascript
复制
 //领导
class Leader {
  //指挥工作
  public void commandWork(Programmer programmer) {
    programmer.demandAnalysis();
    programmer.detailedDesign();
    programmer.coding();
    programmer.test();
  }
}

//程序员
class Programmer {
  public void demandAnalysis() {
    System.out.println("进行需求分析");
  }
  
  public void detailedDesign() {
    System.out.println("进行详细设计");
  }
  
  public void coding() {
    System.out.println("进行代码编写");
  }
  
  public void test() {
    System.out.println("进行代码测试");
  }
  
}
public class Test {
  public static void main(String[] args) {
    Leader leader = new Leader();
    Programmer programmer = new Programmer();
    leader.commandWork(programmer);
  }
}

上面代码依旧是符合需求的,先从实际角度来看,作为领导是不需要了解手下是取如何完成一件事,

他只需要结果,上述代码不符合这个条件。再从代码设计角度来看,Leader 类对 Programmer 类了解过多,以致于当 Programmer 类变动时,Leader 类 也要变动。例如 Programmer 执行工作时,只有上一个子工作完成,才能接着做下一个子工作。则 Programmer 的四个子方法返回类型都变为 boolean 类型,同时 Leader 类需要对 该子方法的返回值进行判断。修改一处代码需要改动多处地方代码,这种行为是不可取的,况且我们还有优化的方法。代码如下:

代码语言:javascript
复制
 //领导
class Leader {
  //指挥工作
  public void commandWork(Programmer programmer) {
    programmer.doWork();
  }
}

//程序员
class Programmer {
  private void demandAnalysis() {
    System.out.println("进行需求分析");
  }
  private void detailedDesign() {
    System.out.println("进行详细设计");
  }
  private void coding() {
    System.out.println("进行代码编写");
  }
  private void test() {
    System.out.println("进行代码测试");
  }
  
  public void doWork() {
    demandAnalysis();
    detailedDesign();
    coding();
    test();
  }
}
public class Test {
  public static void main(String[] args) {
    Leader leader = new Leader();
    Programmer programmer = new Programmer();
    leader.commandWork(programmer);
  }
}

我们将 Programmer 类的原有四个方法访问权限设置为 private 不对外暴露,只暴露一个工作 doWork 方法。而 Leader 类只需要调用 doWork 方法即可,无需了解细节且细节的变化也与其无关,它只关心结果。

PS:是你该做的就做,不是你该做的就别做了

最少知识原则的实现规则

在实际使用最少知识原则时,我们应该根据以下几个规则来贯彻实行。

  • 在设计类的时候,尽量降低类成员的访问权限。
  • 不暴露类的属性成员,通过提供相应的访问器(set 和 get 方法)。
  • 在对其他类的引用上,将引用其他对象的次数降到最低。
  • 在类的设计上,优先考虑将一个类设置成Final类。
  • 谨慎使用序列化功能。

要注意的是过度使用最少知识原则会使产生大量的中间逻辑代码,从而增加系统的复杂性和可维护性。所以我们在釆用最少知识原则时要反复思量,要在确保高内聚和低耦合的同时,保证系统的结构清晰。

以上就是今天《最少知识原则》的讲解,良好的代码风格需要长期不断的积累学习。各位读者大人若有问题,欢迎后台留言,我将第一时间回复!

下期文章将介绍《设计模式(六):开放封闭原则》

更多内容欢迎关注我们的微信公众号:IT界的泥石流

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 什么是最少知识原则?
  • 最少知识原则的作用?
  • 为什么要遵守最少知识原则?
  • 最少知识原则的实现规则
    • 更多内容欢迎关注我们的微信公众号:IT界的泥石流
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档