工厂模式的应用实例

工厂模式的应用实例,第1张

概述就拿机房收费系统来说吧。 NUMBER ONE 单纯的用抽象工厂来实现。这样的好处,是从整个系统的全局出发,而不单单从原始的D看待,古人云:父母之爱子则为之计深远。这使得系统更容易扩展了。因为这里面除了SQLHelper都使用了实体包,实体包的线就省略了。 NUMBER TWO   用"简单工厂"去改造的抽象工厂。 这里说的简单工厂只是因为它没有工厂接口。而事实上因为我们的机房收费系统是用对一簇产


就拿机房收费系统来说吧。

NUMBER ONE

单纯的用抽象工厂来实现。这样的好处,是从整个系统的全局出发,而不单单从原始的D看待,古人云:父母之爱子则为之计深远。这使得系统更容易扩展了。因为这里面除了sqlHelper都使用了实体包,实体包的线就省略了。

NUMBER TWO

 

"简单工厂"去改造的抽象工厂。

这里说的简单工厂只是因为它没有工厂接口。而事实上因为我们的机房收费系统是用对一簇产品进行创建使用,按理说一簇产品应该是抽象工厂的。这样的好处是,在D层实现了解耦,和抽象工厂比起来,我们要扩展的话,BLL层和IFactory改动较大。

NUMBER THREE

"简单工厂"和抽象工厂结合改造后,再加上配置文件。

 与NUMBER ONE不同的是去掉一条线。这样子的好处是去除了DALFactory与实际功能类DAL的耦合。

 

 

 

 

当然如果找个平衡点的话,我们的最佳选择是用NUMBER THREE

代码如下。(一下代码均以登录为例。UI省略)

NUMBER ONE

BLL层。

'------------------------------------------------------------------------------' <copyright file="DALUser.vb" company="FANG">' copyright (c) 2012 FANG. All rights reserved.' <copyright>' <author>The Sky Always Sunshine<author>' <author>我的博客地址http://blog.csdn.net/xhf55555</author>' <date>2012年2月3日<date>' <description>'BLL层之登录。' <description>'------------------------------------------------------------------------------Public Class BLL_Login     Public Function Login(ByVal User As Entity.EN_User) As Boolean        Dim myUser As New Entity.EN_User        '确定实例化哪个数据库给Factory,来实现换DB。        Dim factory As Ifactory.Ifactory = New DALFactory.sqlserverFactory        Dim IUser As IDAL.IUser        '与具体的数据库访问解除了依赖。        IUser = factory.CheckUser()        myUser = IUser.GetUser(User)        If myUser.UserPwd = User.UserPwd Then            Return True        Else            Return False        End If     End Function End Class


IDAL层。

 

''' <summary>''' 用户表功能接口。''' </summary>''' <remarks></remarks>Public Interface IUser    Function GetUser(ByVal User As Entity.EN_User) As Entity.EN_UserEnd Interface

DAL层。(以sqlserverUser为例。)

 

Public Class sqlserverUser : Implements IDAL.IUser     Public Function GetUser(ByVal User As Entity.EN_User) As Entity.EN_User Implements IDAL.IUser.GetUser        Dim ConnStr As String = "Data Source=192.168.24.169;Initial Catalog=PC_ChargeSys;User ID=sa;Pwd=123456"        Dim conn As sqlConnection = New sqlConnection(ConnStr)         ' Dim connection As New sqlHelp.ConnectionHelp        Dim sql As String = "select * from tb_User where UserID='" & User.UserID & "'"        Dim cmd As sqlCommand = New sqlCommand(sql, conn)        Dim read As sqlDataReader        Dim myUser As New Entity.EN_User        Try            conn.open()            read = cmd.ExecuteReader            read.Read()            myUser.UserID = read.Item("")            myUser.UserPwd = read.Item("UserPwd")            Return myUser        Catch ex As Exception            myUser.UserID = 0            myUser.UserPwd = ""            Return myUser        End Try     End FunctionEnd Class


 

IFactory层。

''' <summary>''' 定义 *** 作工厂接口。''' </summary>''' <remarks></remarks>Public Interface Ifactory    Function CheckUser() As IDAL.IUserEnd Interface


 sqlserverFactory具体 *** 作工程类。

