抽象工厂模式

抽象工厂模式

public class Main {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		User user=new User();
		SqlserverUser su=new SqlserverUser();
		su.Insert(user);
		su.GetUser(1);
	}

}
class User{
	private int id;
	private String name;
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}	
}
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;
	}
}

这里之所以不能换数据库,原因就在于SqlserverUser su= new SqlserverUser()使得su这个对象被框死在了SQL Server上了。如果这里是灵活的,是多态的,那么在执行su.insert(user)和su.getUser(1)时就不用考虑是在用SQL Server还是在用Access。--用 工厂方法模式来封装new SqlserverUser0所造成的变化。工厂方法模式是定义一个用户创建对象的接口,让子类决定实例化哪个类。

public class Main {
	public static void main(String[] args) {
		User user = new User();
		IFactory factory = new SqlserverFactory();
		//若要更改成Access只需要改此处的Sqlserver
		IUser iu = factory.CreateUser();
		iu.Insert(user);
		iu.GetUser(1);
	}
}

class User {
	private int id;
	private String name;

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}
}

//IUser接口,解除与具体数据库的耦合
interface IUser {
	void Insert(User user);

	User GetUser(int id);
}
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;
	}
}
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("在Sqlserver中根据ID得到User表一条记录");
		return null;
	}

}

interface IFactory {
	IUser CreateUser();
}

class SqlserverFactory implements IFactory {
	@Override
	public IUser CreateUser() {
		// TODO Auto-generated method stub
		return new SqlserverUser();
	}
}

class AccessFactory implements IFactory {

	@Override
	public IUser CreateUser() {
		// TODO Auto-generated method stub
		return new AccessUser();
	}

}

但是数据库里还会有其他表,如增加部门表(Department表)

public class Main {
	public static void main(String[] args) {
		User user = new User();
		IFactory factory = new SqlserverFactory();
		IUser iu = factory.CreateUser();
		iu.Insert(user);
		iu.GetUser(1);
		
		Department dept=new Department();
		IDepartment id=factory.CreateDepartment();
		id.Insert(dept);
		id.GetDepartment(1);
	}
}

class User {
	private int id;
	private String name;

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}
}

//IUser接口,解除与具体数据库的耦合
interface IUser {
	void Insert(User user);

	User GetUser(int id);
}
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;
	}
}
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中根据ID得到User表一条记录");
		return null;
	}

}

interface IFactory {
	IUser CreateUser();
	IDepartment CreateDepartment();
}

class SqlserverFactory implements IFactory {
	@Override
	public IUser CreateUser() {
		// TODO Auto-generated method stub
		return new SqlserverUser();
	}

	@Override
	public IDepartment CreateDepartment() {
		// TODO Auto-generated method stub
		return new SqlserverDepartment();
	}
}

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();
	}

}
class Department{
	private int id;
	private String deptName;
	public String getDeptName() {
		return deptName;
	}
	public void setDeptName(String deptName) {
		this.deptName = deptName;
	}
}
interface IDepartment{
	void Insert(Department department);
	Department GetDepartment(int id);
}
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;
	}
	
}
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中根据ID得到Department表一条记录");
		return null;
	}
	
}

抽象工厂模式的优点

  • 易于交换产品系列,由于具体工厂类,例如IFactory factory = new AccessFactory(),在一个应用中只需要在初始化的时候出现一次,这就使得改变一个应用的具体工厂变得非常容易,它只需要改变具体工厂即可使用不同的产品配置。设计不能去防止霄求的更改,理想便是让改动变得最小,现在如杲要更改数据库访问,只霄要更改具体的工厂。
  • 它让具体的创建实例过程与客户端分离,客户端是通过它们的抽象接口操纵实例,产品的具体类名也被具体工厂的实现分离,不会出现在客户端代码中。.上例中,客户端只认识IUser和IDepartment,至于它是用SQL Server来实现还是用Access来实现就不知道了。
    这个模式是开放_封闭原则,依赖倒转设计原则的良好运用。

抽象工厂模式的缺点

  • 抽象工厂模式可以很方便地切换两个数据库访问的代码,但是如杲霄求来自增加功能,如要增加项目表Project,就要至少增加三个类: Iprojeet、 SqlserverProject、AccessProject,还需要改IFactory.、SqlserverFactory和AccessFactory才可以实现。
  • 客户端程序类显然不会只有一个,有很多地方都在使用IUser或IDepartment,而这样的设计,在每一个类的开始都需要声明IFactory factory = new SqlserverFactory(),如具有100个调用数据库访问的类,就要更改100次IFactoryfactory = new AccessFactory()这样的代码。这不能解决更改数据库访问时,改动一处就完全更改的要求.
    大批量地改动,是非常丑陋的做法。
public class Main {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		User user=new User();
		Department dept=new Department();
		IUser iu=DataAccess.CreateUser();
		iu.Insert(user);
		iu.GetUser(1);
		IDepartment id=DataAccess.CreateDepartment();
		id.Insert(dept);
		id.GetDepartment(1);		
	}

}
class User{
	private int id;
	private String name;
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}	
}//IUser接口,解除与具体数据库的耦合
interface IUser {
	void Insert(User user);

	User GetUser(int id);
}
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;
	}
}
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中根据ID得到User表一条记录");
		return null;
	}

}
class Department{
	private int id;
	private String deptName;
	public String getDeptName() {
		return deptName;
	}
	public void setDeptName(String deptName) {
		this.deptName = deptName;
	}
}
interface IDepartment{
	void Insert(Department department);
	Department GetDepartment(int id);
}
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;
	}
	
}
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中根据ID得到Department表一条记录");
		return null;
	}
	
}
class DataAccess{
	private static String db="Sqlserver";
	//private static String db="Sqlserver";事先设置db的值
	public static IUser CreateUser() {
		IUser result =null;
		switch(db) {
		case "Sqlserver":result=new SqlserverUser();break;
		case "Access":result=new AccessUser();break;
		}
		return result;
	}
	public static IDepartment CreateDepartment() {
		// TODO Auto-generated method stub
		IDepartment result=null;
		switch(db) {
		case "Sqlserver":result=new SqlserverDepartment();break;
		case "Access":result=new AccessDepartment();break;		
		}
		return result;
	}
}

存在的问题:分支问题
若要增加Oracle数据库访问,本来抽象工厂只增加一个OracleFactory工厂类就可以了,现在修改量变大,需要在DataAccess类中每个方法的if分支语句里面增加。或者霄要修改所有switch,没有很好支持“开放-封闭”原则。
解决办法:
不在程序里写明‘如果是Sqlserver就去实例化SQL Server
数据库相关的类,如果是Access就去实例化Access相关的类’这样的语句,而是根据字符串db的值去某个地方找应该要实例化的类是哪一个。这样,就可以避免使用分支语句了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值