Home  >  Article  >  Backend Development  >  Summary of the five principles of PHP object-oriented design (SOLID)

Summary of the five principles of PHP object-oriented design (SOLID)

不言
不言Original
2018-07-13 15:58:592184browse

This article mainly introduces the summary of the five principles of PHP object-oriented design (SOLID), which has certain reference value. Now I share it with you. Friends in need can refer to it

PHP Design Principles To sort it out, refer to "PHP Core Technology and Best Practices", "Agile Development Principles, Patterns and Practices", the article Five Principles of PHP Object-Oriented Design, Design Pattern PrinciplesSOLID

Single Responsibility Principle, SRP)

Definition/Features
  • There is only one reason for a class change

  • A class has only one responsibility (Responsibility: reason for change)

  • Avoid the same responsibilities being spread to different classes and duplication of functions

Problems
  • A class has too many responsibilities, and multiple responsibilities are interdependent. The change of one responsibility will affect the ability of this class to complete other responsibilities. When the cause of the class change occurs, it will suffer unexpected consequences. Destruction

Advantages of adhering to SPR principles
  • Reduce coupling between classes: When requirements change, only modify one Class, thereby isolating the impact of changes on other responsibilities caused by the class

  • Improving the reusability of classes: Reference on demand, one class is responsible for one responsibility, requirements Changes only require modifying the corresponding class or adding a certain responsibility

  • Reduce the complexity of the class: Single responsibility, decentralized functions Reduce one class to multiple responsibility classes Complexity

Code example
class ParseText
{
    private $content;
    
    public function decodeText(String $content)
    {
        // TODO: decode content
    }
    
    public function saveText()
    {
        // TODO:: save $this->content;
    }
}
/*
问题思考:
解析的文本类型会有多种-html、xml、json
保存的文本也会有多种途径-redis、mysql、file
客户端只需要解析文本时必须会引入saveText不需要的方法
两个职责之间没有强烈的依赖关系存在
任意职责需求变化都需要更改这个类
*/

/*
符合SRP的设计
职责拆分
*/

class Decoder
{
    private $content;
    
    public function decodeText(String $content)
    {
    // TODO: decode content
    }
    
    public function getText()
    {
        return $this->content;
    }
}

class Store
{
    public function save($content)
    {
        // TODE: save
    }
}
Summary

Much of what software design does is discovering responsibilities and reasonably separating the relationships between responsibilities. If changes to the application always affect multiple responsibilities at the same time, there is no need to separate responsibilities.

Interface Segregation Principle ISP

Problem

When designing an application, the interface of the class is not cohesive. Different clients only contain some centralized functions, but the system will force the client to implement all methods in the module, and also write some dumb methods. Such an interface becomes a fat interface or interface pollution. Such an interface will introduce some inappropriate behaviors into the system, waste resources, affect other client programs, enhance coupling, etc.

ISP Definition/Features

  • Clients should not be forced to rely on methods/functions they do not need

  • The dependence of a class on a class should be based on the smallest interface

  • The implementation class of the interface should only be presented as the single responsibility principle

Advantages of following the ISP principle
  • will Fat interface separation, each group of interfaces provides specific functions to serve a specific group of client programs

  • Changes to one group of interfaces will not/minorly affect other interfaces/ Client program to ensure the purity of the interface

Solution

  • The fat interface is decomposed into multiple client-specific interfaces/multiple interfaces are separated and inherited

  • Using the delegation separation interface, two objects participate in processing the same request, and the object accepting the request delegates the request to another object for processing

Code Example
/*
* 公告接口
*/
interface Employee
{
    public function startWork();
    public function endWork();
}

/*
* 定义特定客户端接口
*/
interface Coder
{
    public function writeCode();
}

interface Ui
{
    public function designPage();
}

class CoderClient implements Employee, Coder
{
    public function startWork()
    {
        //TODO:: start work time
    }
    public function endWork()
    {
        //TODO:: end work time
    }
    
    public function writeCode()
    {
        //TODO:: start write code
        return 'hellow world';
    }
}
$c = new CoderClient();
echo $c->writeCode();
Summary

Fat classes can lead to abnormal and harmful coupling relationships between their client programs. By decomposing thick clients into multiple client-specific interfaces, clients are tightly dependent on the methods they actually call, thus detaching the dependencies between clients and methods they do not call. Interface isolation should be kept small and infrequent.

Comparison between SRP and ISP
  • Both solve the dependency principle in software design

  • SRP focuses on the division of responsibilities, mainly Constraint classes are actually interfaces and methods, which are the details and implementation in the program. ISP focuses on the isolation of interfaces and restricts the interfaces. It abstracts the design of interfaces from a more macro perspective

Open-Close Principle OCP

Problem

