Dieser Artikel stellt hauptsächlich die Zusammenfassung der fünf Prinzipien des objektorientierten PHP-Designs (SOLID) vor, die einen gewissen Referenzwert haben. Jetzt können Freunde in Not darauf verweisen
PHP Designprinzipien Um es zu klären, lesen Sie „PHP-Kerntechnologie und Best Practices“, „Agile Entwicklungsprinzipien, Muster und Praktiken“, den Artikel „Fünf Prinzipien des objektorientierten PHP-Designs“, DesignmusterprinzipienSOLID
Nur ein Grund für eine Klassenänderung
Eine Klasse hat nur einen Verantwortung (Verantwortung: Grund für Änderung)
Vermeiden Sie die Verteilung der gleichen Verantwortlichkeiten auf verschiedene Klassen und die Duplizierung von Funktionen
Eine Klasse hat zu viele Verantwortlichkeiten, und die Änderung einer Verantwortlichkeit beeinträchtigt die Fähigkeit dieser Klasse, andere Verantwortlichkeiten zu erfüllen unerwartete Konsequenzen. Zerstören Sie
Reduzieren Sie die Kopplung zwischen Klassen : Nur wenn sich die Anforderungen ändern eine ist eine modifizierte Klasse, wodurch die Auswirkungen von Änderungen auf andere Verantwortlichkeiten isoliert werden
Verbesserung der Wiederverwendbarkeit von Klassen : Referenz auf Anfrage, eine Klasse ist für eine Verantwortung verantwortlich, Anforderungen Änderungen erfordern lediglich das Ändern der entsprechenden Klasse oder das Hinzufügen einer bestimmten Verantwortung
Reduzieren Sie die Komplexität der Klasse: Einzelne Verantwortung, dezentrale Funktionen Reduzieren Sie eine Klasse auf mehrere Verantwortungsklassen Komplexität
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 } }
Viele Aufgaben des Softwaredesigns bestehen darin, Verantwortlichkeiten zu entdecken und die Beziehungen zwischen Verantwortlichkeiten sinnvoll zu trennen. Wenn sich Änderungen an der Anwendung immer auf mehrere Verantwortlichkeiten gleichzeitig auswirken, ist keine Trennung der Verantwortlichkeiten erforderlich.
Beim Entwerfen einer Anwendung ist die Schnittstelle der Klasse nicht zusammenhängend. Verschiedene Clients enthalten nur einige zentralisierte Funktionen, aber das System zwingt den Client, alle Methoden im Modul zu implementieren und auch einige dumme Methoden zu schreiben. Eine solche Schnittstelle wird zu einer fetten Schnittstelle oder einer Schnittstellenverschmutzung. Eine solche Schnittstelle führt zu unangemessenem Verhalten im System, verschwendet Ressourcen, beeinträchtigt andere Client-Programme, verbessert die Kopplung usw.
Clients sollten nicht gezwungen werden, sich auf Methoden/Funktionen zu verlassen, die sie nicht benötigen
Die Abhängigkeit einer Klasse von einer Klasse sollte auf der kleinsten Schnittstelle basieren
Die Implementierungsklasse der Schnittstelle sollte nur als Einzelverantwortungsprinzip dargestellt werden
Bei der Trennung von Fettschnittstellen stellt jede Gruppe von Schnittstellen spezifische Funktionen bereit, um eine bestimmte Gruppe von Clientprogrammen zu bedienen.
Änderungen an einer Gruppe von Schnittstellen haben keine oder nur geringfügige Auswirkungen andere Schnittstellen/Client-Programm, um die Reinheit der Schnittstelle sicherzustellen
Fat-Schnittstelle wird in mehrere kundenspezifische Schnittstellen/mehrere Schnittstellen zerlegt Getrennte Vererbung
Mithilfe der Delegation-Trennungsschnittstelle sind zwei Objekte an der Verarbeitung derselben Anfrage beteiligt, und das Objekt, das die Anfrage akzeptiert, delegiert die Anfrage an ein anderes Objekt zur Verarbeitung
/* * 公告接口 */ 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();
Fat-Klassen können abnormale und schädliche Kopplungsbeziehungen zwischen ihren Clientprogrammen verursachen. Durch die Zerlegung von Thick-Clients in mehrere clientspezifische Schnittstellen sind Clients stark von den Methoden abhängig, die sie tatsächlich aufrufen, wodurch die Abhängigkeiten zwischen Clients und Methoden, die sie nicht aufrufen, gelöst werden. Die Schnittstellenisolation sollte klein und selten gehalten werden.
Beide lösen das Abhängigkeitsprinzip im Softwaredesign
SRP konzentriert sich auf die Aufteilung der Verantwortlichkeiten Bei Constraint-Klassen handelt es sich hauptsächlich um Schnittstellen und Methoden, bei denen es sich um Details und Implementierungen im Programm handelt. ISP achtet auf die Isolation von Schnittstellen. Das abstrakte Design der Schnittstelle erfolgt aus einer eher makroökonomischen Perspektive
Da die Größe von Softwaresystemen weiter zunimmt, nimmt die Komplexität der Systemwartung und -modifikation weiter zu. Änderungen in einem Teil des Systems wirken sich häufig auf andere Module aus. Die richtige Anwendung der OCP-Prinzipien kann solche Probleme lösen.
Ein Modul sollte im Hinblick auf die Erweiterung des Verhaltens offen und im Hinblick auf die Veränderbarkeit geschlossen sein
Das Verhalten des Moduls ist erweiterbar und das Verhalten/die Funktion des vorhandenen Moduls kann problemlos erweitert werden
Erweiterungen des Moduls Verhalten wird keine/geringe Auswirkungen auf bestehende Systeme/Module haben
/* * 定义有固定行为的抽象接口 */ 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());
Die Kernidee von OCP ist die Abstraktionsschnittstelle Beim Programmieren ist die Abstraktion relativ stabil. Lassen Sie Klassen von festen Abstraktionen abhängen, lassen Sie Klassen Abstraktionen durch objektorientierte Vererbung und Polymorphismus erben und ihre Methoden oder inhärenten Verhaltensweisen überschreiben. Dies dient dazu, über neue Erweiterungsmethoden/-funktionen nachzudenken und Erweiterungen zu erreichen.
面向对象中大量的继承关系十分普遍和简单,这种继承规则是什么,最佳的继承层次的规则又是什么,怎样优雅的设计继承关系,子类能正确的对基类中的某些方法进行重新,这是LSP原则所要处理的问题。
子类必须能够替换掉他们的基类型:任何出现基类的地方都可以替换成子类并且客户端程序不会改变基类行为或者出现异常和错误,反之不行。
客户端程序只应该使用子类的抽象父类,这样可以实现动态绑定(php多态)
假设一个函数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得以应用的最主要的原则之一,正是因为子类性的可替换行是的基类类型在无需修改的情况下扩展功能。
软件开发设计中,总是倾向于创建一些高层模块依赖底层模块,底层模块更改时直接影响到高层模块,从而迫使他们改变。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中文网!
相关推荐:
Das obige ist der detaillierte Inhalt vonZusammenfassung der fünf Prinzipien des objektorientierten PHP-Designs (SOLID). Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!