常用的23种设计模式中,并不包含简单工厂,它其实不是一个设计模式,反而比较像一种编程习惯。但在程序中却经常使用。(在此之前,我一直以为简单的工厂是一种设计模式,不知你是否跟我认知是一样的。以前我以为我会两种设计模式:1.单例模式 2.简单工厂模式,到现在我真的不敢说我会设计模式了,因为我不确定仅剩下的“单例模式”是否正确)好了,言归正转。
我们先模拟一个买手机的场景
如果不采用简单工厂方法,我们的代码可能是这样的
假设:东和攀要买苹果手机--iphone5s 和iphone6 (这是一个产品实例,所以需要一个公共超类)
/**
* 定义手机超类
* @author jiazq
*
*/
public abstract class MobilePhone {
protected String name; //手机名称,有子类决定
/**
* 手机零件准备
*/
abstract void prepare();
/**
* 组装
*/
abstract void assemble();
/**
* 安装系统
*/
abstract void installSystem();
/**
* 最终测试
*/
abstract void finalTest();
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
实现类有iphone4s,iphone5s,iphone 6
代码如下:
public class IPhone4s extends MobilePhone {
public IPhone4s() {
this.name="iphone4s";
}
@Override
public void assemble() {
System.out.println(".....进行iphone 4s的组装.....");
}
@Override
public void finalTest() {
System.out.println(".....iphone 4s测试通过.....");
}
@Override
public void installSystem() {
System.out.println("安装iphone 4s的IOS系统");
}
@Override
public void prepare() {
System.out.println(".....准备iphone 4s的配件.....");
}
}
public class IPhone5s extends MobilePhone {
public IPhone5s() {
this.name="iphone5s";
}
@Override
public void assemble() {
System.out.println(".....进行iphone 5s的组装.....");
}
@Override
public void finalTest() {
System.out.println(".....iphone 5s测试通过.....");
}
@Override
public void installSystem() {
System.out.println("安装iphone 5s的IOS系统");
}
@Override
public void prepare() {
System.out.println(".....准备iphone 5s的配件.....");
}
}
public class IPhone6 extends MobilePhone{
public IPhone6() {
this.name="iphone6";
}
@Override
public void assemble() {
System.out.println(".....进行iphone 6的组装.....");
}
@Override
public void finalTest() {
System.out.println(".....iphone 6测试通过.....");
}
@Override
public void installSystem() {
System.out.println("安装iphone 6的IOS系统");
}
@Override
public void prepare() {
System.out.println(".....准备iphone 6的配件.....");
}
}
如果不采用简单工厂方法,我们的代码可能是这样的
public class IPhoneStore {
public IPhoneStore() {
super();
}
/**
* 通过直接new的方式创建MobilePhone产品
* @param type
* @return
*/
public MobilePhone orderPhoneByNew(PhoneType type){
MobilePhone phone;
if(type.equals(PhoneType.iphone4s)){
phone = new IPhone4s();
}else if(type.equals(PhoneType.iphone5s)){
phone = new IPhone5s();
}else if(type.equals(PhoneType.iphone6)){
phone = new IPhone6();
}else{
return null;
}
phone.prepare();
phone.assemble();
phone.installSystem();
phone.finalTest();
return phone;
}
}
说明:如果这样写
IPhoneStore 类在构造MobilePhone时候,直接依赖了iphone4s,iphone5s,iphone6.具体产品类,如果以后增加或者取消手机类型,IPhoneStore 就要不断做出增加或者修改,不易扩展。OO思想,其实IPhoneStore只想获取一个手机实例,不需要知道任何一款手机实际构造过程.所以我们将代码进行如下修改:
增加IPhone工厂类,为生产IPhone手机而生。
/***
* 生成IPhone 手机的工厂
* @author jiazq
*
*/
public class IPhoneFactory {
<span style="white-space:pre"> </span>public MobilePhone orderPhone(PhoneType type) {
<span style="white-space:pre"> </span>MobilePhone phone;
<span style="white-space:pre"> </span>if(type.equals(PhoneType.iphone4s)){
<span style="white-space:pre"> </span>phone = new IPhone4s();
<span style="white-space:pre"> </span>}else if(type.equals(PhoneType.iphone5s)){
<span style="white-space:pre"> </span>phone = new IPhone5s();
<span style="white-space:pre"> </span>}else if(type.equals(PhoneType.iphone6)){
<span style="white-space:pre"> </span>phone = new IPhone6();
<span style="white-space:pre"> </span>}else{
<span style="white-space:pre"> </span>return null;
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>return phone;
<span style="white-space:pre"> </span>}
}
在来看下IPhoneStore 类的使用
/**
* 通过工厂创建对象
* @author jiazq
*
*/
public class IPhoneStoreExp {
private IPhoneFactory factory;
public IPhoneStoreExp(IPhoneFactory factory) {
this.factory = factory;
}
/**
* 通过简单工厂创建产品
*
* @param type
* @return
*/
public MobilePhone orderPhoneByFactory(PhoneType type) {
MobilePhone phone =factory.orderPhone(type);
phone.prepare();
phone.assemble();
phone.installSystem();
phone.finalTest();
return phone;
}
}
外部测试代码:
<pre name="code" class="html">/***
* 外部测试类
* @author jiazq
*
*/
public class FactoryTest {
public static void main(String args[]){
//普通方式 向iphone专门店订购一条iphone手机
IPhoneStore phone = new IPhoneStore();
MobilePhone mobiePhone = phone.orderPhoneByNew(PhoneType.iphone5s);
System.out.println("向东订制的手机是:"+mobiePhone.getName());
//通过简单工厂订购手机
IPhoneStoreExp phoneExp = new IPhoneStoreExp(new IPhoneFactory());
MobilePhone phone6 =phoneExp.orderPhoneByFactory(PhoneType.iphone6);
System.out.println("攀儿订制的手机是:"+phone6.getName());
}
}
代码类图如下:
简单工厂,就是没有通过new直接创建对象,而是依赖工厂类去创建的对象(或许工厂方法是通过new来创建的对象)
这样不都是new创建的对象嘛,虽然工厂类也是使用的同样的代码,将依赖的对象提取到工厂类中好处有
1.可以实现代码复用(有可能还有其他地方会使用到)
2.通过简单工厂可以遵循“对扩展开发,对修改关闭”,使用类只能调用,不可修改,增加了代码的安全性,而工厂却可以扩展功能,调用者不需要改变任何代码.
上述:对扩展开放,修改关闭这一原则,其实简单工厂,并不能完全做到,如果业务扩展,要求增加生产Meizu或者华为类型手机那么
IPhoneFactory 是不满足的。直接增加相应MeizuStore,与MeizuStoreFacotry进行扩展,代码就会有冗余不能复用,而这里只是简单介绍,为下面的“工厂方法模式”和“抽象工厂模式”做铺垫.