美文网首页
类的设计原则

类的设计原则

作者: birjemin | 来源:发表于2018-03-03 16:32 被阅读5次
示意图

简介

SOLID:

  • S: 单一职责原则 (SRP)
  • O: 开闭原则 (OCP)
  • L: 里氏替换原则 (LSP)
  • I: 接口隔离原则 (ISP)
  • D: 依赖反转原则 (DIP)
  • 迪米特法则

详情

单一职责原则(SRP:Single responsibility principle)

解耦和增强内聚性(高内聚,低耦合),一个类和方法的只负责一个职责

  • 示例1:一个类中一个方法职责混乱。�
class Activity
{
  public function getActivity()
  {
    if ($this->startDate < time() && $this->endDate > time()) {
      return '活动:' . $this->name . '已经在' . date('Y-m-d H:i:s', $this->startDate) . '开始';
    } else {
      return '活动:' . $this->name . '没有开始';
    }
  }
}

弊端:如果再增加条件,和输出修改,会加重逻辑。
改变为 ->

class Activity
{
  public function getActivity()
  {
    return $this->isStart ? $this->getStartWord() : $this->getEndWord();
  }
  public function isStart()
  {
    return $this->startDate < time() && $this->endDate > time();
  }
  public function getStartWord()
  {
    return '活动:' . $this->name . '已经在' . date('Y-m-d H:i:s', $this->startDate) . '开始';  
  }
  public function getNotStartWord()
  {
    return '活动:' . $this->name . '没有开始';  
  }
}
  • 示例2:类的职责混乱
class Activity
{
  public function __construct(Activity $activity)
  {
    $this->activity = $activity;
  }
  public function draw()
  {
    if ($this->isStart()) {
      return $this->draw();
    }
    throw Exception('没有开始');
  }
}

弊端:类的职责不清。抽奖和活动不应该属于同一个类
更改为->

class Activity
{
  public function __construct(Activity $activity)
  {
    $this->activity = $activity;
    $this->config = '38_festival';
  }
  public function draw()
  {
    if ($this->isStart()) {
      return $this->initDrawManage->draw();
    }
    throw Exception('没有开始');
  }
  public function initDrawManage()
  {
    !isset($this->drawManage) && $this->drawManage = new DrawManage($this->config)
    return $this->drawManage
  }
}
class DrawManage
{
  public function __construct($config)
  {
    $this->config = $config
  }
  public function draw()
  {
    ...
  }
}

开闭原则(OCP:Open/Closed Principle)

对扩展开放,对修改关闭。
与其修改别人的代码(或者老代码)不如先继承,然后更改。

  • 示例1:新增一个学生,应当采用继承的方式来做,而不是修改原有的代码
interface UserInterface
{
  public function getUserIdentify();
}
class User implements UserInterface
{
  private $identify = '先生/女士';
  public function getUserIdentify
  {
    return $this->name . $this->identify;
  }
}

改为->

interface UserInterface
{
  public function getUserIdentify();
}
class User implements UserInterface
{
  private $identify = '先生/女士';
  public function getUserIdentify
  {
    return $this->name . $this->identify;
  }
}
class Student extend User
{
  private $identify = '学生';  
}
  • 示例2:调整结构。
    增加新的角色和工种时
interface UserInterface
{
  public function getUserIdentify();
}
class User implements UserInterface
{
  private $identify = 'young';
  public function getUserIdentify()
  {
    return $this->identify;
  }
}

class Student extend User
{
  private $identify = 'student';  
}

class Work
{
  private $identify

  public function __construct(UserInterface $identify)
  {
    $this->identify = $identify;
  }

  public function getWorking()
  {
    return $this->identify->getIdentify() == 'student'
    ? $this->study() : $this->working();
  }
  public function study()
  {
    return '学习';
  }
  public function wordking()
  {
    return '工作';
  }
}

弊端:修改代码~~
更改Work类的代码->

interface UserInterface
{
  public function getUserIdentify();
  public function doing();
}
class User implements UserInterface
{
  private $identify = 'young';
  public function getUserIdentify()
  {
    return $this->identify;
  }
  public function doing()
  {
    return 'working';
  }
}

