概念
设计模式(Design Pattern)是前辈们对代码开发经验的总结,是解决特定问题的⼀系列解决⽅ 案。它不是语法规定,⽽是⼀套⽤来提⾼代码可复⽤性、可维护性、可读性、稳健性以及安全性 的解决⽅案
类型
根据设计模式的参考书 Design Patterns - Elements of Reusable Object-Oriented Software(中文译名:设计模式 - 可复用的⾯向对象软件元素) 中所提到的,总共有 23 种设计模式。这些模式可以 分为三⼤类:创建型模式(Creational Patterns)、结构型模式(Structural Patterns)、行为型模式 (Behavioral Patterns)。当然,我们还会讨论另⼀类设计模式:J2EE 设计模式。
序号 | 模式 & 描述 | 包括 |
1 | 创建型模式 这些设计模式 提供了⼀种在创建对象的 同时隐藏创建逻辑的⽅ 式,⽽不是使⽤ new 运 算符直接实例化对象。这 使得程序在判断针对某个 给定实例需要创建哪些对 象时更加灵活。 | ⼯⼚模式(Factory Pattern)抽象⼯⼚模式(Abstract Factory Pattern)单例模式(Singleton Pattern)建造者模 式(Builder Pattern)原型模式(Prototype Pattern) |
2 | 结构型模式 这些设计模式 关注类和对象的组合。继 承的概念被⽤来组合接⼝ 和定义组合对象获得新功 能的⽅式。 | 适配器模式(Adapter Pattern)桥接模式(Bridge Pattern)过滤器模式(Filter、Criteria Pattern)组合模式 (Composite Pattern)装饰器模式(Decorator Pattern) 外观模式(Facade Pattern)享元模式(Flyweight Pattern)代理模式(Proxy Pattern) |
3 | ⾏为型模式 这些设计模式 特别关注对象之间的通信。 | 责任链模式(Chain of Responsibility Pattern)命令模式 (Command Pattern)解释器模式(Interpreter Pattern) 迭代器模式(Iterator Pattern)中介者模式(Mediator Pattern)备忘录模式(Memento Pattern)观察者模式 (Observer Pattern)状态模式(State Pattern)空对象模 式(Null Object Pattern)策略模式(Strategy Pattern)模 板模式(Template Pattern)访问者模式(Visitor Pattern) |
4 | J2EE 模式 这些设计模式 特别关注表示层。这些模 式是由 Sun Java Center 鉴定的。 | MVC 模式(MVC Pattern)业务代表模式(Business Delegate Pattern)组合实体模式(Composite Entity Pattern)数据访问对象模式(Data Access Object Pattern)前端控制器模式(Front Controller Pattern)拦截 过滤器模式(Intercepting Filter Pattern)服务定位器模式 (Service Locator Pattern)传输对象模式(Transfer Object Pattern) |
设计模式的六大原则
1、开闭原则(Open Close Principle)
开闭原则的意思是:对扩展开放,对修改关闭。在程序需要进⾏拓展的时候,不能去修改原有的代码, 实现⼀个热插拔的效果。简⾔之,是为了使程序的扩展性好,易于维护和升级。想要达到这样的效果, 我们需要使⽤接⼝和抽象类,后⾯的具体设计中我们会提到这点。
2、里氏代换原则(Liskov Substitution Principle)
⾥⽒代换原则是⾯向对象设计的基本原则之⼀。 ⾥⽒代换原则中说,任何基类可以出现的地⽅,⼦类⼀ 定可以出现。LSP 是继承复⽤的基⽯,只有当派⽣类可以替换掉基类,且软件单位的功能不受到影响 时,基类才能真正被复⽤,⽽派⽣类也能够在基类的基础上增加新的⾏为。⾥⽒代换原则是对开闭原则 的补充。实现开闭原则的关键步骤就是抽象化,⽽基类与⼦类的继承关系就是抽象化的具体实现,所以 ⾥⽒代换原则是对实现抽象化的具体步骤的规范。
3、依赖倒转原则(Dependence Inversion Principle)
这个原则是开闭原则的基础,具体内容:针对接⼝编程,依赖于抽象⽽不依赖于具体。
4、接口隔离原则(Interface Segregation Principle)
这个原则的意思是:使⽤多个隔离的接口,比使⽤单个接⼝要好。它还有另外⼀个意思是:降低类之间 的耦合度。由此可见,其实设计模式就是从大型软件架构出发、便于升级和维护的软件设计思想,它强 调降低依赖,降低耦合。
5、迪米特法则,又称最少知道原则(Demeter Principle)
最少知道原则是指:⼀个实体应当尽量少地与其他实体之间发⽣相互作⽤,使得系统功能模块相对独立。
6、合成复用原则(Composite Reuse Principle)
合成复用原则是指:尽量使用合成/聚合的⽅式,而不是使⽤继承
这里简单介绍两种模式
1、单例模式
概念
指⼀个类只有⼀个实例,且该类能⾃⾏创建这个实例的⼀种模式
特点
1. 单例类只有⼀个实例对象
2. 该单例对象必须由单例类⾃⾏创建
3. 单例类对外提供⼀个访问该单例的全局访问点
优点
避免内存资源的浪费
使用场景
在计算机系统中,还有 Windows 的回收站、操作系统中的⽂件系统、多线程中的线程池、显卡的驱动 程序对象、打印机的后台处理服务、应⽤程序的⽇志对象、数据库的连接池、⽹站的计数器、Web 应⽤ 的配置对象、应⽤程序中的对话框、系统中的缓存等常常被设计成单例
实现方法
三私⼀公:私有化静态属性,私有化构造⽅法,私有化克隆⽅法,公有化静态⽅法。
代码实现
<?php
final class Mysql
{
/**
*
* - @var self[该属性⽤来保存实例]
*/
private static $instance;
/**
*
* - @var mixed
*/
public $mix;
/**
* - Return self instance[创建⼀个⽤来实例化对象的⽅法]
*
* - @return self
*/
public static function getInstance()
{
if(!(self::$instance instanceof self)) {
self::$instance = new self();
}
return self::$instance;
}
/**
* - 构造函数为private,防⽌创建对象
*/
private function __construct()
{
}
/**
* - 防⽌对象被复制
*/
private function __clone()
{
trigger_error('Clone is not allowed !');
}
}
// @test
$firstMysql = Mysql::getInstance();
$secondMysql = Mysql::getInstance();
$firstMysql->mix = 'ityangs_one';
$secondMysql->mix = 'ityangs_two';
print_r($firstMysql->mix);
// 输出: ityangs_two
print_r($secondMysql->mix);
2、简单工厂模式
定义
简单工厂模式属于创建型模式⼜叫做静态工厂⽅法模式,它属于类创建型模式。在简单工厂模式中,可 以根据参数的不同返回不同类的实例。 简单工厂模式专⻔定义⼀个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类。
结构图
- Factory:⼯⼚类,简单⼯⼚模式的核⼼,它负责实现创建所有实例的内部逻辑。⼯⼚类的创建产 品类的⽅法可以被外界直接调⽤,创建所需的产品对象。
- IProduct:抽象产品类,简单⼯⼚模式所创建的所有对象的⽗类,它负责描述所有实例所共有的公 共接⼝。
- Product:具体产品类,是简单⼯⼚模式的创建⽬标。
简单实现
这⾥我们⽤⽣产电脑来举例,假设有⼀个电脑的代⼯⽣产商,它⽬前已经可以代⼯⽣产联想电脑了,随 着业务的拓展,这个代⼯⽣产商还要⽣产惠普和华硕的电脑,这样我们就需要⽤⼀个单独的类来专⻔⽣ 产电脑,这就⽤到了简单⼯⼚模式。下⾯我们来实现简单⼯⼚模式:
创建抽象产品类
我们创建⼀个电脑的抽象产品类,他有⼀个抽象⽅法⽤于启动电脑:
interface Computer
{
public function start();
}
创建具体产品类
接着我们创建各个品牌的电脑,他们都继承了他们的⽗类Computer ,并实现了⽗类的start⽅法:
联想电脑:
class LenovoComputer implements Computer
{
public function start()
{
return '联想电脑启动';
}
}
惠普电脑
class HpComputer implements Computer
{
public function start()
{
return '惠普电脑启动';
}
}
华硕电脑
class AsusComputer implements Computer
{
public function start()
{
return '华硕电脑启动';
}
}
创建工厂类
接下来创建⼀个工厂类,它提供了⼀个静态⽅法createComputer⽤来⽣产电脑。你只需要传⼊你想生产的电脑的品牌,它就会实例化相应品牌的电脑对象:
Class ComputerFactory
{
public static function createComputer($type)
{
switch ($type) {
case 'lenovo':
return new LenovoComputer();
case 'hp':
return new HpComputer();
case 'asus':
return new AsusComputer();
default:
return null;
}
}
}
客户端调用工厂类
客户端调⽤工厂类,传⼊“hp”⽣产出惠普电脑并调用该电脑对象的start方法:
//lenovo
$computer = ComputerFactory::createComputer('lenovo');
echo $computer->start();
优点和缺点
优:
- ⼯⼚类含有必要的判断逻辑,可以决定在什么时候创建哪⼀个产品类的实例,客户端可以免除直接 创建产品对象的责任,⽽仅仅“消费”产品;简单⼯⼚模式通过这种做法实现了对责任的分割,它提 供了专⻔的⼯⼚类⽤于创建对象。
- 客户端⽆须知道所创建的具体产品类的类名,只需要知道具体产品类所对应的参数即可,对于⼀些 复杂的类名,通过简单⼯⼚模式可以减少使⽤者的记忆量。
- 通过引⼊配置⽂件,可以在不修改任何客户端代码的情况下更换和增加新的具体产品类,在⼀定程 度上提⾼了系统的灵活性。
缺:
- 由于⼯⼚类集中了所有产品创建逻辑,⼀旦不能正常⼯作,整个系统都要受到影响。
- 使⽤简单⼯⼚模式将会增加系统中类的个数,在⼀定程序上增加了系统的复杂度和理解难度。
- 系统扩展困难,⼀旦添加新产品就不得不修改⼯⼚逻辑,同样破坏了“开闭原则”;在产品类型较多 时,有可能造成⼯⼚逻辑过于复杂,不利于系统的扩展和维护。
- 简单⼯⼚模式由于使⽤了静态⼯⼚⽅法,造成⼯⼚⻆⾊⽆法形成基于继承的等级结构。
适用环境
在以下情况下可以使⽤简单⼯⼚模式:
- ⼯⼚类负责创建的对象⽐较少:由于创建的对象较少,不会造成⼯⼚⽅法中的业务逻辑太过复杂。 客户端只知道传⼊⼯⼚类的参数,对于如何创建对象不关⼼:
- 客户端既不需要关⼼创建细节,甚⾄ 连类名都不需要记住,只需要知道类型所对应的参数。
模式应⽤
- JDK类库中⼴泛使⽤了简单⼯⼚模式,如⼯具类java.text.DateFormat,它⽤于格式化⼀个本地⽇ 期或者时间。
public final static DateFormat getDateInstance(); public final static DateFormat getDateInstance(int style); public final static DateFormat getDateInstance(int style,Locale locale);
- 获取不同加密算法的密钥⽣成器。
KeyGenerator keyGen=KeyGenerator.getInstance("DESede");
3、其他
例如观察者模式、适配器模式、外观模式(门面模式)、策略模式使用也较多,想了解可自行百度搜索