设计模式(三)创建型模式

设计模式(三)创建型模式,第1张

根据菜鸟教程的目录,我们首先来看看创建型模式。 创建型模式研究:

下面分别对创建型模式下的各种具体模式进行讲解。

先看例子: 工厂模式。

某功能的使用者只和接口打交道,不关心如何实现。这种情况下,肯定有一个接口类,使用者使用接口;功能提供者继承并实现接口。这利用了C++的多态特性。

既然使用者只关心接口,那么没有必要把子类直接给使用者,没有必要让使用者在代码中直接new子类。如果这样做,会把不必要的信息暴露给使用者,增加了信息的耦合。试想,如果使用者在很多地方都new了子类,那么如果这些地方需要修改的话,怎么改?只能一个一个地方改,改完还需要编译,维护极其困难。

工厂模式是指,针对某一功能接口,我们要新建一个工厂类,此工厂类将接口子类名称、接口子类的创建过程封装起来,只返回一个接口指针给接口的使用者。接口的实现类对使用者完全透明,高度解耦。这样可以方便地切换接口的具体实现,而不影响上层功能使用者。拿 汽车 打比方,不管工厂生产 汽车 的流程是什么,只要是 汽车 ,它的驾驶方法(人机接口)都类似。

显而易见,工厂模式在使用者和实现者之间增加了一个封装层,这正印证了计算机行业中一句名言:

典型的例子是:Qt中的数据库模块就利用了工厂模式,封装了数据库的底层实现。在保持数据库用户接口不变的情况下,通过更换数据库驱动,可以实现数据库类型无缝切换。

在需求趋于稳定时使用,需求不稳定时,不要过度设计,否则设计很容易被推翻,白费力气。

从设计模式的本质来看,工厂模式:

先看例子: 抽象工厂模式。

由前面工厂模式可知,所有的“工厂”有一个共同点:每个工厂都会提供创建对象的函数。 既然所有工厂都实现了同一类功能,那么我们可以为工厂抽象出一个公共接口(虚基类),此接口定义了创建工厂子类的功能。 这种场景是否似曾相识?是的,工厂和工厂的功能接口构成了使用工厂模式的场景。即工厂本身也适用于工厂模式。 使用工厂模式来设计工厂,必然要写一个生产工厂的工厂。 生产工厂的工厂,返回值是工厂的抽象接口类,所以这种设计模式叫“抽象工厂模式”。其实,笔者觉得把这种设计模式叫做“工厂工厂模式”更容易理解。

如果只有一个工厂就不要使用抽象工厂模式了,只有在工厂很多时,才使用抽象工厂模式。

需求不稳定时,不要过度设计,一切都可能被推翻。 对于小的项目,不需要过度追求使用设计模式,架构的代码最好只占整个项目代码的一小部分,否则就是主次颠倒,给自己找麻烦。 对于大的项目,在需求较稳定的情况下,为了提高可维护性、扩展性,可以考虑使用设计模式。 另外,抽象工厂模式有一定的理解难度,要考虑你设计的代码,其他人是否能够读懂,简单易懂也是需要考虑的方面。

所以,从设计模式的本质来看,

先看例子: 单例模式。

上面的例子都是允许一个类被创建多次的。如果我们想要限制一个类只被创建一次,即只有一个全局可访问的实例(和C语言中的全局变量一样),例如应用程序对象,每个应用程序都应该只有一个应用程序对象。此时应该怎么编写代码呢?

答案还是封装。把不想暴露出来的信息藏起来,把必须暴露的信息暴露出来。单例模式把类的构造函数设置成private私有访问权限,限制外部无法通过new来创建实例。只能通过特定的接口来获取实例指针。需要提及的是,封装时需要考虑多线程安全的问题。

当一个类需要有多个实例存在时,不使用单例模式。

从设计模式的本质上看,

具体的例子和写法,可以参考菜鸟教程中的 建造者模式。

