上一篇我们介绍了设计模式的特性并且详细讲解了4种创建型模式,创建型模式是负责如何产生对象实例的,现在我们继续来给大家介绍结构型模式。
一、什么是结构型模式? 结构型模式是解析类和对象的内部结构和外部组合,通过优化程序结构解决模块之间的耦合问题。
二、结构型模式的种类: 适配器模式 桥接模式 装饰模式 组合模式 外观模式 享元模式 代理模式
1、 适配器模式(Adapter) 将一个类的接口转换成客户希望的另一个接口,适配器模式使得原本的由于接口不兼容而不能一起工作的那些类可以一起工作。 应用场景:老代码接口不适应新的接口需求,或者代码很多很乱不便于继续修改,或者使用第三方类库。 代码实现
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
|
/** * 优才网公开课示例代码
*
* 适配器模式
*
* @author 优才网全栈工程师教研组
* @see http://www.ucai.cn
*/
//老的代码 class User {
private $name ;
function __construct( $name ) {
$this ->name = $name ;
}
public function getName() {
return $this ->name;
}
} //新代码,开放平台标准接口 interface UserInterface {
function getUserName();
} class UserInfo implements UserInterface {
protected $user ;
function __construct( $user ) {
$this ->user = $user ;
}
public function getUserName() {
return $this ->user->getName();
}
} $olduser = new User( '张三' );
echo $olduser ->getName(). "n" ;
$newuser = new UserInfo( $olduser );
echo $newuser ->getUserName(). "n" ;
|
注意点:这里的新接口使用了组合方式,UserInfo内部有一个成员变量保存老接口User对象,模块之间是松耦合的,这种结构其实就是组合模式。不要使用继承,虽然UserInfo继承User也能达到同样的目的,但是耦合度高,相互产生影响。
2、 桥接模式 将抽象部分与它的实现部分分离,使它们都可以独立变化 特点:独立存在,扩展性强
应用:需要不断更换调用对象却执行相同的调用方法,实现扩展功能
代码实现
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
|
/** * 优才网公开课示例代码
*
* 桥接模式
*
* @author 优才网全栈工程师教研组
* @see http://www.ucai.cn
*/
abstract class Person {
abstract function getJob();
} class Student extends Person {
public function getJob() {
return '学生' ;
}
} class Teacher extends Person {
public function getJob() {
return '老师' ;
}
} class BridgeObj {
protected $_person ;
public function setPerson( $person ) {
$this ->_person = $person ;
}
public function getJob() {
return $this ->_person->getJob();
}
} $obj = new BridgeObj();
$obj ->setPerson( new Student());
printf( "本次桥接对象:%sn" , $obj ->getJob());
$obj ->setPerson( new Teacher());
printf( "本次桥接对象:%sn" , $obj ->getJob());
|
3、 装饰模式 动态地给一个对象添加额外的职责。在原有的基础上进行功能增强。 特点:用来增强原有对象功能,依附于原有对象。 应用:用于需要对原有对象增加功能而不是完全覆盖的时候
代码实现
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
|
/** * 优才网公开课示例代码
*
* 装饰模式
*
* @author 优才网全栈工程师教研组
* @see http://www.ucai.cn
*/
//产品 abstract class Person {
abstract function getPermission();
} //被装饰者 class User extends Person {
public function getPermission() {
return '公开文档' ;
}
} //装饰类 class PermUser extends Person {
protected $_user ;
protected $_special = '' ;
function __construct( $user ) {
$this ->_user = $user ;
}
public function getPermission() {
return $this ->_user->getPermission() . $this ->_special;
}
} //装饰类产品 class JavaUser extends PermUser {
protected $_special = ' java程序' ;
} class CPlusUser extends PermUser {
protected $_special = ' c++程序' ;
} $user = new User();
printf( "permission:%sn" , $user ->getPermission());
$user = new JavaUser( $user );
printf( "permission:%sn" , $user ->getPermission());
$user = new CPlusUser( $user );
printf( "permission:%sn" , $user ->getPermission());
|
大家想想装饰和继承的区别在哪? 如果是上面的例子,如果用继承,是CPlusUser继承JavaUser还是反过来呢?谁也不知道最终使用者需要哪一种。
在多层关系的情况下,装饰是和顺序无关并且随时增加装饰,而继承只能是特定的顺序,所以装饰模式会更加的灵活。
4、组合模式 将对象组合成树形结构表示“部分-整体”的层次结构。 特点:灵活性强 应用:对象的部分-整体的层次结构,模糊组合对象和简单对象处理问题代码实现
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
|
/** * 优才网公开课示例代码
*
* 组合模式
*
* @author 优才网全栈工程师教研组
* @see http://www.ucai.cn
*/
//继承模式 class UserBaseInfo {
private $name ;
function __construct( $name ) {
$this ->name = $name ;
}
public function getName() {
return $this ->name;
}
} class User extends UserBaseInfo {
private $login = false;
public function setLogin( $islogin ) {
$this ->login = $islogin ;
}
public function isLogin() {
return $this ->login;
}
} $user = new User( '张三' );
$user ->setLogin(true);
if ( $user ->isLogin()) {
echo $user ->getName(). "已经登录了n" ;
} else {
echo $user ->getName(). "还没有登录n" ;
} //组合模式 class LoginInfo {
protected $user ;
protected $login = false;
public function setLogin( $user , $isLogin ) {
$this ->user = $user ;
$this ->login = $isLogin ;
}
public function isLogin() {
return $this ->login;
}
} $user = new User( '张三' );
$login = new LoginInfo();
$login ->setLogin( $user , true);
if ( $login ->isLogin()) {
echo $user ->getName(). "已经登录了n" ;
} else {
echo $user ->getName(). "还没有登录n" ;
} //部分可以更换,用继承则不行 class Admin {
protected $level ;
function __construct( $level ) {
$this ->level = $level ;
}
function getLevel() {
return $this ->level;
}
} $admin = new Admin(1);
$login ->setLogin( $admin , true);
if ( $login ->isLogin()) {
printf( "级别为 %d 的管理员已经登录了n" , $admin ->getLevel());
} else {
printf( "级别为 %d 的管理员还没有登录n" , $admin ->getLevel());
} |
上面的例子分别展示了使用继承和组合来处理新功能,在简单的情况下看似区别不大,但在项目后期越来越复杂的时候组合模式的优势就越来越明显了。 例如上面的登录信息,如果要增加登录次数、最后登录时间、登录ip等信息,登录本身就会变成一个比较复杂的对象。如果以后有新的需求比如好友信息、用户的 访问信息等,再要继承的话,用户类就会变得非常庞大,难免各父类之间没有冲突的变量和方法,而外部访问用户类的众多方法也变得很费劲。采用组合模式后,一 个类负责一个角色,功能区分非常明显,扩展方便。
5、 外观模式(门面模式) 为了系统中的一组接口提供一个一致的界面 特点:向上抽取,有共性 应用:内部接口众多,由统一的接口来调用
代码实现
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
|
/** * 优才网公开课示例代码
*
* 外观模式,也叫门面模式
*
* @author 优才网全栈工程师教研组
* @see http://www.ucai.cn
*/
class Operation {
public function testPlus() {
printf( "plus: %sn" , (1 + 2 == 3 ? 'true' : 'false' ));
}
public function testMinus() {
printf( "minus: %sn" , (3 - 2 == 2 ? 'true' : 'false' ));
}
public function testTimes() {
printf( "times: %sn" , (2 * 3 == 6 ? 'true' : 'false' ));
}
} class Tester {
protected $_operation ;
function __construct() {
$this ->_operation = new Operation();
}
public function testAll() {
$this ->_operation->testPlus();
$this ->_operation->testMinus();
$this ->_operation->testTimes();
}
} //测试用例,测试全部接口 $tester = new Tester();
$tester ->testAll();
|
门面模式估计大家在实际代码中都已经使用到了,接口较多时把相似功能的接口封装成一个接口供外部调用,这就是门面模式。
6、 享元模式 运用共享技术有效地支持大量细粒度对象,采用一个共享来避免大量有相同内容对象的开销。这种开销中最直观的就是内存的损耗。 特点:高效性,共享性 应用:系统底层的设计。例如字符串的创建。如果两个字符串相同,则不会创建第二个字符串,而是第二个的引用直接指向第一个字符 串。$str1=”abc”,$str2=”abc”.则内存存储中只会创建一个字符串“abc”而引用$str1.$str2都会指向它。
7、 代理模式 为其他对象提供一个代理来控制对这个对象的访问,就是给某一对象提供代理对象,并由代理对象控制具体对象的引用。能够协调调用者和被调用者,能够在一定程度上降低系统的耦合性。 特点:低耦合性,独立性好,安全性 应用:客户访问不到或者被访问者希望隐藏自己,所以通过代理来访问自己。
代码实现
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
|
/** * 优才网公开课示例代码
*
* 代理模式
*
* @author 优才网全栈工程师教研组
* @see http://www.ucai.cn
*/
//内部对象 class User {
public function getName() {
return '张三' ;
}
public function getType () {
return '付费用户' ;
}
} //代理接口定义,例如开放平台 interface UserInterface {
function getName();
} //代理对象 class UserProxy implements UserInterface {
protected $_user ;
function __construct() {
$this ->_user = new User();
}
public function getName() {
return $this ->_user->getName();
}
} //内部调用 $user = new User();
printf( "user name:%sn" , $user ->getName());
printf( "user type:%sn" , $user -> getType ());
//外部调用 // $user = new UserProxy(); // printf("user name:%sn", $user->getName()); // printf("user type:%sn", $user->getType()); //不能访问,及时知道内部对象有这个方法 |
三、总结 1、代理模式、适配器模式、门面模式、装饰模式的区别 a、 相同之处:都封装一个内部对象,调用内部对象的方法 b、 不同之处:各自有各自的特性和应用场景,不能相互替代。所以用的时候要仔细分析用那种合适。
2、 关于模式的选用问题 模式的选用要根据实际的业务需求,通过对业务逻辑的仔细分析,再根据模式具有的特性和应用场景进行合理的选择和区分。大部分情况下业务的场景决定了哪种模 式,而不是选择哪个模式去实现一个业务,少数情况几种模式确实都能解决问题,那主要就是考虑以后的扩展了。 到这里我们已经了解了7种结构型模式,下一篇我们继续给大家介绍设计模式的行为型模式,先预览一下行为型模式的种类吧:
u模版方法模式
u命令模式
u迭代器模式
u观察者模式
u终结者模式
u备忘录模式
u解释器模式
u状态模式
u策略模式
u职责链模式
u访问者模式
优才网公开课:http://www.ucai.cn/train/
转载自:http://www.ucai.cn/blogdetail/7020?action=gt&mid=1
相关推荐
2. PHP设计模式的类型:PHP中常用的设计模式可以分为三大类,分别是创建型模式、结构型模式和行为型模式。创建型模式主要涉及对象实例化的过程,如单例模式、工厂模式、建造者模式等;结构型模式涉及如何组合类和...
PHP设计模式是将这些模式应用到PHP编程中的具体实现,可以帮助开发者编写更灵活、可维护和高效的代码。以下是对标题和描述中提及的一些设计模式的详细说明: 1. **解释器设计模式**:它允许我们创建一个简单的语言...
16. 组合模式:定义了一种树形结构,用于表示部分与整体的层次结构,允许用户对单个对象和组合对象进行相同的操作。 通过学习和实践这些设计模式,开发者可以提高代码质量,使其更具可读性、可维护性和可扩展性。...
《Learning PHP设计模式》这本书是面向PHP开发者的一本专业指南,旨在帮助读者深入理解并掌握设计模式在PHP编程中的应用。设计模式是软件工程中经过时间验证的最佳实践,它们为解决常见问题提供了一种标准的方法,使...
《PHP设计模式》是一本探讨如何在PHP编程中应用设计模式的书籍。设计模式是软件工程领域中,解决常见问题的模板或策略。本书作者是美国的Aaron Saray,内容详尽地介绍了各种设计模式,旨在帮助PHP开发者构建出更加...
**PHP设计模式详解** 在IT领域,设计模式是一种在特定情境下解决常见问题的标准方法,它们代表了软件设计中的最佳实践。PHP作为一种广泛使用的服务器端脚本语言,同样可以从设计模式中受益。《Learning PHP设计模式...
《PHP设计模式全解》是一本深入探讨PHP编程中设计模式的资源集合,它旨在帮助PHP开发者提升代码质量、可维护性和复用性。设计模式是软件工程中的宝贵经验总结,通过将常见的问题解决方案标准化,使得开发过程更加...
8. 组合模式:组合模式允许你将对象组合成树形结构来表示“部分-整体”的层次结构。在PHP中,可以用于构建菜单系统或文件系统树。 9. 适配器模式:适配器模式使两个不兼容的接口能够协同工作。在PHP中,它可以用于...
### PHP设计模式详解 #### 一、设计模式概述 **设计模式**是在软件工程领域中广泛应用的一种编程思想,它提供了一种系统化的解决方案,用于解决软件设计中的常见问题。设计模式不仅有助于提高代码的可复用性和可...
例如,工厂模式、单例模式、观察者模式等,都是在PHP开发中经常用到的设计模式。通过理解这些模式,开发者可以写出更灵活、可扩展的代码,并且能够更好地与其他开发者协作。 再者,“框架”章节会介绍一些流行的PHP...
PHP设计模式是编程世界中用于组织和结构化代码的通用模板。本部分主要内容涉及设计模式的概念、其历史背景以及在软件开发中的重要性,并指出了设计模式与代码库的不同。同时,本文还概述了本书的写作目的,即介绍...
本资源包含了《PHP设计模式》一书中的实际代码示例,这些例程涵盖了多种设计模式,包括创建型、结构型和行为型模式。通过这些源码,开发者可以更直观地学习如何在实际项目中应用这些模式。 1. **创建型模式**: - ...
《Learning PHP设计模式》是由美国作家William Sanders撰写的一本面向初学者和中级PHP开发者的设计模式指南。这本书旨在帮助读者理解并应用设计模式这一强大的软件工程工具,以提高PHP编程的效率和代码质量。设计...
**PHP设计模式详解** 在软件开发中,设计模式是一种经过时间考验、被广泛接受的解决方案模板,用于解决常见的设计问题。对于PHP开发者来说,理解并掌握设计模式是提升代码质量和可维护性的关键步骤。设计模式并非...
《PHP设计模式大全》 设计模式是软件工程中的一种最佳实践,它是在特定上下文中解决常见问题的经验总结。在PHP编程中,理解并熟练运用设计模式对于提升代码质量、可维护性和可扩展性至关重要。本篇文章将深入探讨...
本资源包含的"php23种完整设计模式(完整代码)"是一个宝贵的学习资料,它涵盖了设计模式的全貌,让开发者可以通过实践来掌握这些模式。 首先,让我们逐一了解这23种设计模式,并讨论它们的核心思想和应用场景: 1...
根据提供的文件信息,本文将对《Learning_PHP设计模式》这一主题进行深入解析,重点围绕PHP设计模式的基础概念、分类及应用场景展开讨论。 ### PHP设计模式基础 #### 1. 设计模式简介 设计模式是在软件工程领域内...
《PHP设计模式》一书由美国作者Aaron Saray撰写,主要针对PHP开发者,详细阐述了在实际编程过程中如何运用设计模式提升代码质量和可维护性。设计模式是软件工程中的最佳实践,它们是解决常见问题的经验总结,使得...
PHP设计模式主要分为三大类:创建型模式、结构型模式和行为型模式。 1. **创建型模式**: - 单例模式:确保一个类只有一个实例,并提供一个全局访问点。 - 工厂模式:提供一个接口来创建对象,但让子类决定实例化...