前言
今年接手的一个计费项目让我痛苦不堪,里面到处充斥着重复冗余的代码,一个简单的需求往往需要改n个地方,而且很多改动牵一发动全身,这个项目涉及到支付,出问题就是损失银子的问题。虽然我不会写出如此难维护的代码,并且平常也用到了一些设计模式,比如工厂,策略,但是我觉得还是很有必要系统学习下面向对象方面的知识。想要学好设计模式,我认为首先要清楚懂面向对象的基本概念,如抽象,封装,继承,多态, 懂得看UML图,其次要理解设计模式的几大原则,咱们首先认识下UML。
UML图简介
一. 依赖关系
依赖关系表示的是一种使用关系,特定事物的改变有可能影响到使用该事物的其它事物,依赖关系在UML中使用虚线箭头表示,在代码中通常有如下三种表示方式
1.一个类的实例 作为另外一个类方法的参数
2.一个类的实例 作为另外一个类方法的局部变量
3.一个类在方法中调用了另外一个类的静态方法
<?php class Member{ public function add(Redis $redis){ $redis->set(); } public function set(){ $redis = new Redis(); $redis->set(); } public function del(){ Redis::del(); } } class Redis{ public function set(){ echo "添加数据"; } public static function del(){ echo "删除数据"; } }
二.关联关系
关联关系是一种结构化的关系,表示一个类与另外一个类有联系,关联关系用实线箭头表示,关联关系又分为单向关联,双向联,聚合,组合,关联关系在代码中通常体现为一个类的实例作为另外一个类的成员变量。
例如,我们把Redis对象的实例做为Member类的成员变量。
class Member{ private $redis; public function add(Redis $redis){ $this->redis = $redis; $this->redis->set(); } } class Redis{ public function set(){ echo "添加数据"; } public static function del(){ echo "删除数据"; } }
Member的add方法执行完后,Redis对象的声明周期并不会结束,而依赖关系在Member的方法执行完后,Redis对象的生命周期随之结束。所以关联关系相比依赖关系具有更强的耦合性。
三.聚合关系
聚合关系表示的是整体和部分的关系,整体和部分可以拆开,聚合关系使用带空心菱形的直线表示,在代码中通常体现为成员对象通常作为构造方法、业务方法的参数注入到整体对象中。
<?php class Redis{ public function set(){ echo "添加数据"; } public static function del(){ echo "删除数据"; } } class Member{ private $redis; public function __construct(Redis $redis) { $this->redis = $redis; } public function add(){ $this->redis->set(); } }
四.组合关系
组合关系也是整体和部分的关系,但是整体和部分是不可分割的,整体和部分具有形同的生命周期,聚合关系使用实心菱形的直线表示,在代码中通常体现为通过构造函数实例化。
<?php class Redis{ public function set(){ echo "添加数据"; } public static function del(){ echo "删除数据"; } } class Member{ private $redis; public function __construct() { $this->redis = new Redis(); } public function add(){ $this->redis->set(); } }
泛化和实现就不多说了,理解清楚关联,依赖,组合,聚合对于学习设计模式是非常有必要的。本文的UML图是使用Netbeans UML插件绘制,虽然我大PHP是弱类型的语言,但这并不妨碍我们看懂UML。