徐 宏
(太原城市职业技术学院,山西 太原 030027)
利用案例教学法由浅入深地讲解抽象工厂模式
徐 宏
(太原城市职业技术学院,山西 太原 030027)
文章主要阐述了抽象工厂模式,通过利用案例教学法进行讲解,让学员彻底理解并会使用抽象工厂设计模式。
抽象工厂模式;案例教学法;讲解
抽象工厂模式是所有形态的工厂模式中最为抽象和最具一般性的一种形态。抽象工厂模式是指当有多个抽象角色时,使用的一种工厂模式。抽象工厂模式可以向客户端提供一个接口,使客户端在不必指定产品的具体的情况下,创建多个产品族中的产品对象。根据LSP原则,任何接受父类型的地方,都应当能够接受子类型。因此,实际上系统所需要的,仅仅是类型与这些抽象产品角色相同的一些实例,而不是这些抽象产品的实例。换言之,也就是这些抽象产品的具体子类的实例。工厂类负责创建抽象产品的具体子类的实例。
学生在利用该设计模式开发项目的时候,往往只是机械地照搬教师的源代码,并没有真正理解抽象工厂的含义。那么如何讲解好这个知识点呢?在实际的授课过程中,笔者总结了讲解这个难点的方法和技巧,总结出来与大家共享。
这里,笔者采用了案例教学法,层层深入,大约需要3个阶段把这个难点讲解完成。具体的思路是:首先,让学员明白引入接口的原因;其次,讲解使用简单工厂的便利;最后,讲解使用抽象工厂是锦上添花。
文章所使用的案例是一个用VS2008开发的用户登录程序。
第一阶段:讲解接口的引入,为什么要使用接口呢?这里需要跟学生说明,目前的软件产品大部分都会和数据库进行交互,但每个公司或企业不可能使用同样的数据库。例如,一个工资管理系统,大公司可能使用SQLServer,而小公司可能使用Access就够用了,那么如何让一套程序既可使用SQLServer,又可使用Access作为数据库呢?答案是我们在数据访问层使用统一的接口,让访问SQLServer和Access的类都实现这个接口,然后通过接口调用具体的实现。
具体的演示方法是在用户登录系统的基础上点击DAL层的类,右键选择重构,选择提取接口,这样一个接口就出现了,见图1。
这里为了更加的规范,新建一个接口层的类库IDAL,将这个接口移到这个类库IDAL中,见图2。
接口建立以后,为了可以使用Access库,添加新的数据层AccessDAL,再添加一个AccessUserDAL类并实现刚才创建的接口。最后修改BLL层的调用方式为接口调用,用接口隐示的声明,用类显示的实现调用,对于访问SQLServer数据库具体的代码是:
图2 ISqlUserDAL dal=new Demo.DAL.SqlUserDAL();
如果需要访问Access库,稍加改动就变成访问Access库,具体代码是:
ISqlUserDAL dal=new Demo.AccessDAL.AccessUserDAL();
第二阶段:首先给学生提出问题:接口就可以实现访问不同的数据库我们为什么采用工厂模式呢?原因有两个:第一是客户提出新需求,自己不改变源码就更换为其他数据库;第二是从开发公司考虑,为了适应不同的数据库,每次需要修改BLL层源代码,再编译程序,发布程序比较麻烦。那么具体实现步骤是创建新的工厂项目类,添加类SFactory,然后在类中实现返回实现产品接口的方法,具体代码如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Demo.SFactory
{
public class Factory
{
static string strDBType=
System.Configuration.ConfigurationManager.AppSettings["DBType"].ToString();
public static Demo.DAL.IUserDALCreatUserInfo()
{switch(strDBType)
{ case"sqlServer":
return new Demo.DAL.UserDAL();
break;
case "Access":
return new Demo.AccessDAL.UserAccessDAL();
break;
default:
return null;
}
}
}
}
通过Web.Config读取配置数据,针对不同数据库,返回不同实现接口的对象,最后修改BLL层的调用方式为简单工厂调用,用接口隐示声明,但是实现通过工厂创建,代码如下:
privatestatic IUserInfodb=SFactory.CreateDalUserInfoInstance();
配置文件App.Config代码如下:
="Provider=Microsoft.Jet.OLEDB.4.0;Data Source=D:Three-FrameDemoUIDemoUIinDebugAccessDb.mdb"/> 这样我们就可以通过修改配置文件实现不同数据库的访问,实现了简单工厂的设计模式。 第三阶段:讲解抽象工厂的实现,有了简单工厂,为什么还要使用抽象工厂呢,原因是一个大的软件项目中包括很多的模块,不同的模块就要创建不同的接口,那么如何返回很多实现接口的对象呢,在简单工厂模式中只能编写多块相似的代码,通过判断数据库的类型返回具体的对象,这样就造成大量的代码冗余。这里采用优化的方法,即抽象公共的部分,通过抽象类调用具体的实现类,可以产生一批有关联的产品,例如通过配置文件读取是Access数据库类型,那么得到是Access的工厂,工厂里的产品都是通过访问Access数据库数据产生的产品。可以说对于简单工厂模式一次只能创建一个对象,而对于抽象工厂模式实现一次创建一系列相互依赖对象的需求。 具体的演示实现步骤是首先通过修改前面的编写的简单工厂SFactory类为抽象工厂类,添加相应的抽象方法,通过读取对应的配置文件,返回实现抽象类的工厂;然后创建一个具体工厂类SQLFactory继承这个抽象工厂类,重写抽象方法,只返回具体SQLServer库的实现;最后创建新的Access具体工厂类,添加类AccessFactory,让它也继承抽象工厂类,重写抽象方法。另外,不要忘记修改BLL层的调用方式为抽象工厂调用,具体的代码是先得到一个工厂,然后再得到相应产品。具体的代码是: private static AbsDALFactory factory=AbsDALFactory.Choose-Factory(); private static IUserInfo db=factory.CreateDalUserInfoInstance(); 这样我们就将数据访问层的内容进行了细化,首先引入接口,再使用简单工厂,然后引入抽象工厂模式,通过演示让学员明白为什么要使用简单工厂和抽象工厂以及如何使用它。具体思路见图3。 图3 使用简单工厂和抽象工厂的具体思路 这里演示完成后,如果学生还无法透彻地理解抽象工厂模式,下面共享一个生活案例给大家,通过案例剖析抽象工厂的实现方式: 图4 抽象工厂 客户是什么?这里我们说的客户是指调用者,具体而言如网站的美工设计人员。那么地图是什么呢?指配置文件,快餐点比喻我们的抽象工厂,汉堡和鸡腿比喻抽象产品,客户即调用者只知道这些,具体的哪个快餐店,如何制作什么汉堡,客户并不关心,只要能到最方便的快餐店吃到汉堡,填饱肚子即可。具体的工厂是肯德基和麦当劳,具体产品是KFC的汉堡、KFC鸡腿,他们这一组是相关的,另外一组是McDonald汉堡、McDonald鸡腿,他们两个是相关的,是可以左手拿着McDonald汉堡,右手拿着Mc-Donald鸡腿狼吞虎咽的;我们把相关的产品,称为一系列的产品,你还想吃薯条,稍微扩展一下,加一个薯条的产品,包括抽象薯条和具体的薯条。如下图所示:蓝色框图中的肯德基的汉堡、鸡腿和薯条是相关的,一系列的,由此可以看出抽象工厂设计模式给客户提供的不再是单一的产品,而是提供一批系列的产品。 图5 抽象工厂二 通过层层深入的代码演示,再结合生活案例来理解抽象工厂,希望大家能够掌握简单三层到抽象工厂的讲解技巧,在实际的授课中深入浅出、步步为营熟练地进行代码演示,让学员彻底理解并会使用抽象工厂设计模式。 Explains the Abstract Factory Pattern from the Shallow to the Deep Using the Case Teaching Method Xu Hong The article mainly elaborated the abstract factory pattern,through carries on the explanation using the case teaching method,will let the student understand and use the abstract plant design pattern thoroughly. abstract factory pattern;case teaching method;explanation G712 A 1000-8136(2010)32-0107-033 总结