资讯专栏INFORMATION COLUMN

PHP设计模式(六):MVC

时飞 / 2956人阅读

摘要:原文地址设计模式六世纪年代,计算机发展迅速,编程技术也日益分化。到了年代,的出现更是让这种程序设计模式得以延续。根据设计模式三封装中介绍的设计原则,在面向对象程序设计中,类和类之间的访问交互和更新应该是通过和。

</>复制代码

  1. 原文地址:PHP设计模式(六):MVC

Introduction

20世纪80年代,计算机发展迅速,编程技术也日益分化。桌面应用编程,也逐渐出现了用户图形界面和程序逻辑分离的程序设计。到了90年代,web的出现更是让这种程序设计模式得以延续。
这种设计模式便是MVC(Model-View-Control),除了MVC,还有MVC的变种,如MVVM(Model-View-View Model)等。

MVC

回到80年代的桌面应用编程,当时面向对象的编程设计模式(见PHP设计模式(一):基础编程模式)兴起,程序员将桌面应用分割成两个大的对象:领域对象(domain objects)和可视对象(presentation objects)。领域对象是对现实事物的抽象模型,可视对象是对用户界面部分的抽象模型。
后来人们发现,只有领域对象和可视对象是不够的,特别是在复杂的业务中。根据PHP设计模式(三):封装中介绍的设计原则,在面向对象程序设计中,类和类之间的访问、交互和更新应该是通过Accessors和Mutators。
那么如果操作领域对象呢?人们引入了控制器(controller)的对象,通过控制器来操作领域模型。
到此,MVC模型逐渐稳定下来,用户通过可视对象操作控制器对象,控制器对象再去操作领域对象。

MVC中的设计模式

上面介绍的MVC属于抽象度比较高的设计模式,在实际编程中,需要遵守下面的设计模式。

基于接口去编程

基于接口去编程的好处就是分离设计和实现,这一点我们在PHP设计模式(二):抽象类和接口已经介绍过了,下面我们举一个实际的例子来说明这个设计的好处。

</>复制代码

  1. eatFish()) {
  2. echo $this->name . " can eat fish.
  3. ";
  4. }
  5. if ($this->eatMoss()) {
  6. echo $this->name . " can eat moss.
  7. ";
  8. }
  9. }
  10. }
  11. ?>

我们创建一个鲸鱼类:

</>复制代码

  1. name = "Whale";
  2. }
  3. public function eatFish() {
  4. return TRUE;
  5. }
  6. public function eatMoss() {
  7. return FALSE;
  8. }
  9. }
  10. $whale = new Whale();
  11. $whale->eat();
  12. ?>

运行一下:

</>复制代码

  1. $ php Whale.php
  2. Whale eats fish.

看上去没什么问题,对吧?我们创建一个鲤鱼类:

</>复制代码

  1. name = "Carp";
  2. }
  3. public function eatMoss() {
  4. return TRUE;
  5. }
  6. }
  7. $carp = new Carp();
  8. $carp->eat();
  9. ?>

运行一下:

</>复制代码

  1. $ php Carp.php
  2. PHP Fatal error: Class Carp contains 1 abstract method and must therefore be
  3. declared abstract or implement the remaining method (Animal::eatFish) in
  4. Carp.php on line 9

报错了,对吧?因为我们实现Carp.php的时候故意没有去实现eatFish接口,基于接口的编程设计模式可以在开发期就发现这种逻辑错误。

使用组件而不是继承

将一个对象拆成更小的对象,这些小的对象成为组件(composition)。尽量使用组件而不是继承的设计模式的意义在于,多种继承之下,子类可能会拥有大量毫无意义的未实现方法。而通过组件的方式,子类可以选择需要的组件。
下面给出一个例子:

</>复制代码

  1. eatFish()) {
  2. echo $this->name . " can eat fish.
  3. ";
  4. }
  5. if ($this->eatMoss()) {
  6. echo $this->name . " can eat moss.
  7. ";
  8. }
  9. }
  10. }
  11. class Whale extends Animal {
  12. protected function __construct() {
  13. $this->name = "Whale";
  14. }
  15. protected function eatFish() {
  16. return TRUE;
  17. }
  18. protected function eatMoss() {
  19. return FALSE;
  20. }
  21. }
  22. class BullWhale extends Whale {
  23. public function __construct() {
  24. $this->name = "Bull Whale";
  25. }
  26. public function getGender() {
  27. return "Male";
  28. }
  29. }
  30. ?>