'------------------------------------------------------------------------------' <copyright file="DALUser.vb" company="FANG">' copyright (c) 2012 FANG. All rights reserved.' <copyright>' <author>The Sky Always Sunshine<author>' <author>我的博客地址http://blog.csdn.net/xhf55555</author>' <date>2012年2月3日<date>' <description>'具体的 *** 作类工厂实现抽象的功能类接口。' <description>'------------------------------------------------------------------------------Public Class sqlserverFactory : Implements Ifactory.Ifactory    Public Function CheckUser() As IDAL.IUser Implements Ifactory.Ifactory.CheckUser        Return New DAL.sqlserverUser    End FunctionEnd Class


AccessFactory(与sqlserver相似,不再赘余。)

 

User实体类。

'User实体类。Public Class EN_User    Dim intUserID As Integer  '定义用户编号变量。    Dim strUsername As String  '定义用户姓名变量。    Dim strUserPwd As String '定义用户密码变量名。    Dim strUserActor As String '定义用户角色变量。    Dim vntUserRegDate As Date '定义用户注册日期。    Dim strUserFlag As String '定义用户是否合法的标记的变量。    Dim strUserType As String '定义用户类型变量。    ''' <summary>    ''' 用户编号属性方法。    ''' </summary>    ''' <value></value>    ''' <returns></returns>    ''' <remarks></remarks>    Public Property UserID() As Integer        Get            Return intUserID        End Get         Set(ByVal value As Integer)            intUserID = value        End Set    End Property    ''' <summary>    ''' 定义用户名属性方法。    ''' </summary>    ''' <value></value>    ''' <returns></returns>    ''' <remarks></remarks>    Public Property Username() As String        Get            Return strUsername        End Get        Set(ByVal value As String)            strUsername = value        End Set    End Property    ''' <summary>    ''' 定义用户密码属性方法 。    ''' </summary>    ''' <value></value>    ''' <returns></returns>    ''' <remarks></remarks>    Public Property UserPwd() As String        Get            Return strUserPwd        End Get        Set(ByVal value As String)            strUserPwd = value        End Set    End Property    ''' <summary>    ''' 定义用户角色属性方法。    ''' </summary>    ''' <value></value>    ''' <returns></returns>    ''' <remarks></remarks>    Public Property UserActor() As String        Get            Return strUserActor        End Get        Set(ByVal value As String)            strUserActor = value        End Set    End Property    ''' <summary>    ''' 定义注册日期变量。    ''' </summary>    ''' <value></value>    ''' <returns></returns>    ''' <remarks></remarks>    Public Property UserRegDate As Date        Get            Return vntUserRegDate        End Get        Set(ByVal value As Date)            vntUserRegDate = value        End Set    End Property    ''' <summary>    ''' 定义用户是否合法的标记。(看是否是已经注销)    ''' </summary>    ''' <value></value>    ''' <returns></returns>    ''' <remarks></remarks>    Public Property UserFlag As String        Get            Return strUserFlag        End Get        Set(ByVal value As String)            strUserFlag = value        End Set    End Property    ''' <summary>    ''' 定义用户类型变量(是固定用户还是临时用户)    ''' </summary>    ''' <value></value>    ''' <returns></returns>    ''' <remarks></remarks>    Public Property UserTyep() As String        Get            Return strUserType        End Get        Set(ByVal value As String)            strUserType = value        End Set    End Property End Class

我们再看NUMBER TWO 用简单工厂改造的抽象工厂。

我们是去掉了IFactory工厂接口和他手下的具体工厂 *** 作类,而用一个DALFactory代替解决。这样把对功能类的判断放到了DALFactory里通过SelectCase来进行判断而不是通过实例化来判断了。

UI、IUser、AccessUser、sqlserverUser是不变的。所以在以上基础上改变 ,代码如下。

BLL层代码。

 