建造者模式的典型使用场景是快餐店的套餐搭配模型。 套餐由若干个单个餐品组合而成。单个餐品又由不同的原材料构成。这种层层组合的树形对象关系的应用场景下,为了创建顶层的对象,需要先一层层的创建底层的对象,逐步向上,直到构造出根对象。 这种场景下,使用继承可以将同类的对象关联起来,使用组合可以将不同类型的对象组合起来。组合就是把不同对象放在一块内存中保存,作为一个整体使用。

完全使用继承来解决此类问题是非常不提倡的。设计模式理论中有一个原则是:“少用继承,多用组合”。因为继承是一种强耦合,组合是一种松散的耦合。耦合不利于适应需求变化,是项目中的一颗定时炸d。

从设计模式的本质上看,

菜鸟教程中没有提及的一种设计模式是组合模式。具体内容可以参考: 第四节:组合模式和建筑者模式详解。

这里简单说明一下,组合模式和建造者模式比较像,也是遵循树形对象关系结构。和建造者模式相比,不同之处在于,子对象和父对象具有相同的类型。所以可以说,组合模式是简单的建造者模式。

具体的使用场合和实例,见原型模式。

原型模式,在实际使用时可能用得不多。用一句话描述其特点:

这种克隆是一种内存中的复制行为,速度快,能充分利用已有对象的缓存数据,性能高。克隆出来的对象具有和原对象相同的属性和行为,可以用来帮助原对象处理一些事务。用一句动漫中的词汇来描述,“影分身”再合适不过了。

从设计模式的本质看,

下一篇,我们将介绍结构型模式。

抽象工厂模式定义:提供一个创建一系列相关或者相互依赖对象的接口,而无需指定它们具体的类。

好处:经常用层数据层,便于更换数据库产品,灵活性强,让具体的创建实例过程和客户端分离。

反射技术:提供了封装程序集、模块和类型的对象。可以使用反射动态地创建类型的实例,将类型绑定到现有对 象,或从现有对象中获取类型。

语法格式:Assembly.load("程序集名称").CreatInstance("命名空间 .类名称")

基础介绍完毕,下面逐步认识实例中的应用:

程序采用三层架构,利用抽象工厂实现了DAL和BLL分离,这是包图:

DAL数据层:

IDAL层和DAL层的关系:

工厂层关系:

代码实现:

BLL层方法:

''' <summary>

''' 增加用户

''' </summary>

''' <param name="userInfo">实体类</param>

''' <returns>返回不同的情况</returns>

''' <remarks>不同情况代表不同的数值</remarks>

Function AddUserInfo(ByVal userInfo As UserInfo) As Integer

Dim iUser As IDAL.IUser

Dim intAdd As Integer

Dim btnAdd As Boolean

Dim dsSelect As New DataSet

'调用抽象工厂实例化数据表

Dim dataAccess As New DataAccess

iUser = dataAccess.CreateUser

'调用数据接口层的函数 查询是否存在用户

dsSelect = iUser.QueryUser(userInfo)

If Not dsSelect.Tables(0).Rows.Count = 0 Then

intAdd = 0 '用户名已经存在,不能重复注册

Return intAdd

Exit Function

Else

' 用户名不存在,可以添加

btnAdd = iUser.AddUser(userInfo)

If btnAdd = True Then

intAdd = 1'添加成功

Else

intAdd = 2 '出现故障

End If

Return intAdd

End If

End Function

抽象工厂类代码:

'******类名:DataAccess

'******创建人:Jesse

'******创建时间:2012年5月4日

'******说明:用抽象工厂实现数据接口层,用到反射+配置文件

Option Explicit On

Option Strict On

Imports IDAL

Imports System.Reflection '引入反射

Imports System.Configuration '引入配置文件管理

''' <summary>

''' 简单工厂优化的抽象工厂方法

''' </summary>

''' <remarks></remarks>

Public Class DataAccess

Private Shared ReadOnly AssemblyName As String = "DAL" '数据程序集名称

Private Shared ReadOnly db As String = ConfigurationManager.AppSettings("DB") '读取配置文件

