场景问题
假设一个网站的数据来源于数据库SQL Server,当网站进行维护时,增加或删除功能,在数据库做改动,相应的程序代码也必须改动,此时维护的工作量是很大的。再比如遇到要用到Oracle数据库,改动的地方更多。因此应该提供不同的数据库访问接口,通过组装来应对不同的需求变更。
用工厂方法模式的数据访问
Iuser接口: 用于客户端访问,解除与具体的数据库访问的解耦
package factory;
interface IUser {
void Insert(User user);
User GetUser(int id);
}
SqlServerUser类:用于访问SQL Server的User
package factory;
public class SqlServerUser implements IUser {
@Override
public void Insert(User user) {
// TODO Auto-generated method stub
System.out.println("在sqlserver中给User表增加一条记录");
}
@Override
public User GetUser(int id) {
// TODO Auto-generated method stub
System.out.println("在sqlserver中根据ID得到user表的一条记录");
return null;
}
}
AccessUser类:用于访问Access的User
package factory;
public class AccessUser implements IUser {
@Override
public void Insert(User user) {
// TODO Auto-generated method stub
System.out.println("在Access中给User表增加一条记录");
}
@Override
public User GetUser(int id) {
// TODO Auto-generated method stub
System.out.println("在Access中给User表增加一条记录");
return null;
}
}
IFactory接口:定义一个创建访问User表对象的抽象的工厂接口
package factory;
public interface IFactory {
IUser CreateUser();
}
SqlServerFactory类:实现IFactory接口,实例化SqlServerUser
package factory;
public class SqlServerFactory implements IFactory {
@Override
public SqlServerUser CreateUser() {
// TODO Auto-generated method stub
return new SqlServerUser();
}
}
AccessFactory类:实现IFactory接口,实例化AccessUser
package factory;
public class AccessFactory implements IFactory {
@Override
public IUser CreateUser() {
// TODO Auto-generated method stub
return new AccessUser();
}
}
客户端代码:
package factory;
public class Client {
public static void main(String[] args) {
User user = new User();
/**
* 此处如果是Access数据库,只需要将本其改为
* IFactory factory = new AccessFactory();
*/
IFactory factory = new SqlServerFactory();
IUser iUser = factory.CreateUser();
iUser.Insert(user);
iUser.GetUser(1);
}
}
用抽象工厂模式的数据访问程序
代码结构图:
IDepartment接口:用于客户端访问,解除与具体数据库访问的耦合
package factory;
public interface IDepartment {
void Insert(Department department);
Department GetDepartment(int id);
}
SqlServerDepartment类:用于访问SQL Serv er的Department
package factory;
public class SqlServerDepartment implements IDepartment {
@Override
public void Insert(Department department) {
// TODO Auto-generated method stub
System.out.println("在sqlserver中给Department表增加一条记录");
}
@Override
public Department GetDepartment(int id) {
// TODO Auto-generated method stub
System.out.println("在sqlserver中根据ID得到Department表的一条记录");
return null;
}
}
AccessDepartment类:用于访问Access的Department
package factory;
public class AccessDepartment implements IDepartment {
@Override
public void Insert(Department department) {
// TODO Auto-generated method stub
System.out.println("在Access中给Department表增加一条记录");
}
@Override
public Department GetDepartment(int id) {
// TODO Auto-generated method stub
System.out.println("在Access中给Department表增加一条记录");
return null;
}
}
IFactory接口:增加了创建部门的接口方法
package factory;
public interface IFactory {
IUser CreateUser();
/**
* 增加了接口方法
* @return
*/
IDepartment CreateDepartment();
}
SqlServerFactory类:实现IFactory接口,实例化SqlServerUser和SqlServerDepartment
package factory;
public class SqlServerFactory implements IFactory {
@Override
public SqlServerUser CreateUser() {
// TODO Auto-generated method stub
return new SqlServerUser();
}
@Override
public IDepartment CreateDepartment() {
// TODO Auto-generated method stub
return new SqlServerDepartment();
}
}
AccessFactory类:实现IFactory接口,实例化AccessUser和AccessDepartment
package factory;
public class AccessFactory implements IFactory {
@Override
public IUser CreateUser() {
// TODO Auto-generated method stub
return new AccessUser();
}
@Override
public IDepartment CreateDepartment() {
// TODO Auto-generated method stub
return new AccessDepartment();
}
}
客户端代码:
package factory;
public class Client {
public static void main(String[] args) {
User user = new User();
Department department = new Department();
/**
* 只需要确定实例化哪一个数据库访问对象给factory
*/
IFactory factory = new AccessFactory();
IUser iUser = factory.CreateUser();
iUser.Insert(user);
iUser.GetUser(1);
IDepartment id = factory.CreateDepartment();
id.Insert(department);
id.GetDepartment(1);
}
}
抽象工厂模式
抽象工厂模式(Abstract Factory):提供一个创建一系列相关或依赖对象 的接口,无需指定它们具体的类
结构图:
AbstractProductA和AbstractProductB是两个抽象产品,之所以抽象,是因为他们可能有不同的实现方法。
IFactory是一个抽象工厂的接口,包含所有产品创建的抽象方法,ConcreteFactory1和ConcreteFactory2就是具体的工厂
通常在运行时刻再创建一个ConcreteFactory类的实例,这个具体的工厂再创建具体特定的产品,不同产品对象,客户端用不同的具体工厂
抽象工厂模式的优缺点
好处:
1 易于交换产品,具体工厂类只需要在初始化时实例化一次,之后可改变具体工厂使用不同产品。
2 具体的创建实例的过程与客户端分离,客户端通过它们的抽象接口操纵实例,产品的具体类名也被具体工厂实现分离
缺点:在增加功能时修改的类会比较多,如增加产品,至少会修改接口和若干实现类