1. 云栖社区>
  2. PHP教程>
  3. 正文

Learning PHP —— 设计模式 | Chap1:浅谈设计模式中的OOP

作者:用户 来源:互联网 时间:2017-12-01 15:01:46

设计模式

Learning PHP ——  设计模式 | Chap1:浅谈设计模式中的OOP - 摘要: 本文讲的是Learning PHP —— 设计模式 | Chap1:浅谈设计模式中的OOP, 为什么使用OOP OOP是一个模块化的过程,目的是为了把复杂问题简单化,一个模块解决一个复杂问题的某一个方面,即一个类应当只有一个职责 OOP区别于顺序式编程与过程式编程,在于: 1.顺序编程:用于处理最简单的问题2.过程编程:将代码

为什么使用OOP

  • OOP是一个模块化的过程,目的是为了把复杂问题简单化,一个模块解决一个复杂问题的某一个方面,即一个类应当只有一个职责

  • OOP区别于顺序式编程与过程式编程,在于:

    1.顺序编程:用于处理最简单的问题2.过程编程:将代码分为模块以便在程序中重用,程序猿输为一个函数输入不同实参就能利用不同具体值使用函数3.OOP:形同过程编程,长处在于能处理自己的数据结构,更方便地处理  独立但相互关联的类
  • 从外部源启动PHP类,往往由其它模块调动,不会自启动,举个反例:

<?php class TellAll{private function __construct(){...}}$tellAll = new TellAll();?>

OOP基本概念

抽象(abstract)

  • 用于指示一个对象的基本特征,是处理复杂性的具体方法。
    我们会对现实中的相似性分组,对具体的相似性抽象

举个例子:我们一般不会叫自己的爱宠哈士奇为"我的蠢萌蠢萌的、摇着尾巴的、爱捣乱的名叫Jeff的哈士奇",而往往会直接说:"我的狗。"

  • 抽象类不能实例化,只能由具体类(可以实例化的类,非抽象类)继承抽象类的接口以及所有具体属性

  • 所有类都是对数据的一组操作的抽象

  • 基本语法:

<?php //IAbstract.phpabstract class IAbstract{public $storeHere;//可以定义属性public function test(){...//非抽象类,继承子类无须实现}abstract public function trick($whatever);//作为对继承子类的限制}?>
<?php//OneAbstract.phpclass OneAbstract extends IAbstract{public function trick(){...//声明了抽象方法就必须实现}}?>

接口(interface)

  • 不能像抽象类那样在接口中包含具体方法或变量,除非是具有抽象性的接口,可以包含具体常量

  • 接口的核心部分由类中操作(函数)定义的所有签名组成。签名包括一个操作的操作名和参数,一个接口表示的就是所有签名的集合。例如以下代码,签名由trick()和形参$whatever组成

public function trick($whatever){echo 'signature';}
  • 如果要实现接口(implements),就要保证实现接口中的所有方法,在此基础上可以再继续添加额外的方法

<?php//ImethodHolder.phpinterface IMethodHolder{public function getInfo($info);public function sendInfo($Info);public function calculate($first,$second);}?>
<?php//ImplementAlpha.phpinclude_once('IMethodHolder.php');class ImplementAlpha implements IMethodHolder{/********  接口中所有方法必须实现   ********/public function getInfo($info){echo 'This is my News!' . $info."<br/>";}public function sendInfo(){return $Info;}public function calculate($first,$second){$calculate = $first * $second;return $calculate;} /********  除此之外可以增加其他类   ********/public function useMethods(){$this->getInfo('习近平会见马英九');echo $this->sendInfo('恒大战平阿赫利') . "<br/>";echo "Salary : $" . $this->calculate(20,15) ;}$worker = new ImplementAlpha;$worker->useMethods();//前面提到不要自启动,这里为了方便就直接自启动实例化类//不过可以看到,在实现类中,方法都是经过useMethods的方法调用的//在后面章你会看到很多例子都是这样实现的,而往往不会直接调用}?>
  • OOP和设计模式有很多重要的结构要素,其中之一就是指定数据类型为接口而不是一个具体实现,对数据的引用要通过父类完成。如下所示:

<?php//IProduct.phpinterface IProduct{function apples();function books();}?>
<?php//FruitStore.phpinclude_once('IProduct.php');class FruitStore store implements IProduct{public function apples(){   return  'Fruit shop-----We have apples';}public function books(){ return  'Fruit shop-----We don't have books';}}?>
<?php//BookStore.php//再来一个BookStore类同上,No apples,but books?>
<?//useProduct.php//两个实现include进来,此处省略代码class useProduct{public function __construct(){$apple = new FruitStore();$book = new BookStore();$this->doInterface($apple);$this->doInterface($book);}function doInterface(IProduct $product){echo $product->apples();echo $product->books();}}$worker = new useProduct();?>

这就是强制数据类型,其中使用的对象(类)必然有给定的接口,如果把一个接口 (一个对象类或者接口) 作为代码提示,绑定会更宽松)它会绑定到接口而不是绑定到一个特定的实现,如上面的doInterface(IProduct $product)

封装(Encapsulation)

  • 封装是画份一个抽象的诸多元素的过程,这些元素构成该抽象的结构和行为,封装的作用就是将抽象的契约接口与其实现分离

  • 通过3种类型的可见性保护封装(private/protected/public)。但是一个类还是要有可见方法访问封装,比如__consruct构造函数,默认为公共的

  • 为了保持封装而又提供可访问性,OOP建议使用getter()和setter()方法,但是不能滥用,否则会破坏封装

<?phpclass GetSet{private $data;function __construct(){$this->setter(200);$got = $this->getter();echo $got;}private function getter(){return $this->data;}private function setter($setValue){$this->data = $setValue;}}$worker = new GetSet();?>

继承(extends)

  • 假设我有一只哈士奇(我们称之为子类),那么它继承了狗(父类)的属性,比如四只脚,看到的世界都是通过#404040层过滤的。而哈士奇区别于普通狗,又有新的特征:逗比,爱捣乱

  • 为了保证类之间的松绑定,通常会继承抽象类,而且是浅继承(只有一层子类)。深继承的话,一旦对父类进行简单修改,子类会带来严重的破坏

<?php//dog.phpclass dog{protected $pet;//共同特征,四条腿protected function fourlegs(){return 'walk on all four';}//宠物性格protected function character($petChar){$this->$pet = $petChar;}}?>
<?php//haski.phpinclude_once 'dog.php';class haski extends dog{function __construct(){echo 'Haski ' . $this->fourlegs() . "<br/>";echo $this->character('They are crazy!') . "<br/>";echo $this->naughty() . "<br/>"; }private function naughty(){return 'Haski dogs are naughty';}}?>
<?php//client.phpinclude_once 'haski.php';class client{function __construct(){$haski = new haski();}}$worker = new Client();?>

多态(polymorphism)

  • 多态的真正价值在于可以调用有相同接口的对象来完成不同的工作。一个大型项目中,增加和修改会对程序带来巨大影响,除非有一个公共的接口(父类或接口),例如:

<?php//Poly.phpinterface ISpeed{function fast();function cruise();function slow();}class Jet implements ISpeed{function slow(){return 120;}function cruise(){return 1200;}function fase(){return 1500;}}class car impplements ISpeed{   function slow(){$carslow = 15;return $carslow;}function cruise(){$carcruise = 65;return $carcruise;}function fase(){$carZoom = 110;return $carZoom;}}$f22 = new Jet();//各种调用,省略$ford = new Car();//同上?>

从上面的例子看出,Jet和Car类对接口的实现有很大不同。但是基于这样一个公共接口,在一个给定的程序结构中做出修改或者增补时,可以放心地请求或使用接口方法,而不必担心程序会崩溃


PS:该篇引用于《Learning PHP设计模式》第1、2章节

Chap2 预告 :设计模式与UML

  • 算法处理操作速度,设计模式解决开发速度

以上是云栖社区小编为您精心准备的的内容,在云栖社区的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索设计模式 ,以便于您获取更多的相关知识。

弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率

40+云计算产品,6个月免费体验

现在注册,免费体验40+云产品,及域名优惠!

云服务器9.9元/月,大学必备