深入理解抽象工厂模式、状态模式

1,抽象工厂模式

提供给客户端一系列与需求相关的,相互依赖的接口,通过接口的调用的可变性来提高代码的适用性。举个例子,在开发中,我们使用不同的数据库的语法不一样,Oracle与Mysql例如分页上语法不一,MongoDB操作为指令性操作,后台通过getCommand()方法来操作MongoDB,因为需求的对数据库类型的改变就需要修改很多代码,通过抽象工厂模式可以起到灵活转换,代码使用性提高的作用。下面的代码省略了MongoDB实现User接口与创建MongoDB工厂的类。

public interface User {
	public void getUser();
	public void setUser();
}
public class SqlServerUse implements User {
	@Override
	public void getUser() {
		System.out.println("SqlServer获取User");
	}
	@Override
	public void setUser() {
		System.out.println("SqlServer插入User");
	}
}
public interface IFctory {
	public User createUser();
}
public class SqlServerFactory implements IFctory{
	@Override
	public User createUser() {
		return new SqlServerUse();
	}
}

抽象工厂模式的缺点:

看一下抽象工厂模式的架构图,虽然做到了设计模式中单一职责原则,对每个的类的修改变少了,但是抽象工厂模式只对既定的转换情况表现灵活性,对于需求转换的大更改,就会要求增加很多的类,使用起来并不方便。

用反射改进抽象工厂模式:

去掉抽象工厂模式中的IFactory与每个数据库具体实现返回实例的Factory类。用反射来实例化对象。这样对于需求的更改,只需要增加对实体类需要的数据库操作类就可以了,即上面的实现User的类。在设计中应该更多的减少原有代码上的更改,这里的代码可以通过Spring框架依赖注入的原理,在xml文件中配置databaseName,然后让ReflectFactoryUse去解析Xml拿到databaseName。

public class ReflectFactoryUse {
	private static String databaseName = "SqlServer";
	public User getUseFactory() throws InstantiationException, IllegalAccessException{
		String clazzName = "com.fyihan.abstractFactoryModel."+databaseName+"Use";
		Class clazz  = null;
		try {
			clazz= Class.forName(clazzName);
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
		return (User)clazz.newInstance();
	}
}

2,状态模式

当一个对象内部的状态发生了改变,同时行为也跟着发生改变。常规的操作会通过if...else if......else if...../switch ... case x:.....来对状态发的改变判断然后做出行为改变。状态模式,用于简化语句判断的冗长,让对象中状态发生改变时,行为改变就像改变了这个类。在具体的对象中,构造初始化最早发生的状态,然后通过对每个状态的封装来解决冗长问题,也方便日后需求修改,对于状态添加或者修改的需求。

abstract class State {
	abstract void handle(UsallyLife ul);
}
class TorrowLife extends State {
	@Override
	void handle(UsallyLife ul) {
		if(ul.hour == 9.00){
			System.out.println("现在是9点,状态:9点");
		}else{
			MoringLife ml = new MoringLife();
			ml.handle(ul);
		}
	}
}
class MoringLife extends State {
	@Override
	void handle(UsallyLife ul) {
		if(ul.hour==9.30){
			System.out.println("现在是9.30,是工作时间了,写代码");
		}else{
			LunchLife ll = new LunchLife();
			ll.handle(ul);
		}
	}
}
class LunchLife extends State {
	@Override
	void handle(UsallyLife ul) {
		if(ul.hour==12.00){
			System.out.println("现在是12.00午餐时间");
		}else{
			AfterLife al = new AfterLife();
			al.handle(ul);
		}
	}
}
class AfterLife extends State {
	@Override
	void handle(UsallyLife ul) {
		if(ul.hour==12.30){
			System.out.println("现在是下午时间12.30,开始学习,写代码");
		}
	}
}
class UsallyLife {
	double hour;
	private State state;
	UsallyLife(){
		this.state = new TorrowLife(); 
	}
	void writeUrl(UsallyLife ul){
		this.state.handle(ul);
	}
}
class Main {
	static void main(String[] args) {
		UsallyLife ul = new UsallyLife();
		ul.hour =9.00;
		ul.writeUrl(ul);
		ul.hour =9.30;
		ul.writeUrl(ul);
		ul.hour = 12.00;
		ul.writeUrl(ul);
		ul.hour =12.30;
		ul.writeUrl(ul);
	}
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值