(Java - SE)设计模式之工厂方法

(Java - SE)设计模式之工厂方法


从今天开始每天一篇关于记录23种设计模式中的设计思想!

今天来说的是工厂方法:

简而言之就是对于同一个目的你有不同的实现,但是恰好我们又不知道该使用哪一个实现面对这种情况我们就可以考虑使用工厂方法的设计思想。

其实书本上的例子看看即可,切不可去硬记它还是那句话这是一种思想模式化是具有灵魂的!

工厂方法的设计灵魂就在于像上面提到过的(某一模块的一个目的的多种行为实现我都提供好了,但是具体按照你自己的需求去选择用哪个就是你的事儿了)

来我们一起来看看Java中的工厂方法是怎么实现的?先贴出来我从书上看到的,然后谈谈利弊再贴出经过我改造的!

书上的工厂方法思想:

(书) - StorageInfo接口[用来强调目标功能]

public interface StorageInfo {

	// 定义存储功能
	public abstract void storage();
}

(书) - StorageInfo接口的实现类HardDiskImpl[作用提供具体的实现策略]

public class HardDiskImpl implements StorageInfo {

	@Override
	public void storage() {
		// 使用硬盘存储
		System.out.println("使用硬盘存储信息 ...");
	}

}

(书) - StorageInfo接口的实现类FloppyDiskImpl[作用提供具体的实现策略]

public class FloppyDiskImpl implements StorageInfo {

	@Override
	public void storage() {

		// 使用软盘存储
		System.out.println("使用软盘存储数据 ...");
	}

}

(书) - StorageFactory接口[工厂接口准备被指定命令的时候返回对应的实例]

public interface StorageFactory {

    // 返回构建 StorageInfo 接口实现类的实例
	public abstract StorageInfo builder();
}

(书) - StorageFactory接口的实现类[返回Xxx类的实例]

public class HardDiskFactory implements StorageFactory {

	@Override
	public StorageInfo builder() {
		
		return new HardDiskImpl();
	}

}

(书) - StorageFactory接口的实现类[返回Xxx类的实例]

public class FloppyDiskFactory implements StorageFactory {

	@Override
	public StorageInfo builder() {
		
		return new FloppyDiskImpl();
	}

}

(书) - 测试

	@Test
	public void testBookCode() {
		StorageFactory sf = new HardDiskFactory();
		sf.builder().storage();// 打印 使用硬盘存储信息 ...
		
		sf = new FloppyDiskFactory();
		sf.builder().storage();// 打印 使用软盘存储数据 ...
	}

如此便实现了工厂的思想,书上是借助这种方式实现的,那么看到这里很多人就有问题了。典型问题如下:

-1).为什么要搞这些花花肠子?直接new不好吗?

回答:不好,因为直接new虽然可以但是你想想,我们要做的事情测初衷就是有一致目的的两种实现策略,说明二者功能上是一样的这就是我们为什么要用接口将其功能抽取的原因也是为什么将其聚合的原因,倘若行为 不相干的两个类我们通过接口来约束它们有何意义呢?

接着向下刨

我们的最终目的是要那两个行为策略所在实现类的实例,而要想获取他们的实例其接收类型必须是他们实现的接口StorageInfo,这也就是为什么我们在定义工厂接口方法中返回值类型是StorageInfo接口的原因了。

 

-2).按照这种做法那岂不是需要很多的工厂的实现类来返回实例吗?

对,按照书上的做法是这样的。这应该也算是一个弊端的,但是我们稍加修改就可以干掉这个弊端,如果要写太多的工厂的实现类真实让人头疼,不利于扩展!

 

改进:

其它代码不变,写一个通用的工厂接口的实现类

(己)StorageFactoryImpl

public class StorageFactoryImpl<E extends StorageInfo> implements StorageFactory {

	private Class<?> clazz;
	
	// 无参构造器
	public StorageFactoryImpl(Class<?> clazz) {
		this.clazz = clazz;
	}
	
	@SuppressWarnings("unchecked")
	@Override
	public StorageInfo builder() {
		Object instance = null;
		try {
			// 通过反射创建指定类型的实例
			instance = clazz.newInstance();
		} catch (InstantiationException | IllegalAccessException e) {
			e.printStackTrace();
		}
		// 转型
		return (E) instance;
	}

}

这样的话我们仅仅需要一个工厂接口的实现类就可以完成原来的工作。

(己)测试

	@Test
	public void testBookCode() {
		StorageFactory sf = new StorageFactoryImpl<HardDiskImpl>(HardDiskImpl.class);
		sf.builder().storage();// 打印 使用硬盘存储信息 ...
	}

上面就是今天探讨的设计模式中的工厂方法,如有不对之处还请不吝赐教!

 

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值