设计模式学习-抽象工厂模式

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

抽象工厂模式是工厂方法模式的升级版本,工厂方法模式只生产一个等级的产品,而抽象工厂模式可生产多个等级的产品。

抽象工厂模式与工厂方法模式的区别:
工厂方法模式只有一个抽象产品类,而抽象工厂模式有多个。工厂方法模式的具体工厂类只能创建一个具体产品类的实例,而抽象工厂模式可以创建多个。

优点:
(1)分离了具体的类。客户通过抽象接口操纵实例,产品的类名也在具体工厂的实现中被分离,它们不出现在客户代码中。
(2)易于交换产品系列。一个具体工厂类只在初始化时出现一次,这使得改变一个应用的具体工厂变得很容易,只需改变具体的工厂即可使用不同的产品配置。
(3)有利于产品的一致性。当一个系列的产品对象被设计成一起工作时,一个应用一次只能使用同一个系列中的对象,这一点很重要,而抽象工厂很容易实现这一点。

缺点:
当产品族中需要增加一个新的产品时,所有的工厂类都需要进行修改。

代码实现:
以数据访问程序为例
最基本的程序

创建用户类:

class User
{
private int _id;
private String _name;
public int get_id() {
return _id;
}
public void set_id(int _id) {
this._id = _id;
}
public String get_name() {
return _name;
}
public void set_name(String _name) {
this._name = _name;
}
}

创建SqlserverUser类——用于使用SQL server操作User表:

class SqlserverUser
{
//新增用户,
public void Insert(User user)
{
System.out.println(“在Sqlserver中给User表增加一条记录”);
}

//得到用户,
public User GetUser(int id)
{
    System.out.println("在Sqlserver中根据ID得到User表一条记录");
    return null;
}

}

客户端代码:

public static void Main(String[] args){
User user = new User();
SqlserverUser su = new SqlserverUser();//与SQL server耦合
su.Insert(user);//插入用户
su.GetUser(1);//得到ID为1的用户
}

这样无法选择其他数据库对User表进行操作,因为su这个对象被框死在SQL server上了,我们使用工厂方法模式对代码进行改进,增加Access类。

//IUser接口,用于客户端访问,解除与具体数据库的耦合,
interface IUser
{
void Insert(User user);

User GetUser(int id);

}

//SqlserverUser类,用于访问SQLServer的User,
class SqlserverUser implements IUser
{
//新增用户,
public void Insert(User user)
{
System.out.println(“在Sqlserver中给User表增加一条记录”);
}

//得到用户,
public User GetUser(int id)
{
    System.out.println("在Sqlserver中根据ID得到User表一条记录");
    return null;
}

}

//AccessUser类,用于访问Access的User
class AccessUser implements IUser
{
public void Insert(User user)
{
System.out.println(“在Access中给User表增加一条记录”);
}

public User GetUser(int id)
{
    System.out.println("在Access中根据ID得到User表一条记录");
    return null;
}

}

//IFactory接口,定义一个创建访问User表对象的抽象的工厂接口,
interface IFactory
{
IUser CreateUser();
}

//SqlServerFactory类,实现IFactory接口,实例化SqlserverUser,
class SqlServerFactory implements IFactory
{
public IUser CreateUser()
{
return new SqlserverUser();
}
}

//AccessFactory类,实现IFactory接口,实例化AccessUser,
class AccessFactory implements IFactory
{
public IUser CreateUser()
{
return new AccessUser();
}
}

客户端代码:

User user = new User();
IFactory factory = new SqlserverFactory();//若要改成Access数据库,只需将本句改成IFactory factory = new AccessFactory();
IUser iu = factory.CreateUser();
iu.Insert(user);
iu.GetUser(1);

现在要更换数据库,只需将new SqlserverFactory()改成new AccessFactory(),此时由于多态关系,使得声明IUser接口的对象iu事先根本不知道是在访问哪个数据库,却可在运行时很好的完成工作,这就是所谓的业务逻辑与数据访问的解耦。

数据库中不可能只有一个User表,现在增加一个部门表(Department表),就要用到抽象工厂模式了。

增加Department类:

class Department
{
private int _id;
private String _deptName;
public int get_id() {
return _id;
}
public void set_id(int _id) {
this._id = _id;
}
public String get_deptName() {
return _deptName;
}
public void set_deptName(String _deptName) {
this._deptName = _deptName;
}
}

IDepartment接口

interface IDepartment
{
void Insert(Department department);

Department GetDepartment(int id);

}
1
2
3
4
5
6
SqlserverDepartment类和AccessDepartment类

class SqlserverDepartment implements IDepartment
{
public void Insert(Department department)
{
System.out.println(“在Sqlserver中给Department表增加一条记录”);
}

public Department GetDepartment(int id)
{
	System.out.println("在Sqlserver中根据ID得到Department表一条记录");
    return null;
}

}

class AccessDepartment implements IDepartment
{
public void Insert(Department department)
{
System.out.println(“在Access中给Department表增加一条记录”);
}

public Department GetDepartment(int id)
{
	System.out.println("在Access中根据ID得到Department表一条记录");
    return null;
}

}

对于抽象工厂类和具体工厂类,只需在类内增加一个工厂接口并在具体工厂中实现:

//IFactory接口
interface IFactory
{
IUser CreateUser();
IDepartment CreateDepartment();//增加的接口方法
}

//SqlServerFactory类
class SqlServerFactory implements IFactory
{
public IUser CreateUser()
{
return new SqlserverUser();
}
public IDepartment CreateDepartment()
{
return new SqlserverDepartment();
}
}

//AccessFactory类
class AccessFactory implements IFactory
{
public IUser CreateUser()
{
return new AccessUser();
}
public IDepartment CreateDepartment()
{
return new AccessDepartment();
}
}

客户端代码:

User user = new User();
Department dept = new Department();
//IFacotory factory = new SqlserverFactory();
//只需确定实例化哪一个数据库访问对象给factory
IFacotory factory = new AccessFactory();

IUser iu = factory.CreateUser();

iu.Insert(user);
iu.GetUser(1);

IDepartment id = factory.CreateDepartment();

id.Insert(dept);
id.GetDepartment(1);

AbstractProductA和AbstractProductB是两个抽象产品,之所以为抽象,是因为它们都有可能有两种不同的实现,就刚才的例子来说就是User和Department,t而ProductA1、ProductA2和ProducB、ProductB2就是对两个抽象产品的具体分类的实现,比如ProductA1 可以理解为是SqlserverUser, 而ProductB1是SqlserverDepartment。IFactory 是一个抽象工厂接口,它里面应该包含所有的产品创建的抽象方法。而ConcreteFactory1和ConcreteFactory2就是具体的工厂了。就像SqlserverFactory和AccessFactory一样。在运行时刻再创建一个ConcreteFactory类的实例,这个具体的工厂再创建具有特定实现的产品对象,也就是说,为创建不同的产品对象,客户端应使用不同的具体工厂。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值