''' <summary>''' 用户登录业务逻辑。''' </summary>''' <remarks></remarks>Public Class BLL_Login    Public Function Login(ByVal User As Entity.EN_User) As Boolean        Dim myUser As New Entity.EN_User        '通过具体的 *** 作工厂实现要判断使用哪个数据库。        Dim Dalfactory As New DALFactory.DFactory        Dim IUser As IDAL.IUser        '与具体的数据库访问解除了依赖。        IUser = Dalfactory.createuserInfo()        myUser = IUser.GetUser(User)        If myUser.UserPwd = User.UserPwd Then            Return True        Else            Return False        End If    End FunctionEnd Class


DALFactory层。

imports IDAL''' <summary>'''  *** 作工厂类。''' </summary>''' <remarks></remarks>Public Class DFactory    'Dim DataBase As String = "Access"    Dim DataBase As String = "sql"    Function createuserInfo() As IDAL.IUser        Dim db As IUser        Select Case DataBase            Case "sql"                db = New DAL.sqlserverUser                'Case "Access"                '   db = New DAL.AccessUser        End Select        Return db    End Function

NUMBER THREE我们是改变了 *** 作工厂case而用反射的方法,和case说拜拜。我们用case判断太过于发死,把字符串写死在了DALFactory中,我们对功能类的使用,不是功能类本身去决定自己。我们要自己决定自己的人生大事,所以用反射就可以了。这样解除了分支判断的耦合。

DALFactory代码。

imports IDALimports System.Reflection''' <summary>'''  *** 作工厂类。''' </summary>''' <remarks></remarks>Public Class DFactory    'Dim DataBase As String = "Access"    'Dim DataBase As String = "sql"    Dim strDB As String = System.Configuration.ConfigurationSettings.AppSettings("DBString")    Function createuserInfo() As IDAL.IUser                Return CType(Assembly.Load("DAL").CreateInstance("DAL.sqlserverUser" & strDB),IDAL.IUser)    End FunctionEnd Class


具体的功能类sqlserverUser,只是改了一句话。

 

Public Class sqlserverUser : Implements IDAL.IUser    Public Function GetUser(ByVal User As Entity.EN_User) As Entity.EN_User Implements IDAL.IUser.GetUser        'Dim ConnStr As String = "Data Source=192.168.24.169;Initial Catalog=PC_ChargeSys;User ID=sa;Pwd=123456"        Dim ConnStr As String = System.Configuration.ConfigurationSettings.AppSettings("ConnStr")        Dim conn As sqlConnection = New sqlConnection(ConnStr)        'Dim connection As New sqlHelp.ConnectionHelp        'connection.Connect()        Dim sql As String = "select * from tb_User where UserID='" & User.UserID & "'"        Dim cmd As sqlCommand = New sqlCommand(sql,conn)        Dim read As sqlDataReader        Dim myUser As New Entity.EN_User        Try            conn.open()            read = cmd.ExecuteReader            read.Read()            myUser.UserID = read.Item("")            myUser.UserPwd = read.Item("UserPwd")            Return myUser        Catch ex As Exception            myUser.UserID = 0            myUser.UserPwd = ""            Return myUser        End Try    End FunctionEnd Class


 工厂模式的基本原理见:http://www.voidcn.com/article/p-butonjbw-bep.html

 综上,我们把简单工厂、工厂方法、和抽象工厂三个模式在实际应用中进行了比较。我们的最佳组合是简单工厂改造的抽象工厂加上配置文件,耦合度和系统的开闭(对扩展开放、对修改封闭)、系统的可维护和灵活性尽在我们的三个包图中。笔者(me)认为,我们的设计模式就像数学公式,灵活运用就好。我们在开发一个系统的时候思考问题不要从上向下的思考方式,我们要从下向上,不是因为解耦而解耦,而是我们从系统长远的角度出发,使得我们在系统在不断的重构中发现问题,才去不断的思考,进一步的抽象,使得系统更加完美。没有完美的系统,只有完美的过程。

 

 

 

 

问题多多,欢迎您前来指教!

总结

以上是内存溢出为你收集整理的工厂模式的应用实例全部内容,希望文章能够帮你解决工厂模式的应用实例所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

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

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

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-02
下一篇 2022-06-02

发表评论

登录后才能评论

评论列表(0条)

保存