As the scale of software systems continues to expand, the complexity of system maintenance and modification continues to increase. Changes in one part of the system often affect other modules. Correct application of OCP principles can solve such problems.

Definition/Characteristics
  • A module should be open in terms of extending behavior and closed in terms of changeability

Follow OCP advantages
  • The behavior of the module is extensible, and the behavior/function of the existing module can be easily extended

  • Extensions to module behavior will have little/little impact on existing systems/modules

Code examples
/*
* 定义有固定行为的抽象接口
*/
interface Process
{
    public function action(String $content);
}

/*
* 继承抽象接口,扩展不同的行为
*/
class WriteToCache implements Process
{
    public function action(String $content)
    {
        return 'write content to cache: '.$content;
    }
}

class ParseText
{
    private $content;
    public function decodeText($content)
    {
        $this->content = $content;
    }
    
    public function addAction(Process $process)
    {
        if ($process instanceof Process) {
            return $process->action($this->content);    
        }
    }
}

$p = new ParseText();
$p->decodeText('content');
echo $p->addAction(new WriteToCache());
Summary

The core idea of ​​OCP is abstraction Interface programming, abstraction is relatively stable. Let classes depend on fixed abstractions, let classes inherit abstractions through object-oriented inheritance and polymorphism, and overwrite their methods or inherent behaviors. This is to think of new extension methods/functions and achieve extensions.

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

问题

面向对象中大量的继承关系十分普遍和简单,这种继承规则是什么,最佳的继承层次的规则又是什么,怎样优雅的设计继承关系,子类能正确的对基类中的某些方法进行重新,这是LSP原则所要处理的问题。

定义/特性
  • 子类必须能够替换掉他们的基类型:任何出现基类的地方都可以替换成子类并且客户端程序不会改变基类行为或者出现异常和错误,反之不行。

  • 客户端程序只应该使用子类的抽象父类,这样可以实现动态绑定(php多态)

违反LSP原则

假设一个函数a,他的参数引用一个基类b,c是b的派生类,如果将c的对象作为b类型传递给a,会导致a出现错误的行为,那没c就违法了LSP原则。

/*
* 基类
*/
class Computer
{
    public function action($a, $b)
    {
        return $a+$b;
    }
}
/*
* 子类复习了父类方法,改变了action 的行为
* 违反了LSP原则
*/
class Client extends Computer
{
    public function action($a, $b)
    {
        return $a-$b;
    }  
}

function run(Computer $computer, $a, $b) {
    return $computer->action($a, $b);
}

echo run((new Client()), 3, 5);
总结

LSP是OCP得以应用的最主要的原则之一,正是因为子类性的可替换行是的基类类型在无需修改的情况下扩展功能。

依赖倒置原则(Depend Inversion Principle DIP)

问题

软件开发设计中,总是倾向于创建一些高层模块依赖底层模块,底层模块更改时直接影响到高层模块,从而迫使他们改变。DIP原则描述了高层次模块怎样调用低层次模块。

定义/特性
  • 高层模块不应该依赖与底层模块,二者都应该依赖于抽象

  • 抽象不应该依赖与细节,细节应该依赖于抽象

代码示例
interface Arithmetic
{
    //public function sub($a, $b);
}

class Client
{
    
    public function computer(Arithmetic $arithmetic, $a, $b)
    {
        return $arithmetic->add($a, $b);
    }
}

class Addition implements Arithmetic
{
    public function add($a, $b)
    {
        return $a + $b;
    }
}

$c = new Client();
echo $c->computer(new Addition(), 2, 3);

/*
client 高层类 依赖于Arithmetic,Addition底层实现细节类实现Arithmetic接口,达到二者依赖于抽象接口的DIP设计原则
*/
总结

DIP原则就是每个高层次模块定义一个它所需服务的接口声明,低层次模块实现这个接口。每个高层次类通过该抽象接口使用服务。

思考

面向对象软件开发中合理的遵循设计原则可以更好的设计代码,减少不必要的错误,提高程序的可维护性,可扩展性和稳定性。

  • 单一职责(SRP)如何正确的划分职责,类的职责单一提高代码复用性,降低耦合性

  • 接口隔离(OCP)合理划分接口功能,保证接口的专一性,纯洁性,减少依赖关系

  • 里氏替换(LSP)合理利用类的继承体系,保证真确的继承关系不被破坏

  • 依赖倒置(DIP)抽象接口编程由于抽象具体实现

  • 开放封闭(OCP)面向对象编程终极目标所达到的结果,类/模块/系统的功能行为可扩展,内部更改性是封闭的

以上就是本文的全部内容,希望对大家的学习有所帮助,更多相关内容请关注PHP中文网!

相关推荐:

对LNMP的运维追踪

The above is the detailed content of Summary of the five principles of PHP object-oriented design (SOLID). For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn