Introduction

面向对象编程中,一切都是对象,对一个对象的封装,也成了面向对象编程中必不可少的部分。和C/C++,Java,Python等语言一样,PHP也支持封装。

封装/Encapsulation

对事物的封装是指,将事物进行抽象后,提供抽象概念的实现的具体方法。

听起来很拗口,还是举鲸鱼的例子。

对于鲸鱼来说,需要吃东西这个行为,吃本身是一个抽象的概念,因为具体到怎么吃,是咀嚼和消化的过程,甚至如何咀嚼和消化也是不可见的。对外部而言,可见的只是吃这一个接口,如何吃、怎么吃,是被封装在了鲸鱼的实现中。

甚至可以说,消化系统,被封装到了鲸鱼这个对象中,对外部不可见,仅仅鲸鱼自己可见。

封装方法

和别的程序设计语言一样,PHP也只是三种封装概念:Private,Protected,Public。

私有/Private

私有的概念是,仅仅对象内部可见,外部不可见,如:<?php

class Whale {

private $name;

public function __construct() {

$this->name = "Whale";

}

public function eat($food) {

chew($food);

digest($food);

}

private function chew($food) {

echo "Chewing " . $food . "\n";

}

private function digest($food) {

echo "Digest " . $food . "\n";

}

}

?>

name是鲸鱼的私有属性,chew()和digest()是鲸鱼的私有方法,对于其他类来说,都是不可见的。对于现实来说,我们如果只是注重吃,并没有必要去关心鲸鱼是如何去吃的。

保护/Protected

保护的概念是,仅仅是自身类和继承类可见,这个关键字的用途主要是防止滥用类的派生,另外三方库编写的时候会用到,防止误用。<?php

abstract class Animal {

private $name;

abstract public function eat($food);

protected function chew($food) {

echo "Chewing " . $food . "\n";

}

protected function digest($food) {

echo "Digest " . $food . "\n";

}

}

class Whale extends Animal {

private $name;

public function __construct() {

$this->name = "Whale";

}

public function eat($food) {

chew($food);

digest($food);

}

}

?>

鲸鱼类可以通过继承使用动物类的咀嚼和消化方法,但是别的继承鲸鱼类的类就不可以再使用动物类的咀嚼和消化方法了。保护更多是用于面向对象设计,而不是为了编程来实现某个需求。

公共/Public

公共的概念就是,任何类、任何事物都可以访问,没有任何限制,这里不再赘述。

Getters/Setters

Getters和Setters也叫Accessors和Mutators,在Java/C#等语言中常以get()/set()方法出现。对于这两个东西的争议很大,考虑下面一个类:<?php

class Price {

public $priceA;

public $priceB;

public $priceC;

...

}

?>

如果不使用Getters/Setters,我们给Price类赋值和取值一般是这样:<?php

$price = new Price();

$price->priceA = 1;

$price->priceB = 2;

$price->priceC = 3;

...

echo $price->priceA;

echo $price->priceB;

echo $price->priceC;

...

?>

但是如果使用了Getters/Setters,Price类将变成这样:<?php

class Price {

private $priceA;

private $priceB;

private $priceC;

public function getPriceA() {

return $this->priceA;

}

public function setPriceA($price) {

$this->priceA = $price;

}

...

}

?>

这时候赋值将变成这样:<?php

$price = new Price();

$price->setpriceA(1);

$price->setPriceB(2);

$price->setPriceC(3);

...

echo $price->getPriceA();

echo $price->getPriceB();

echo $price->getPriceC();

...

?>

是不是感觉需要多敲很多代码?这也是很多程序员不愿意使用get/set的原因,造成了大量的看似无用冗余的代码。为什么叫看似冗余和无用?因为Getters/Setters是编程设计方法,而不是编程实现方法。

在面向对象程序设计中,类和类之间的访问、交互和更新应该是通过Accessors和Mutators,也就是Getters和Setters来实现。直接访问和修改破坏了类的封装性。

为什么采用这种设计方式?因为程序设计是对现实问题的抽象,而在编程的工程中程序员扮演的角色往往是上帝。

考虑这样一种场景:你朋友要求你改名,决定是否改名的人是你,而不是你朋友。在你的朋友的视觉(也就是你朋友的类),他不能直接去修改你的名字。

如果你直接采用非Getters/Setters的设计方法,事实上是程序员扮演的这个上帝修改了现实规则,允许你朋友能够随意更改你的姓名,显然这是不合理的。

Summary

合理的封装对于好的程序设计是必不可少的,虽然什么都是Public也能解决编程问题,但是这不是用程序设计解决问题的思路。

Tag标签:

php 封装模式,PHP设计模式(三):封装相关推荐

  1. mysql工厂模式_设计模式-三种工厂模式实例

    1.简单工厂模式:代替new产生对象,产品的类型比较少时. 我们要获得三种不同的数据库对象,如Mysql,SQLserver,Oracle,它们拥有共同的特征,即可以进行抽象,简单工厂目的是将获得具体 ...

  2. java架构模式与设计模式(三)--事件风暴

    本文来自 什么是事件风暴 很多人在学习DDD的过程中,都会有一个疑问:DDD的概念看着挺多,听起来也很有用.但具体怎么落地实施到项目中? 事件风暴(Event Storming)于2013年首次被提出 ...

  3. 设计模式精髓—封装变化

    设计模式精髓-封装变化 模式,是为了需求变动而产生,抛开需求谈模式,显得很苍白. 无论是创建型模式.结构型模式还是行为型模式,归根结底都是寻找软件中可能存在的"变化",然后利用抽象 ...

  4. 设计模式三—抽象工厂模式

    设计模式三-抽象工厂模式 一.定义 抽象工厂模式是工厂方法模式的进一步抽象.如果产品簇中只有一种产品,则退化为工厂方法模式. 二.原理图 三.代码实例 * 苹果和土豆是园丁1的杰作 * 葡萄和西红柿是 ...

  5. 设计模式-创建型模式-工厂模式(工厂三兄弟) TypeScript

    设计模式-创建型模式-工厂模式(工厂三兄弟) TypeScript 简单工厂模式 定义一个接口,三个具体类.然后书写如下,通过选择,生产出相应的对象 // 定义Shape接口 interface Sh ...

  6. JS设计模式三:策略模式

    官方:策略模式定义了算法家族,分别封装起来,让他们之间可以互相替换,此模式让算法的变化不会影响到使用算法的客户. 策略模式是常用的模式,例如jQuery的 $(selector).animate(st ...

  7. 设计模式-创建型模式-工厂模式(工厂三兄弟)

    设计模式-创建型模式-工厂模式(工厂三兄弟) 工厂模式分为简单工厂,工厂方法,抽象工厂. 简单工厂模式 一个接口,三个具体类,一个工厂,通过选择,生产出对应的对象. package demo2;pub ...

  8. Vue 组件的高级封装模式

    一.传统模式 我们在使用 vue 进行项目开发过程中,对组件的封装是不可避免的,组件式开发在很大程度上提高了代码的复用性,能够提高开发效率.一般情况下,我们使用最基础的封装模式,基本流程如下: 创建 ...

  9. 无线WLAN隧道转发模式下数据的封装以及转发过程

    无线WLAN隧道转发模式下数据的封装以及转发过程 实验用的拓扑: AP1.AP2的业务vlan为101.102,管理vlan为100,AR路由器作为DHCP服务器为AP和终端分配IP地址.DNS等信息 ...

最新文章

  1. Linux——Linux概念架构的理解
  2. Python Qt GUI设计:QScrollBar类实现窗口水平或垂直滑动条效果(拓展篇—4)
  3. 大厂白嫖拖垮开源!开源届码农:用户脾气大需求多还不给钱
  4. C# static的用法详解
  5. 高数第七版_习题解答_3-1行列式习题
  6. jQuery 人脸识别插件,支持图片和视频
  7. 破解前端面试系列(3):如何搞定纸上代码环节?
  8. 南京工业大学python考试期末题库_大学慕课2020用Python玩转数据期末考试大全答案...
  9. 【应用】Properties类与Properties配置文件的读写
  10. FreeBSD学习笔记15-FreeBSD下安装Apache
  11. java自带函数_java8中内置的四大核心函数式接口
  12. Cron表达式 定时执行说明
  13. 小米8,全面屏手机判断是否显示虚拟键
  14. 计算机上那里可以看产品密钥,使用Windows Key Viewer一键轻松查看当前计算机的产品密钥...
  15. redis 集群介绍及docker实现
  16. HTTP提交方式之PUT详细介绍及POST和PUT的区别
  17. AIO-3399J重新安装Ubuntu系统-刷新固件
  18. vue 总结一项目建立及文件夹结构配置
  19. 2015年杭电计算机存储器扩展,杭电计算机组成原理存储器设计实验5
  20. RDD -- Transformation算子分析

热门文章

  1. xampp配置虚拟主机
  2. skywalking调研相关资料整理
  3. 个人总结的【LaTeX】超高频特殊符号表(仅33个符号)+复杂公式速写解决方案,请查收!
  4. sku组合查询算法探索
  5. 怎么看tomcat连接的哪个mysql_如何验证tomcat和mysql连接成功呢
  6. 【转】mac/linux终端光标的快捷键操作
  7. 阿里云服务器下安装LAMP环境(CentOS Linux 6.3)(1)
  8. asp.net 正在加载效果实现
  9. 三维点云学习(3)2- K-Means
  10. 5年赚50倍的段永平:这几家公司正在长长的坡上滚着厚厚的雪