《大话设计模式--抽象工厂模式》笔记

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

2、抽象工厂模式结构图:
在这里插入图片描述
3、简单代码实现
书上例子主要是切换两个不同的数据库。
user和department实体类

public class User {

	
	private String id;
	private String name;
	
	public String getId() {
		return id;
	}
	public void setId(String id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	
	
}

public class Department {

	private String id;
	private String deptName;
	public String getId() {
		return id;
	}
	public void setId(String id) {
		this.id = id;
	}
	public String getDeptName() {
		return deptName;
	}
	public void setDeptName(String deptName) {
		this.deptName = deptName;
	}
	
}

department和user持久层接口

interface IDepartment {

	void insert(Department department);
	Department getDepartment(int id);
}
public interface IUser {

	void insert(User user);
	User getUser(int id);
}

department持久层实现类,分为access类和sqlserver类;

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

}

public class SqlserverDepartment implements IDepartment {

	@Override
	public void insert(Department department) {
		
		System.out.println("在Sqlserver中增加一条department数据");
		
	}

	@Override
	public Department getDepartment(int id) {
		System.out.println("从Sqlserver中获取一条department数据");
		return null;
	}
	
	

}

user持久层实现类,分为access类和sqlserver类;

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) {
		System.out.println("从Access中获取一条user数据");
		return null;
	}

}

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) {
		System.out.println("从Sqlserver中获取一条User数据");
		return null;
	}

}

IFactory接口,定义一个创建持久层表对象的抽象工厂类

public interface IFactory {
	
	IUser createUser();
	IDepartment createDepartment();

}

Sqlserver类,实现IFactory接口,实例化sqlserver类型的两个持久层对象

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

}

Accessserver类,实现IFactory接口,实例化Accessserver类型的两个持久层对象

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

}

客户端代码

public class Client {
	
	public static void main(String[] args) {
		User user=new User();
		Department dept=new Department();
		
		
		//IFactory fa=new SqlserverFactory();
		IFactory fa=new AccessFactoy();
		
		IUser iu=fa.createUser();
		
		iu.insert(user);
		iu.getUser(1);
		
		IDepartment id=fa.createDepartment();
		
		id.insert(dept);
		id.getDepartment(1);
		
		
	}

}

抽象工厂模式的优缺点:
优点:
1、易于交换产品系列,具体工厂类,在一个应用中只需要在初始化的时候出现一次,这使得改变一个应用的具体工厂变得非常容易,只需改变工厂,便可以使用不同的产品配置。
2、他让具体的创建实例与客户端分离,客户端通过抽象接口操作实例,产品的具体类名也被具体工厂的实现分离,不会出现在客户端代码中
缺点:
1、当我们需要增加Project实体,需增加Iproject、sqlserverProject、AccessProject。还需要修改IFactory,SqlserverFactory,AccessFactory。

4、使用简单工厂方法改进上面的缺点
1、增加了dataAccess简单工厂类,客户端只需要createUser()和createDeptment() 。取代了IFactory、SqlserverFactory、AccessFactory。

public class DataAccess {

//	private static final String DB="Sqlserver";
	private static final String DB="Access";
	
	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 createDeptment() {
		IDepartment result=null;
		
		switch (DB){
		case "Sqlserver":
			result=new SqlserverDepartment();
			break;
		case "Access":
			result=new AccessDepartment();
			break;
		}
		
		return result;
	}
}

客户端代码

public class Client2 {
	
		
		public static void main(String[] args) {
			User user=new User();
			Department dept=new Department();
			
			
			IUser iu=DataAccess.createUser();
			
			iu.insert(user);
			iu.getUser(1);
			
			IDepartment id=DataAccess.createDeptment();
			
			id.insert(dept);
			id.getDepartment(1);
			
			
		}

	}

但是在添加需求和修改时仍需要修改dataAccess类的switch和case

5、使用反射来取代IFactory、SqlserverFactory、AccessFactory。

public class DataAccess2 {

	private static final String PACKAGE="practice.AbstractFactory";
//		private static final String DB="Sqlserver";
		private static final String DB="Access";
		
		public static IUser createUser() {
			IUser result=null;
			
			String className=PACKAGE+"."+DB+"User";
			
			try {
				result=	(IUser) Class.forName(className).newInstance();
			} catch (Exception e) {
			}
			
			return result;
		}
		public static IDepartment createDeptment() {
			IDepartment result=null;
			
            String className=PACKAGE+"."+DB+"Department";
			
			try {
				result=	(IDepartment) Class.forName(className).newInstance();
			} catch (Exception e) {
			}
			
			return result;
		}
	}


虽然解决了使用简单工厂出现的问题,但是在修改数据库是仍需要修改DB。

6、用反射加配置文件实现访问
添加一个config.properties

db=Access

修改后的dataAccess

public class DataAccess2 {

	private static final String PACKAGE="practice.AbstractFactory";
//		private static final String DB="Sqlserver";
	private static   String db="";
	//使用properties文件配置
	
	
	static {
		Properties p=new Properties();
		try {
			p.load(new FileInputStream("src/practice/AbstractFactory/reflection/config.properties"));
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		db=p.getProperty("db");
	}
		
		public static IUser createUser() {
			IUser result=null;
			
			String className=PACKAGE+"."+db+"User";
			
			try {
				result=	(IUser) Class.forName(className).newInstance();
			} catch (Exception e) {
			}
			
			return result;
		}
		public static IDepartment createDeptment() {
			IDepartment result=null;
			
            String className=PACKAGE+"."+db+"Department";
			
			try {
				result=	(IDepartment) Class.forName(className).newInstance();
			} catch (Exception e) {
			}
			
			return result;
		}
	}

客户端代码同上。

哇,完美解决

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值