''' <summary>

''' 实例产生User表

''' </summary>

''' <returns>User表</returns>

''' <remarks></remarks>

Public Function CreateUser() As IDAL.IUser

Dim ClassName As String = "DAL" + "." + db + "User" '要实例化的类名

Dim User As IUser '定义接口

User = CType(Assembly.Load(AssemblyName).CreateInstance(ClassName), IUser) '反射实例化

Return User

End Function

''' <summary>

''' 实例用户基本信息表

''' </summary>

''' <returns>基本信息表</returns>

''' <remarks></remarks>

Public Function CreateStudentInfo() As IStudentInfo

Dim ClassName As String = "DAL" + "." + db + "StudentInfo"

Dim StudentInfo As IStudentInfo

StudentInfo = CType(Assembly.Load(AssemblyName).CreateInstance(ClassName), IStudentInfo) '反射实例化

Return StudentInfo

End Function

''' <summary>

''' 实例充值表

''' </summary>

''' <returns>充值表</returns>

''' <remarks></remarks>

Public Function CreateRecharge() As IRecharge

Dim ClassName As String = "DAL" + "." + db + "Recharge"

Dim Recharge As IRecharge

Recharge = CType(Assembly.Load(AssemblyName).CreateInstance(ClassName), IRecharge) '反射实例化

Return Recharge

End Function

''' <summary>

''' 实例化退卡信息表

''' </summary>

''' <returns>退卡信息表</returns>

''' <remarks></remarks>

Public Function CreateCancelCard() As ICancelCard

Dim ClassName As String = "DAL" + "." + db + "CancelCard"

Dim CancelCard As ICancelCard

CancelCard = CType(Assembly.Load(AssemblyName).CreateInstance(ClassName), ICancelCard) '反射实例化

Return CancelCard

End Function

''' <summary>

''' 实例化上机记录表

''' </summary>

''' <returns>上机记录表</returns>

''' <remarks></remarks>

Public Function CreateOnlineRcd() As IOnlineRcd

Dim ClassName As String = "DAL" + "." + db + "OnlineRcd"

Dim OnlineRcd As IOnlineRcd

OnlineRcd = CType(Assembly.Load(AssemblyName).CreateInstance(ClassName), IOnlineRcd) '反射实例化

Return OnlineRcd

End Function

''' <summary>

''' 实例化基本数据设定

''' </summary>

''' <returns>基本数据设定</returns>

''' <remarks></remarks>

Public Function CreateBasicData() As IDAL.IBasicData

Dim ClassName As String = "DAL" + "." + db + "BasicData"

Dim BasicData As IBasicData

BasicData = CType(Assembly.Load(AssemblyName).CreateInstance(ClassName), IBasicData) '反射实例化

Return BasicData

End Function

''' <summary>

''' 工作记录表

''' </summary>

''' <returns>工作记录表</returns>

''' <remarks></remarks>

Public Function CreateWorklog() As IDAL.IWorklog

Dim ClassName As String = "DAL" + "." + db + "Worklog"

Dim Worklog As IWorklog

Worklog = CType(Assembly.Load(AssemblyName).CreateInstance(ClassName), IWorklog) '反射实例化

Return Worklog

End Function

''' <summary>

''' 日结账单表

''' </summary>

''' <returns></returns>

''' <remarks></remarks>

Public Function CreateBillOfDay() As IBillOfDay

Dim ClassName As String = "DAL" + "." + db + "BillOfDay"

Dim BillOfDay As IBillOfDay

BillOfDay = CType(Assembly.Load(AssemblyName).CreateInstance(ClassName), IBillOfDay) '反射实例化

Return BillOfDay

End Function

End Class

IDAL层IUser:

'******类名:IUser

'******创建人:毕桃杨

'******创建时间:2012年5月4日

'******说明:数据表User的接口类

''' <summary>

''' User数据表接口

''' </summary>

''' <remarks></remarks>

'''

Public Interface IUser

''' <summary>

''' 查询用户

''' </summary>

