偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

PHP代碼簡(jiǎn)潔之道——SOLID原則

開(kāi)發(fā) 后端
SOLID 是Michael Feathers推薦的便于記憶的首字母簡(jiǎn)寫(xiě),它代表了Robert Martin命名的最重要的五個(gè)面對(duì)對(duì)象編碼設(shè)計(jì)原則。

[[207429]]

SOLID 是Michael Feathers推薦的便于記憶的首字母簡(jiǎn)寫(xiě),它代表了Robert Martin命名的最重要的五個(gè)面對(duì)對(duì)象編碼設(shè)計(jì)原則:

  • S: 單一職責(zé)原則 (SRP)
  • O: 開(kāi)閉原則 (OCP)
  • L: 里氏替換原則 (LSP)
  • I: 接口隔離原則 (ISP)
  • D: 依賴(lài)反轉(zhuǎn)原則 (DIP)

單一職責(zé)原則 Single Responsibility Principle (SRP)

"修改一個(gè)類(lèi)應(yīng)該只為一個(gè)理由"。人們總是易于用一堆方法塞滿(mǎn)一個(gè)類(lèi),如同我們?cè)陲w機(jī)上只能攜帶一個(gè)行李箱(把所有的東西都塞到箱子里)。這樣做的問(wèn)題是:從概念上這樣的類(lèi)不是高內(nèi)聚的,并且留下了很多理由去修改它。將你需要修改類(lèi)的次數(shù)降低到最小很重要。這是因?yàn)?,?dāng)有很多方法在類(lèi)中時(shí),修改其中一處,你很難知曉在代碼庫(kù)中哪些依賴(lài)的模塊會(huì)被影響到。