这里的BullWhale其实非常冗余,实际的业务模型可能并不需要这么复杂,这就是多重继承的恶果。
而组件则不同,通过将行为拆分成不同的部分,又最终子类决定使用哪些组件。
下面给出一个例子:

</>复制代码

  1. name = $name;
  2. }
  3. public function eat($food) {
  4. echo $this->name . " eat ". $food . ".
  5. ";
  6. }
  7. }
  8. class Gender {
  9. private $gender;
  10. public function __construct($gender) {
  11. $this->gender= $gender;
  12. }
  13. public function getGender() {
  14. return $this->gender;
  15. }
  16. }
  17. class BullWhale {
  18. private $action;
  19. private $gender;
  20. public function __construct() {
  21. $this->action = new Action("Bull Whale");
  22. $this->gender = new Gender("Male");
  23. }
  24. public function eatFood($food) {
  25. $this->action->eat($food);
  26. }
  27. public function getGender() {
  28. return $this->gender->getGender();
  29. }
  30. }
  31. $bullWhale = new BullWhale();
  32. $bullWhale->eatFood("fish");
  33. echo $bullWhale->getGender() . "
  34. ";
  35. ?>

运行一下:

</>复制代码

  1. $ php BullWhale.php
  2. Bill Whale eat fish.
  3. Male

BullWhale由Action和Gender组件构成,不同的类可以选择不同的组件组合,这样就不会造成类冗余了。

Summary

实际编程中,更多的往往是混合架构,如既包含继承,又包含组件的编程设计模式。不过,掌握基本的编程架构设计是一切的基础。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/21619.html

相关文章

  • PHP学习路线图

    摘要:学习路线图建议最后买一个域名和阿里云服务器,真正的将代码部署到云服务器上去,走一次上线流程,用一下管理一下代码会更棒。建议学习路线图这个时候使用写一个大并发的多服务器的秒杀出来。 PHP学习路线图 在网上很多人公布了太多的PHP学习路线图,本人在互联网公司工作十余年,也带了很多PHP入门的新手,将他们的一些问题和学习路线图为大家整理出来,希望很多小白少走弯路。 一、 网上某些错误的学习...

    wapeyang 评论0 收藏0
  • 大前端2018现在上车还还得及么

    摘要:面向对象三大特征继承性多态性封装性接口。第五阶段封装一个属于自己的框架框架封装基础事件流冒泡捕获事件对象事件框架选择框架。核心模块和对象全局对象,,,事件驱动,事件发射器加密解密,路径操作,序列化和反序列化文件流操作服务端与客户端。 第一阶段: HTML+CSS:HTML进阶、CSS进阶、div+css布局、HTML+css整站开发、 JavaScript基础:Js基础教程、js内置对...

    stormgens 评论0 收藏0
  • 大前端2018现在上车还还得及么

    摘要:面向对象三大特征继承性多态性封装性接口。第五阶段封装一个属于自己的框架框架封装基础事件流冒泡捕获事件对象事件框架选择框架。核心模块和对象全局对象,,,事件驱动,事件发射器加密解密,路径操作,序列化和反序列化文件流操作服务端与客户端。 第一阶段: HTML+CSS:HTML进阶、CSS进阶、div+css布局、HTML+css整站开发、 JavaScript基础:Js基础教程、js内置对...

    mylxsw 评论0 收藏0
  • 从零开始实现一个简易的Java MVC框架()--加强AOP功能

    摘要:在前面的文章中实现的功能时,目标类都只能被一个切面代理,如果想要生成第二个代理类,就会把之前的代理类覆盖。改装原有功能现在要改装原来的的实现代码,让的功能加入到框架中为了让切面能够排序,先添加一个注解,用于标记排序。 前言 在前面从零开始实现一个简易的Java MVC框架(四)--实现AOP和从零开始实现一个简易的Java MVC框架(五)--引入aspectj实现AOP切点这两节文章...

    Loong_T 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<