''' <param name="userInfo">实体类</param>

''' <returns>返回记录集</returns>

''' <remarks></remarks>

Function SelcetUser(ByVal userInfo As Entity.UserInfo) As DataSet

''' <summary>

''' 修改密码

''' </summary>

''' <param name="userInfo">实体类</param>

''' <returns>是否修改成功</returns>

''' <remarks></remarks>

Function ModifyPwd(ByVal userInfo As Entity.UserInfo) As Boolean

''' <summary>

''' 添加用户

''' </summary>

''' <param name="userInfo">实体类</param>

''' <returns>是否添加成功</returns>

''' <remarks></remarks>

Function AddUser(ByVal userInfo As Entity.UserInfo) As Boolean

''' <summary>

''' 删除用户

''' </summary>

''' <param name="userInfo">实体类</param>

''' <returns>是否删除成功</returns>

''' <remarks></remarks>

Function DeleteUser(ByVal userInfo As Entity.UserInfo) As Boolean

''' <summary>

''' 根据用户等级查询用户

''' </summary>

''' <param name="userInfo">实体类</param>

''' <returns>返回记录集</returns>

''' <remarks></remarks>

Function SelectLevel(ByVal userInfo As Entity.UserInfo) As DataSet

''' <summary>

''' 只是根据用户名查询用户信息

''' </summary>

''' <param name="userInfo">实体类</param>

''' <returns>返回记录集</returns>

''' <remarks></remarks>

Function QueryUser(ByVal userInfo As Entity.UserInfo) As DataSet

End Interface

DAL层IUser实现类:

'******类名:SqlUser

'******创建人:毕桃杨

'******创建时间:2012年5月6日

'****** 说明:数据表SqlUser的 *** 作类

Option Explicit On

Option Strict On

Imports System.Data '引用类库

Imports System.Data.SqlClient

Imports IDAL

Imports Entity

''' <summary>

''' DAL—User *** 作类

''' </summary>

''' <remarks></remarks>

Public Class SqlUser

Implements IDAL.IUser '实现I_user接口

''' <summary>

''' 添加用户

''' </summary>

''' <param name="userInfo">实体类</param>

''' <returns>返回是否添加用户成功</returns>

''' <remarks></remarks>

Public Function AddUser(ByVal userInfo As Entity.UserInfo) As Boolean Implements IDAL.IUser.AddUser

Dim btn As Boolean = False '是否成功标志

Dim sqlHelper As New SQLHelper()'助手类

Dim strSQL As String'SQL字符串

Dim i As Integer'受影响的行数

'参数集合

Dim paras As SqlParameter()

paras = New SqlParameter() {New SqlParameter("@userID", userInfo.userID),

New SqlParameter("@u_password", userInfo.u_password),

New SqlParameter("@u_level", userInfo.u_level),

New SqlParameter("@u_operator", userInfo.u_operator)

}

'SQL语句

strSQL = "insert into D_sqlUser (userID,u_password,u_level,u_operator)" _

&"values(@userID,@u_password,@u_level,@u_operator)"

'执行带参数的过程

i = sqlHelper.ExecuteNonQuery(strSQL, paras, CommandType.Text)

If i >0 Then

btn = True

End If

Return btn

End Function

''' <summary>

''' 删除用户

''' </summary>

''' <param name="userInfo">实体类</param>

''' <returns>是否删除成功</returns>

''' <remarks></remarks>

Public Function DeleteUser(ByVal userInfo As Entity.UserInfo) As Boolean Implements IDAL.IUser.DeleteUser

Dim strSQL As String 'sql字符串

Dim i As Integer '受影响的行数

Dim btn As Boolean = False '是否成功标志

Dim sqlHelper As New SQLHelper'SQL助手类

Dim strUserId As String '用户名

strUserId = userInfo.userID '获取实体类的用户名

'删除用户sql语句

strSQL = "delete from D_sqlStudentInfo where userID ='" &Trim(strUserId) &"'"

i = sqlHelper.ExecuteNonQuery(strSQL, CommandType.Text)

If i >0 Then

btn = True '成功

End If

Return btn

End Function

''' <summary>

