1.概述1.1意图 外观模式定义了一个将子系统的一组接口集成在一起的高层接口,以提供一个一致的界面。通过这个界面,其他系统可以方便地调用子系统中的功能,而忽略子系统内部发生的变化。1.2使用场合 在如下情况下可以使用外观模式。(1)为一个比较复杂的子系统提供一个简单的接口。(2)将客户程序与子系统的实现部分分离,提高子系统的独立性和可移植性。(3)简化子系统间的依赖关系。1.3 结构 下图所示为外观模式的结构。由于该模式的引入,所以外界访问通过这个统一接口进行,系统的复杂性得到降
上天保佑收录:
http://gnhao.blog.163.com/blog/static/719145320135139746163/
http://blog.sina.com.cn/s/blog_5676ce6b0101ef69.html
http://blog.tianya.cn/blogger/post_read.asp?BlogID=4545397&PostID=51297129
低。 在实际中,我们不仅可以从软件逻辑上划分出子系统或者独立的功能模块,并且可以通过将它们封装为某一类型的组件,使其在物理上获得独立。不仅可以单独使用,还有利于系统的升级。 在Windows系统下,可以将一个软件划分后的部分封装为动态接库。然后由主程序调用这些动态接库,封装在动态库中的类(或功能模块)通过外观模式接口与外界发生联系。 1.4效果 外观模式为用户提供了使用子系统组件的简化的接口,使用户减少了处理对象的数目,并且使子系统使用简单。 使用外观模式使子系统和客户之间实现松耦合关系,由于客户针对其接口编程,因此子系统的变化不会影响客户的变化,即其有助于分层体系结构的实现。外观模式并没有限制客户使用子系统类,仍可以直接使用子系统中的类。2.数据库访问外观模式 在前面已经介绍了有关数据库访问的内容,只是角度不同,其中的部分代码如下。 1PublicMustInheritClassclsAbstractDBClassclsAbstractDB2ProtectedmConnStringAsString3PublicPropertyConnString()PropertyConnString()AsString4Get5ReturnmConnString6EndGet7Set(ByValValueAsString)8mConnString=Value9EndSet10EndProperty1112PublicSubNew()SubNew(ByValcsAsString)13mConnString=cs14EndSub1516PublicMustOverrideSubOpen()SubOpen()17PublicMustOverrideSubclose()Subclose()18PublicMustOverrideFunctionExecSQL()FunctionExecSQL(ByValstrSQLAsString)AsDataTable19PublicMustOverrideSubExecSQLNonQuery()SubExecSQLNonQuery(ByValstrSQLAsString)20PublicMustOverrideFunctionTrateDateField()FunctionTrateDateField(ByValstrDateValueAsString)AsString21EndClass22
ClsAbstractDB定义了外观模式的接口,在针对具体数据库中实现了对Connection、Command和DataAdpter的封装。以ClsAbstractDB为例,代码如下: 1PublicClassclsSQLServerDBClassclsSQLServerDB2InheritsclsAbstractDB3PrivatemConnAsData.SqlClient.SqlConnection4PublicSubNew()SubNew(ByValcsAsString)5MyBase.New(cs)6mConn=NewData.SqlClient.SqlConnection7EndSub8PublicOverridesSubclose()Subclose()9IfmConn.StateConnectionState.ClosedThen10mConn.Close()11EndIf12EndSub1314PublicOverridesFunctionExecSQL()FunctionExecSQL(ByValstrSQLAsString)AsSystem.Data.DataTable15DimdtAsDataTable16DimdbCommAsNewData.SqlClient.SqlCommand(strSQL)17DimdbAptAsNewData.SqlClient.SqlDataAdapter(dbComm)18dbComm.Connection=mConn19dbApt.Fill(dt)20Returndt21EndFunction2223PublicOverridesSubExecSQLNonQuery()SubExecSQLNonQuery(ByValstrSQLAsString)24DimdbCommAsNewData.SqlClient.SqlCommand(strSQL)25dbComm.Connection=mConn26dbComm.ExecuteNonQuery()27EndSub2829PublicOverridesSubOpen()SubOpen()30IfmConn.State=ConnectionState.ClosedThen31mConn.ConnectionString=mConnString32mConn.Open()33EndIf34EndSub3536PublicOverridesFunctionTrateDateField()FunctionTrateDateField(ByValstrDateValueAsString)AsString37Return"#"strDateValue"#"38EndFunction3940ProtectedOverridesSubFinalize()SubFinalize()41MyBase.Finalize()42mConn=Nothing43EndSub44EndClass45
这样,当客户端软件需要执行SQL语句时,只要调用ExecSQL方法即可。3.分层结构与外观模式 分层体系结构是一个时髦的话题,理论上讲,分层结构可以使系统更为清晰,更具可维护性。然而,在实践中,如果层次划分不合理,就会产生数据和功能的冗余。 需要注意的是分层的原则,即业务类负责的是业务处理,还是数据缓存。必须说明的是,层次的划分按照功能进行,而数据是在层次之间的传递。 在实现分层设计时,我们不希望层次之间有跨越;否则分层实际上没有太多意义。然而,层次之间的界面经常很难划分清楚,可以采用外观模式封装层次。在设计时可以规定,对英雄模范一层次的访问必须经过外观对象。即确保外观是层次对外的惟一接口,编程从员面对的只是其他层次的外观。这样,就保证了层次仅与相临的部分交互。4.封装子系统 系统升级时,经常是一个大系统的若干子系统分别升级。这时需要封装遗留的子系统,以对外提供一个简单的接口。这种封装可以减少子系统的变化对与它接口的系统的影响,只要接口不发生变化,子系统即可作为孤立的模块升级。 在系统升级过程中,我们不主张将所有的代码升级为新的版本,如从VB 6升级到VB.NET。因为升级过程会遇到各种不确定性,这种不确定性增加了系统实施的风险,在升级体系结构,要达到这个目的,首先要封装子系统。如升级VB 6,可以将可隔离的代码封装为DLL,以被VB.NET引用。完成体系结构升级后,再逐一更新。为了降低新系统和遗留系统的耦合性,可以采用外观模式,封装接口部分的功能,仅能够通过这个接口访问遗留系统。这时,外观模式的实现可以用下图表示。 可以看出,这种结构与适配器模式有些类似,并且目的也一致,不同的是这里针对的目标系统粒度要大得多。 5.子系统隔离 升级与整合一个包含多个子系统的信息系统时,需要隔离这些子系统,以降低耦合性。隔离后,每个部分可以实现单独的渐进演化,整个系统的实施可以采用并行方式进行。由于各子系统只是针对外观模式界面操作,所以各个子系统的不同版本可以同时协同工作,这样便于系统的动态实施。 外观模式对于子系统间耦合强的系统尤其有用,这一点对解决实际系统的同步实施很有帮助。在实际系统的实施中,往往由于各单位无法统一安排实施时间而被一拖再拖。6.系统演化 当渐进演化原有系统时,可以采用外观模式封装原系统。首先开发新系统的表示层,业务逻辑采用原有系统。然后逐步修改各个功能模块,并替换原有系统,如下图:
来源:https://www.cnblogs.com/gnhao/archive/2013/01/24/2875144.html