《head first》书上举的例子讲的还是Pizza的例子,只不过这次是用的原料来模拟抽象共工厂模式,类太多,感觉还是大话的这个例子更贴近一点,类相对来说也少,更加清晰。大话上的例子说的是利用抽象工厂模式模拟实现不同数据库的数据访问。
抽象工厂模式提供了一个接口,用于创建相关或依赖对象的家族,而不需要明确制定具体类。
感觉看例子还是非常容易懂的。
1.首先是两个实体类,此处只列出User,Department一样
package abstractfactory;
public 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 getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
2.IUser接口,借出于具体数据库访问的耦合,感觉有点像实现DAO层时,先定义增删改查等各种方法的接口,IDepartment接口定义类似
package abstractfactory;
public interface IUser {
public void insert(User user);
public User getUser(int id);
}
3.针对IUser接口的实现,模拟SqlServer和Access的数据库操作。
SqlServerUser类
package abstractfactory;
public class SqlServerUser implements IUser{
public User getUser(int id) {
System.out.println("在SQL SERVER中根据ID得到User表的一条记录");
return null;
}
public void insert(User user) {
System.out.println("在SQL SERVER中给User表增加一条记录");
}
}
AccessUser类
package abstractfactory;
public class AccessUser implements IUser {
public User getUser(int id) {
System.out.println("在Access中根据ID得到User表的一条记录");
return null;
}
public void insert(User user) {
System.out.println("在Access中给User表增加一条记录");
}
}
3.IFactory接口,定义一个访问数据库表对象的抽象的工厂接口,相当于图中的AbstractFactory
package abstractfactory;
public interface IFactory {
IDepartment createDepartment();
IUser createUser();
}
对IFactory的实现类SqlServerFactory package abstractfactory;
public class SqlServerFactory implements IFactory{
public IDepartment createDepartment() {
return new SqlServerDepartment();
}
public IUser createUser() {
return new SqlServerUser();
}
}
对IFactory的实现类AccessFactory
package abstractfactory;
public class AccessFactory implements IFactory{
public IDepartment createDepartment() {
return new AccessDepartment();
}
public IUser createUser() {
return new AccessUser();
}
}
4.最后是测试类
package abstractfactory;
public class Test {
public static void main(String[] args) {
User user = new User();
Department department = new Department();
IFactory factory = new SqlServerFactory();
//factory = new AccessFactory();
IUser iUser = factory.createUser();
iUser.insert(user);
iUser.getUser(1);
IDepartment id = factory.createDepartment();
id.insert(department);
id.getDepartment(1);
}
}
从上面的例子中,我们可以看到全部都是一个接口,然后一个实现类,除了实体类和测试类之外,我们很明显可以看到抽象工厂的缺点就是类太多,比如增加个一个实体类Entity,不是又需要添加IEntity、SqlServerEntity、AccessEntity等,所以书中改进的方法是利用了简单工厂替换抽象工厂,针对不同的实体都变成DataAcess类的静态方法。
应用的话,感觉就这个例子就挺形象的,如果我们封装了此处的IUser,把它设计成系统的DAO层,通过这样的封装,可以屏蔽掉不同的数据库访问的差异,可以快速的在不同数据库之间相互切换。其实针对不同的数据库的访问,更常见的是根据反射+配置文件实现数据访问程序,一般web程序中都是自定义一个jdbc.properites文件,该文件是一个个键值对,定义连接数据库的配置属性。
如果文章有什么错误或者有什么建议,欢迎提出,大家共同交流,一起进步
文章转载请注明出处,请尊重知识产权