''' sql实现查询用户

''' </summary>

''' <param name="userInfo">实体类</param>

''' <returns>返回记录集</returns>

''' <remarks></remarks>

Public Function SelcetUser(ByVal userInfo As Entity.UserInfo) As System.Data.DataSet Implements IDAL.IUser.SelcetUser

Dim strUserID As String '用户名存储

Dim strPWD As String'用户密码存储

Dim queryString As String 'SQL查询语句

Dim sqlHelper As SQLHelper = New SQLHelper()

'从实体类获取用户名和密码

strUserID = userInfo.userID

strPWD = userInfo.u_password

'查询SQL语句

queryString = "SELECT * FROM D_sqlUser WHERE userID ='" &Trim(strUserID) &"'" &"AND u_password ='" &strPWD &"'"

Dim dtUser As DataSet

'执行不带参数的查询过程

'dtUser = sqlHelper.Query(queryString)

dtUser = sqlHelper.ExecuteQuery(queryString, CommandType.Text)

Return dtUser

End Function

''' <summary>

''' 修改密码

''' </summary>

''' <param name="userInfo">实体类</param>

''' <returns>返回是否修改成功</returns>

''' <remarks></remarks>

Public Function ModifyPwd(ByVal userInfo As Entity.UserInfo) As Boolean Implements IDAL.IUser.ModifyPwd

Dim btn As Boolean = False '是否修改成功判断

Dim sqlHelper As New SQLHelper()

Dim strSQL As String'SQL语句

Dim i As Integer'受影响的行数

'参数集合

Dim paras As SqlParameter()

paras = New SqlParameter() {New SqlParameter("@userID", userInfo.userID),

New SqlParameter("@u_password", userInfo.u_password)

}

'SQL查询语句

strSQL = "update D_sqlUser set u_password=@u_password where userid=@userID"

i = sqlHelper.ExecuteNonQuery(strSQL, paras, CommandType.Text) '执行带参数的查询过程

If i >0 Then

btn = True'修改成功

End If

Return btn

End Function

''' <summary>

''' 根据用户等级查询信息

''' </summary>

''' <param name="userInfo">实体类</param>

''' <returns>返回记录集</returns>

''' <remarks></remarks>

Public Function SelectLevel(ByVal userInfo As Entity.UserInfo) As System.Data.DataSet Implements IDAL.IUser.SelectLevel

Dim strLevel As String '获取用户等级

Dim sqlHelper As New SQLHelper

Dim queryString As String'SQL语句

Dim dsUser As New DataSet '定义记录集

'从实体类获得等级

strLevel = Trim(userInfo.u_level)

'查询SQL语句

queryString = "SELECT * FROM D_sqlUser WHERE u_level ='" &Trim(strLevel) &"'"

''执行不带参数的查询过程

dsUser = sqlHelper.ExecuteQuery(queryString, CommandType.Text)

Return dsUser

End Function

''' <summary>

''' DAL 查询用户只是根据用户名查询

''' </summary>

''' <param name="userInfo">实体类</param>

''' <returns>返回记录集</returns>

