PHP设计原则梳理,参考《PHP核心技术与最佳实践》、《敏捷开发原则、模式与实践》,文章PHP面向对象设计的五大原则、设计模式原则SOLIDphp
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 } }
软件设计所作的许多内容就是发现职责并合理的分离职责间的关系。若是应用程序的变化老是同时影响多个职责,就不必分离职责。html
设计应用程序时,类的接口不是内聚的。不一样的客户端只包含集中的部分功能,但系统会强制客户端实现模块中全部方法,而且还要编写一些哑方法。这样的接口成为胖接口或者是接口污染,这样的接口会给系统引入一些不当的行为,资源浪费,影响其余客户端程序加强了耦合性等mysql
/* * 公告接口 */ 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();
胖类会致使他们的客户端程序之间产生不正常的而且有害的耦合关系。经过把胖客户度分解成多个特定于客户端的接口,客户端牢牢依赖于他们实际调用的方法,从而解除了客户端与他们没有调用的方法之间的依赖关系。接口隔离应作的小而少。redis
随着软件系统规模的不断扩大,系统的维护和修改的复杂性不断提升。系统一处的更改每每会影响到其余模块。正确的运用OCP原则能够解决此类问题。sql
/* * 定义有固定行为的抽象接口 */ 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());
OCP核心思想就是抽象接口编程,抽象相对稳定。让类依赖与固定的抽象,经过面向对象的继承和多态让类继承抽象,复写其方法或固有行为,是想新的扩展方法/功能,实现扩展。编程
面向对象中大量的继承关系十分广泛和简单,这种继承规则是什么,最佳的继承层次的规则又是什么,怎样优雅的设计继承关系,子类能正确的对基类中的某些方法进行从新,这是LSP原则所要处理的问题。json
假设一个函数a,他的参数引用一个基类b,c是b的派生类,若是将c的对象做为b类型传递给a,会致使a出现错误的行为,那没c就违法了LSP原则。segmentfault
/* * 基类 */ 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原则就是每一个高层次模块定义一个它所需服务的接口声明,低层次模块实现这个接口。每一个高层次类经过该抽象接口使用服务。
面向对象软件开发中合理的遵循设计原则能够更好的设计代码,减小没必要要的错误,提升程序的可维护性,可扩展性和稳定性。