Bad:

  1. class UserSettings{     
  2.     private $user;     
  3.     public function __construct($user
  4.     {         
  5.         $this->user = $user
  6.     }     
  7.     public function changeSettings($settings) 
  8.     {         
  9.         if ($this->verifyCredentials()) {            
  10.          // ... 
  11.         } 
  12.     }     
  13.     private function verifyCredentials() 
  14.     {         
  15.     // ... 
  16.     } 
  17.  

Good:

  1. class UserAuth {     
  2. private $user;     
  3. public function __construct($user){         
  4.     $this->user = $user
  5. }     
  6. public function verifyCredentials(){         
  7.     // ... 
  8.  
  9. class UserSettings {     
  10. private $user;     
  11. private $auth;     
  12. public function __construct($user) {         
  13.   $this->user = $user;         
  14.   $this->auth = new UserAuth($user); 
  15. }     
  16. public function changeSettings($settings){         
  17.     if ($this->auth->verifyCredentials()) {             
  18.     // ... 
  19.         } 
  20.     } 
  21.  

開(kāi)閉原則 Open/Closed Principle (OCP)

正如Bertrand Meyer所述,"軟件的實(shí)體(類(lèi), 模塊, 函數(shù),等)應(yīng)該對(duì)擴(kuò)展開(kāi)放,對(duì)修改關(guān)閉。"這個(gè)原則是在說(shuō)明應(yīng)該允許用戶(hù)在不改變已有代碼的情況下增加新的功能。

Bad:

  1. abstract class Adapter{     
  2. protected $name;     
  3. public function getName(){         
  4.     return $this->name
  5. class AjaxAdapter extends Adapter{     
  6. public function __construct(){      
  7.       parent::__construct();         
  8.       $this->name = 'ajaxAdapter'
  9.  } 
  10. class NodeAdapter extends Adapter{     
  11.     public function __construct(){    
  12.         parent::__construct();         
  13.         $this->name = 'nodeAdapter'
  14.     } 
  15.     class HttpRequester{     
  16.     private $adapter;     
  17.     public function __construct($adapter) 
  18.     {         
  19.         $this->adapter = $adapter; 
  20.     }     
  21.     public function fetch($url) 
  22.     { 
  23.         $adapterName = $this->adapter->getName();         
  24.     if ($adapterName === 'ajaxAdapter') {             
  25.         return $this->makeAjaxCall($url); 
  26.         }  
  27.     elseif ($adapterName === 'httpNodeAdapter') {             
  28.         return $this->makeHttpCall($url); 
  29.         } 
  30.     }     
  31.     private function makeAjaxCall($url) 
  32.     {        // request and return promise 
  33.     }     
  34.     private function makeHttpCall($url) 
  35.     {        // request and return promise 
  36.     } 
  37.  

在上面的代碼中,對(duì)于HttpRequester類(lèi)中的fetch方法,如果我新增了一個(gè)新的xxxAdapter類(lèi)并且要在fetch方法中用到的話(huà),就需要在HttpRequester類(lèi)中去修改類(lèi)(如加上一個(gè)elseif 判斷),而通過(guò)下面的代碼,就可很好的解決這個(gè)問(wèn)題。下面代碼很好的說(shuō)明了如何在不改變?cè)写a的情況下增加新功能。

Good:

  1. interface Adapter{     
  2.     public function request($url); 
  3.     class AjaxAdapter implements Adapter{     
  4.     public function request($url) 
  5.     {        // request and return promise 
  6.     } 
  7. class NodeAdapter implements Adapter{     
  8.     public function request($url) 
  9.     {        // request and return promise 
  10.     } 
  11.     class HttpRequester{     
  12.     private $adapter;     
  13.     public function __construct(Adapter $adapter) 
  14.     {        $this->adapter = $adapter; 
  15.     }     
  16.     public function fetch($url) 
  17.     {        return $this->adapter->request($url); 
  18.     } 
  19.  

里氏替換原則 Liskov Substitution Principle (LSP)

對(duì)這個(gè)概念***的解釋是:如果你有一個(gè)父類(lèi)和一個(gè)子類(lèi),在不改變?cè)薪Y(jié)果正確性的前提下父類(lèi)和子類(lèi)可以互換。這個(gè)聽(tīng)起來(lái)讓人有些迷惑,所以讓我們來(lái)看一個(gè)經(jīng)典的正方形-長(zhǎng)方形的例子。從數(shù)學(xué)上講,正方形是一種長(zhǎng)方形,但是當(dāng)你的模型通過(guò)繼承使用了"is-a"的關(guān)系時(shí),就不對(duì)了。

Bad:

  1. class Rectangle{     
  2.     protected $width = 0;     
  3.     protected $height = 0;     
  4.     public function render($area) 
  5.     {        // ... 
  6.     }     
  7.     public function setWidth($width) 
  8.     {        $this->width = $width; 
  9.     }     
  10.     public function setHeight($height) 
  11.     {        $this->height = $height; 
  12.     }     
  13.     public function getArea() 
  14.     {        return $this->width * $this->height; 
  15.     } 
  16. class Square extends Rectangle{     
  17.     public function setWidth($width) 
  18.     {         
  19.         $this->width = $this->height = $width; 
  20.     }     
  21.     public function setHeight(height) 
  22.     {        $this->width = $this->height = $height; 
  23.     } 
  24. function renderLargeRectangles($rectangles){     
  25.     foreach ($rectangles as $rectangle) { 
  26.         $rectangle->setWidth(4); 
  27.         $rectangle->setHeight(5); 
  28.         $area = $rectangle->getArea(); // BAD: Will return 25 for Square. Should be 20. 
  29.         $rectangle->render($area); 
  30.     } 
  31.  
  32. $rectangles =  
  33. [new Rectangle(), new Rectangle(), new Square()]; 
  34. renderLargeRectangles($rectangles);  

Good:

  1. abstract class Shape{     
  2.     protected $width = 0;     
  3.     protected $height = 0;     
  4.     abstract public function getArea();     
  5.     public function render($area)    {        // ... 
  6.     } 
  7. class Rectangle extends Shape{     
  8.     public function setWidth($width) 
  9.     {        $this->width = $width; 
  10.     }     
  11.     public function setHeight($height) 
  12.     {        $this->height = $height; 
  13.     }     
  14.     public function getArea() 
  15.     {        return $this->width * $this->height; 
  16.     } 
  17. class Square extends Shape{     
  18.     private $length = 0;     
  19.     public function setLength($length) 
  20.     {        $this->length = $length; 
  21.     }     
  22.     public function getArea() 
  23.     {        return pow($this->length, 2); 
  24.     } 
  25. function renderLargeRectangles($rectangles){     
  26. foreach ($rectangles as $rectangle) {         
  27. if ($rectangle instanceof Square) { 
  28.             $rectangle->setLength(5); 
  29.         } elseif ($rectangle instanceof Rectangle) { 
  30.             $rectangle->setWidth(4); 
  31.             $rectangle->setHeight(5); 
  32.         } 
  33.  
  34.         $area = $rectangle->getArea();  
  35.         $rectangle->render($area); 
  36.     } 
  37.  
  38. $shapes = [new Rectangle(), new Rectangle(), new Square()]; 
  39. renderLargeRectangles($shapes);  

接口隔離原則

接口隔離原則:"客戶(hù)端不應(yīng)該被強(qiáng)制去實(shí)現(xiàn)于它不需要的接口"。

有一個(gè)清晰的例子來(lái)說(shuō)明示范這條原則。當(dāng)一個(gè)類(lèi)需要一個(gè)大量的設(shè)置項(xiàng),為了方便不會(huì)要求客戶(hù)端去設(shè)置大量的選項(xiàng),因?yàn)樵谕ǔK麄儾恍枰械脑O(shè)置項(xiàng)。使設(shè)置項(xiàng)可選有助于我們避免產(chǎn)生"胖接口"

Bad:

  1. interface Employee{     
  2.     public function work();     
  3.     public function eat(); 
  4. class Human implements Employee{     
  5.     public function work() 
  6.     {        // ....working 
  7.     }     
  8.     public function eat() 
  9.     {        // ...... eating in lunch break 
  10.     } 
  11. }class Robot implements Employee{     
  12.     public function work() 
  13.     {        //.... working much more 
  14.     }     
  15.     public function eat() 
  16.     {        //.... robot can't eat, but it must implement this method 
  17.     } 
  18.  

上面的代碼中,Robot類(lèi)并不需要eat()這個(gè)方法,但是實(shí)現(xiàn)了Emplyee接口,于是只能實(shí)現(xiàn)所有的方法了,這使得Robot實(shí)現(xiàn)了它并不需要的方法。所以在這里應(yīng)該對(duì)Emplyee接口進(jìn)行拆分,正確的代碼如下:

Good:

  1. interface Workable{     
  2.     public function work(); 
  3. interface Feedable{     
  4.     public function eat(); 
  5. interface Employee extends Feedable, Workable{ 
  6. class Human implements Employee{     
  7.     public function work() 
  8.     {        // ....working 
  9.     }     
  10.     public function eat() 
  11.     {        //.... eating in lunch break 
  12.     } 
  13. }// robot can only work 
  14.  
  15. class Robot implements Workable{     
  16.     public function work() 
  17.     {        // ....working 
  18.     } 
  19.  

依賴(lài)反轉(zhuǎn)原則 Dependency Inversion Principle (DIP)

這條原則說(shuō)明兩個(gè)基本的要點(diǎn):

  • 高階的模塊不應(yīng)該依賴(lài)低階的模塊,它們都應(yīng)該依賴(lài)于抽象
  • 抽象不應(yīng)該依賴(lài)于實(shí)現(xiàn),實(shí)現(xiàn)應(yīng)該依賴(lài)于抽象

這條起初看起來(lái)有點(diǎn)晦澀難懂,但是如果你使用過(guò)php框架(例如 Symfony),你應(yīng)該見(jiàn)過(guò)依賴(lài)注入(DI)對(duì)這個(gè)概念的實(shí)現(xiàn)。雖然它們不是完全相通的概念,依賴(lài)倒置原則使高階模塊與低階模塊的實(shí)現(xiàn)細(xì)節(jié)和創(chuàng)建分離??梢允褂靡蕾?lài)注入(DI)這種方式來(lái)實(shí)現(xiàn)它。更多的好處是它使模塊之間解耦。耦合會(huì)導(dǎo)致你難于重構(gòu),它是一種非常糟糕的的開(kāi)發(fā)模式。

Bad:

  1. class Employee{     
  2.     public function work() 
  3.     {        // ....working 
  4.     } 
  5. class Robot extends Employee{     
  6.     public function work()    {        //.... working much more 
  7.     } 
  8. class Manager{     
  9.     private $employee;    
  10.     public function __construct(Employee $employee) 
  11.     {        $this->employee = $employee; 
  12.     }    public function manage() 
  13.     {        $this->employee->work(); 
  14.     } 
  15.  

Good:

  1. interface Employee{    
  2.  public function work(); 
  3.  class Human implements Employee{    
  4. public function work() 
  5.     {        // ....working 
  6.     } 
  7. class Robot implements Employee{     
  8. public function work() 
  9.     {        //.... working much more 
  10.     } 
  11. class Manager{     
  12. private $employee;     
  13. public function __construct(Employee $employee) 
  14.     {        $this->employee = $employee; 
  15.     }    public function manage() 
  16.     {        $this->employee->work(); 
  17.     } 
  18.  

別寫(xiě)重復(fù)代碼 (DRY)

這條原則大家應(yīng)該都是比較熟悉了。

盡你***的努力去避免復(fù)制代碼,它是一種非常糟糕的行為,復(fù)制代碼通常意味著當(dāng)你需要變更一些邏輯時(shí),你需要修改不止一處。

Bad:

  1. function showDeveloperList($developers){     
  2. foreach ($developers as $developer) { 
  3.         $expectedSalary =  
  4. $developer->calculateExpectedSalary(); 
  5.         $experience = $developer->getExperience(); 
  6.         $githubLink = $developer->getGithubLink(); 
  7.         $data = [ 
  8.             $expectedSalary, 
  9.             $experience, 
  10.             $githubLink 
  11.         ]; 
  12.  
  13.         render($data); 
  14.     } 
  15. function showManagerList($managers){     
  16. foreach ($managers as $manager) { 
  17.         $expectedSalary =  
  18. $manager->calculateExpectedSalary(); 
  19.         $experience = $manager->getExperience(); 
  20.         $githubLink = $manager->getGithubLink(); 
  21.         $data = [ 
  22.             $expectedSalary, 
  23.             $experience, 
  24.             $githubLink 
  25.         ]; 
  26.  
  27.         render($data); 
  28.     } 
  29.  

Good:

  1. function showList($employees){     
  2. foreach ($employees as $employee) { 
  3.         $expectedSalary =  
  4. $employee->calculateExpectedSalary(); 
  5.         $experience = $employee->getExperience(); 
  6.         $githubLink = $employee->getGithubLink(); 
  7.         $data = [ 
  8.             $expectedSalary, 
  9.             $experience, 
  10.             $githubLink 
  11.         ]; 
  12.  
  13.         render($data); 
  14.     } 
  15.  

Very good:

  1. function showList($employees){    foreach ($employees as $employee) { 
  2.         render([ 
  3.             $employee->calculateExpectedSalary(), 
  4.             $employee->getExperience(), 
  5.             $employee->getGithubLink() 
  6.         ]); 
  7.     } 
  8.  

后記:雖然OOP設(shè)計(jì)需要遵守如上原則,不過(guò)實(shí)際的代碼設(shè)計(jì)一定要簡(jiǎn)單、簡(jiǎn)單、簡(jiǎn)單。在實(shí)際編碼中要根據(jù)情況進(jìn)行取舍,一味遵守原則,而不注重實(shí)際情況的話(huà),可能會(huì)讓你的代碼變的難以理解! 

責(zé)任編輯:龐桂玉 來(lái)源: PHP技術(shù)大全
相關(guān)推薦

2022-09-27 09:21:34

SOLID開(kāi)閉原則Go

2015-07-30 14:45:19

java簡(jiǎn)潔

2022-08-31 08:19:04

接口returnCode代碼

2021-05-06 20:03:00

JavaStream代碼

2022-09-02 08:17:40

MapStruct代碼工具

2020-05-14 09:15:52

設(shè)計(jì)模式SOLID 原則JS

2022-07-15 09:01:15

React對(duì)象編程

2018-09-18 16:20:08

Asyncjavascript前端

2021-02-11 08:59:37

SOLID模塊倒置原則

2024-09-30 11:51:07

2022-03-24 09:44:54

TypeScriptSOLID

2012-08-01 09:38:17

代碼整潔

2023-10-09 18:52:14

SOLIDJava

2022-06-27 06:23:23

代碼編程

2022-12-15 10:52:26

代碼開(kāi)發(fā)

2022-08-31 12:15:09

JavaScript代碼優(yōu)化

2012-08-01 09:23:31

代碼

2021-01-06 14:42:09

前端Typescript代碼

2021-04-25 11:31:45

React代碼整潔代碼的實(shí)踐

2023-11-16 18:17:13

Python編程內(nèi)置模塊
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)