''' <remarks></remarks>

Public Function QueryUser(ByVal userInfo As Entity.UserInfo) As System.Data.DataSet Implements IDAL.IUser.QueryUser

Dim strUserID As String '用户名

Dim strPWD As String'密码

Dim sqlHelper As New SQLHelper '助手类

Dim queryString As String 'SQL查询语句

'从实体类获取数据

strUserID = userInfo.userID

strPWD = userInfo.u_password

'SQL查询语句

queryString = "SELECT * FROM D_sqlUser WHERE userID ='" &Trim(strUserID) &"'"

'执行不带参数的查询过程

Dim dsUser As DataSet

dsUser = sqlHelper.ExecuteQuery(queryString, CommandType.Text)

Return dsUser

End Function

End Class

总结:BLL层无需知道DAL层,IDAL接口层实现了数据层和逻辑层的分离,用反射更是减少了分支判断带来的耦合。

总体来说设计模式分为三大类:

一、创建型模式,共五种:工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。

二、结构型模式,共七种:适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。

三、行为型模式,共十一种:策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。

1、工厂方法模式:

定义一个用于创建对象的接口,让子类决定实例化哪一个类。Factory Method 使一个类的实例化延迟到其子类。

工厂模式有一个问题就是,类的创建依赖工厂类,也就是说,如果想要拓展程序,必须对工厂类进行修改,这违背了闭包原则,所以,从设计角度考虑,有一定的问题,这就用到工厂方法模式。

创建一个工厂接口和创建多个工厂实现类,这样一旦需要增加新的功能,直接增加新的工厂类就可以了,不需要修改之前的代码。

2、抽象工厂模式:

提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。抽象工厂需要创建一些列产品,着重点在于"创建哪些"产品上,也就是说,如果你开发,你的主要任务是划分不同差异的产品线,并且尽量保持每条产品线接口一致,从而可以从同一个抽象工厂继承。

3、单例模式:

单例对象(Singleton)是一种常用的设计模式。在Java应用中,单例对象能保证在一个JVM中,该对象只有一个实例存在。这样的模式有几个好处:

(1)某些类创建比较频繁,对于一些大型的对象,这是一笔很大的系统开销。

(2)省去了new *** 作符,降低了系统内存的使用频率,减轻GC压力。

(3)有些类如交易所的核心交易引擎,控制着交易流程,如果该类可以创建多个的话,系统完全乱了。(比如一个军队出现了多个司令员同时指挥,肯定会乱成一团),所以只有使用单例模式,才能保证核心交易服务器独立控制整个流程。

4、建造者模式:

将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。

5、原型模式:

原型模式虽然是创建型的模式,但是与工程模式没有关系,从名字即可看出,该模式的思想就是将一个对象作为原型,对其进行复制、克隆,产生一个和原对象类似的新对象。本小结会通过对象的复制,进行讲解。在Java中,复制对象是通过clone()实现的,先创建一个原型类。

6、适配器模式:

适配器模式将某个类的接口转换成客户端期望的另一个接口表示,目的是消除由于接口不匹配所造成的类的兼容性问题。主要分为三类:类的适配器模式、对象的适配器模式、接口的适配器模式。

7、装饰器模式:

顾名思义,装饰模式就是给一个对象增加一些新的功能,而且是动态的,要求装饰对象和被装饰对象实现同一个接口,装饰对象持有被装饰对象的实例。

8、代理模式:

代理模式就是多一个代理类出来,替原对象进行一些 *** 作,比如我们在租房子的时候回去找中介,为什么呢?因为你对该地区房屋的信息掌握的不够全面,希望找一个更熟悉的人去帮你做,此处的代理就是这个意思。

9、外观模式:

外观模式是为了解决类与类之家的依赖关系的,像spring一样,可以将类和类之间的关系配置到配置文件中,而外观模式就是将他们的关系放在一个Facade类中,降低了类类之间的耦合度,该模式中没有涉及到接口。

10、桥接模式:

桥接模式就是把事物和其具体实现分开,使他们可以各自独立的变化。桥接的用意是:将抽象化与实现化解耦,使得二者可以独立变化,像我们常用的JDBC桥DriverManager一样。

JDBC进行连接数据库的时候,在各个数据库之间进行切换,基本不需要动太多的代码,甚至丝毫不用动,原因就是JDBC提供统一接口,每个数据库提供各自的实现,用一个叫做数据库驱动的程序来桥接就行了。

11、组合模式:

组合模式有时又叫部分-整体模式在处理类似树形结构的问题时比较方便。使用场景:将多个对象组合在一起进行 *** 作,常用于表示树形结构中,例如二叉树,数等。

12、享元模式:

享元模式的主要目的是实现对象的共享,即共享池,当系统中对象多的时候可以减少内存的开销,通常与工厂模式一起使用。

13、策略模式:

策略模式定义了一系列算法,并将每个算法封装起来,使其可以相互替换,且算法的变化不会影响到使用算法的客户。需要设计一个接口,为一系列实现类提供统一的方法,多个实现类实现该接口,设计一个抽象类(可有可无,属于辅助类),提供辅助函数。

14、模板方法模式:

一个抽象类中,有一个主方法,再定义1...n个方法,可以是抽象的,也可以是实际的方法,定义一个类,继承该抽象类,重写抽象方法,通过调用抽象类,实现对子类的调用。

15、观察者模式:

观察者模式很好理解,类似于邮件订阅和RSS订阅,当我们浏览一些博客或wiki时,经常会看到RSS图标,就这的意思是,当你订阅了该文章,如果后续有更新,会及时通知你。

其实,简单来讲就一句话:当一个对象变化时,其它依赖该对象的对象都会收到通知,并且随着变化!对象之间是一种一对多的关系。

16、迭代子模式:

顾名思义,迭代器模式就是顺序访问聚集中的对象,一般来说,集合中非常常见,如果对集合类比较熟悉的话,理解本模式会十分轻松。这句话包含两层意思:一是需要遍历的对象,即聚集对象,二是迭代器对象,用于对聚集对象进行遍历访问。

17、责任链模式:

责任链模式,有多个对象,每个对象持有对下一个对象的引用,这样就会形成一条链,请求在这条链上传递,直到某一对象决定处理该请求。但是发出者并不清楚到底最终那个对象会处理该请求,所以,责任链模式可以实现,在隐瞒客户端的情况下,对系统进行动态的调整。

18、命令模式:

命令模式的目的就是达到命令的发出者和执行者之间解耦,实现请求和执行分开。

19、备忘录模式:

主要目的是保存一个对象的某个状态,以便在适当的时候恢复对象,个人觉得叫备份模式更形象些,通俗的讲下:假设有原始类A,A中有各种属性,A可以决定需要备份的属性,备忘录类B是用来存储A的一些内部状态,类C呢,就是一个用来存储备忘录的,且只能存储,不能修改等 *** 作。

20、状态模式:

状态模式在日常开发中用的挺多的,尤其是做网站的时候,我们有时希望根据对象的某一属性,区别开他们的一些功能,比如说简单的权限控制等。

21、访问者模式:

访问者模式把数据结构和作用于结构上的 *** 作解耦合,使得 *** 作集合可相对自由地演化。访问者模式适用于数据结构相对稳定算法又易变化的系统。因为访问者模式使得算法 *** 作增加变得容易。

若系统数据结构对象易于变化,经常有新的数据对象增加进来,则不适合使用访问者模式。访问者模式的优点是增加 *** 作很容易,因为增加 *** 作意味着增加新的访问者。访问者模式将有关行为集中到一个访问者对象中,其改变不影响系统数据结构。其缺点就是增加新的数据结构很困难。

22、中介者模式:

中介者模式也是用来降低类类之间的耦合的,因为如果类类之间有依赖关系的话,不利于功能的拓展和维护,因为只要修改一个对象,其它关联的对象都得进行修改。

如果使用中介者模式,只需关心和Mediator类的关系,具体类类之间的关系及调度交给Mediator就行,这有点像spring容器的作用。

23、解释器模式:

解释器模式一般主要应用在OOP开发中的编译器的开发中,所以适用面比较窄。

扩展资料:

介绍三本关于设计模式的书:

1、《设计模式:可复用面向对象软件的基础》

作者:[美] Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides

出版社: 机械工业出版社

2、《软件秘笈:设计模式那点事》

作者:郑阿奇

出版社:电子工业出版社

3、《设计模式:基于C#的工程化实现及扩展》

作者:王翔

出版社:电子工业出版社

参考资料来源:百度百科-设计模式


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/sjk/6775238.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-03-28
下一篇 2023-03-28

发表评论

登录后才能评论

评论列表(0条)

保存