class Student extend User
{
  private $identify = 'student';
  public function  doing()
  {
    return 'study';
  }
}

class Work
{
  private $identify

  public function __construct(UserInterface $identify)
  {
    $this->identify = $identify;
  }

  public function getWorking()
  {
    return $this->identify->doing();
  }
}

里氏替换原则(LSP:Liskov Substitution Principle)

父类出现的地方子类就可以出现,且替换成子类也不会出现任何错误或者异常。

接口隔离原则 (ISP:Interface Segregation Principle)

针对接口的原则,规范如下:

  • 接口尽量小(细化业务)
  • 接口高内聚(减少对外交互,public方法少)
  • 定制服务(应单独为一个个体服务)
  • 有限设计(和第一个规范相辅相成)

示例:

interface User
{
  public function working();
  public function studing();
}
class Student implements User
{
  public function working()
  {
    // �学生不工作(假设)
    return null;
  }
  ...
}
class Worker implements User
{
  public fucntion studing
  {
    // 不学习(假设)
    return null;
  }
}

可以修改->

interface StudentInterface
{
  public function studing();
}
interface WorkerInterface
{
  public function working();
}
class Student implements StudentInterface
{
  ...
}
class Worker implements WorkerInterface
{
  ...
}

依赖反转原则 (DIP:Dependency Inversion Principle)

高层模块不应该依赖低层模块,二者都应该依赖其抽象;抽象不应该依赖细节;细节应该依赖抽象。

这个原则刚好本文的第二小节开闭原则示例1貌似就违反了,但是要看具体业务的,如果是A是父类,B是子类,具有一定的联系,无法分割就不遵循。如果A类和B类是平级关系,继承只是共用一些方法,那就有必要让两者都依赖抽象,便于该改动。

迪米特法则(Law of Demeter)

迪米特法则也叫做最少知识原则(Least Knowledge Principle,LKP),即一个对象应该对其他对象有最少的了解。不关心其他对象内部如何处理。

综述

根据实际情况使用不同的原则,可以使得程序降低耦合和冗余代码,优化程序。根据这些规则,会有一系列的设计模式,在实际使用时没必要强行套用设计模式,需要根据业务实际划分合理即可。长城不是一天就能修好的~~~

参考

  1. https://www.cnblogs.com/HouJiao/p/5459022.html
  2. https://segmentfault.com/a/1190000011662984
  3. http://blog.csdn.net/jhq0113/article/details/44907029

相关文章

  • 面向对象设计的六个基本原则的理解图

    根据类设计的几个方向做整理,方便记忆,分别是: 类自身的设计原则:开闭原则、单一职责原则 与外部相关的设计原则:接...

  • 架构设计

    设计 设计模式 设计原则:开闭原则(对扩展开放,对修改关闭)、里氏替换原则(子类可以扩展父类的功能但不能改变父类原...

  • 02 Android常见设计模式:面向对象的设计原则

    一. 类的设计原则 开闭原则里氏替换原则迪米特法则(最少知道原则)单一职责原则接口隔离原则依赖倒置原则 这几个设计...

  • 类的设计原则

    简介 SOLID: S: 单一职责原则 (SRP)O: 开闭原则 (OCP)L: 里氏替换原则 (LSP)I: 接...

  • 类的设计原则

  • 类的设计原则

    在讲述具体的设计模式之前,有必要讲解一下类的设计原则。类有六大设计原则,如下图所示: 2.1 单一职责 2.1.1...

  • 设计模式目录

    1. 设计模式中类的关系和六大设计原则 一、设计模式简介二、设计模式中类的关系三、设计模式的六大设计原则之单一职责...

  • 设计模式

    类图 各个类之间的关系时序图 设计原则 SOLIS 开闭原则(Open-Close) ​ 一个软件实体如类,...

  • 设计原则拾遗

    单一职责原则 如何理解单一职责原则? 不要设计功能大而全的类,要设计粒度小、功能单一的类 如果一个类有多个功能,会...

  • 设计模式原则管中窥豹

    设计原则 单一职责原则(SRP = Single Responsibility Principle) 一个类 ==...

网友评论

      本文标题:类的设计原则

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