工厂模式的定义: 定义一个用于创建对象的接口,让子类决定实例化哪个类,工厂方法使得一个类的实例化延迟到其子类。 上面的定义比较官方,其实就个人的理解工厂方法就相当于一个黑盒,我们传入一个所需产品的识别标示,工厂就会自动产生我们所需要的产品,我们无须理解其中繁杂的创建过程,只要知道所产生产品所能提供的方法就可以了。 还有个优点就是,只要产品的接口不变,那么上层的应用就无须修改,我们如果需要扩展或者需要修改具体的实现只要动中间层即可,比如我们要扩展只要增加产品类即可,如果需要修改只需要修改产品类即可。
工厂模式的变体: 将工厂简化为静态工厂
决定产生何种产品的决定因素可以是如下几种方式: 1.工厂类的传入参数 2.读取配置文件 3.某个运行时参数或者状态量
工厂方法的返回值,可以是接口,抽象类,具体类。 public interface AbsProduct { public void doSomething () ; }
public class ProductImplA implements AbsProduct { @Override public void doSomething () { System.out .println("This Message is Come from " + ProductImplA.class .getSimpleName()); } }
public class ProductImplB implements AbsProduct { @Override public void doSomething () { System.out .println("This messsage is come from " + ProductImplB.class .getSimpleName()); } }
public class ProductImplC implements AbsProduct { @Override public void doSomething () { System.out .println("This massage is come from " + ProductImplC.class .getSimpleName()); } }
public interface AbsFactory { public <T extends AbsProduct> T createProduct (Class<T> clzz) ; }
public class FactoryImpl implements AbsFactory { @Override public <T extends AbsProduct> T createProduct(Class<T> clzz) { AbsProduct product = null ; try { product = (T) Class.forName(clzz.getName()).new Instance (); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } return (T) product; } }
public class FactoryTestMain { public static void main(String args[] ) { AbsFactory factory = new FactoryImpl() ; AbsProduct product; product= factory.createProduct(ProductImplA.class ) ; product.do Something() ; product = factory.createProduct(ProductImplB.class ) ; product.do Something() ; product = factory.createProduct(ProductImplC.class ) ; product.do Something() ; } }
工厂方法还有种比较好用的变体,其实也算不上什么变体,就是在工厂内部定义完成操作的方法,然后我们扔进去一个类型,指定要什么类型的对象来完成这个操作,这时候外部无须获取产品类型,直接调用工厂里面的方法即可 工厂父类一般是抽象方法,主要有两种类型,一个是抽象工厂方法用于产生抽象产品,另一类是使用抽象产品完成的操作方法。这样产品类就不需要抛头露面了。结构如下:
public abstract class AbstractFactory { protected AbstractProduct product = null ; protected int productType = -1 ; public abstract AbstractProduct createFactory () ; public abstract void setProductType (int type ) ; public void doSomeThing () { product = createFactory(); if (product != null ) { product.doSomethingA(); product.doSomethingB(); } } }
public interface AbstractProduct { public void doSomethingA () ; public void doSomethingB () ; }
public class ConcreFactory extends AbstractFactory { @Override public AbstractProduct createFactory() { if (super .productType == 0 ) { return new ConcreProductA (); }else if (super .productType == 1 ) { return new ConcreProductB (); } return null ; } @Override public void setProductType(int type ) { super .productType = type ; } }
public class ConcreProductA implements AbstractProduct { public void doSomethingA () { System.out .println("ConcreProductA doSomething A" ); } public void doSomethingB () { System.out .println("ConcreProductA doSomething B" ); } }
public class ConcreProductB implements AbstractProduct { public void doSomethingA () { System.out .println("ConcreProductB doSomething A" ); } public void doSomethingB () { System.out .println("ConcreProductB doSomething B" ); } }
public class Client { public static void main(String args[] ) { ConcreFactory factory = new ConcreFactory() ; factory.do SomeThing() ; factory.setProductType(0) ; factory.do SomeThing() ; factory.setProductType(1) ; factory.do SomeThing() ; factory.setProductType(2) ; factory.do SomeThing() ; } }
抽象工厂 虽然工厂模式与抽象工厂模式都带有“工厂”两个字,但是二者所要解决的问题是不同的,工厂模式主要解决的问题是屏蔽产品类创建的繁杂过程,只要知道想获得什么的时候传入什么,以及产生的产品有哪些方法即可,而抽象工厂模式解决的是如何产生一个产品簇,这种产品往往有一定约束条件的的,与其称之为抽象工厂方法,而不如称其为方案工厂方法,因为往往产生的是一整套配套的方案。 下面我们用一个萝卜一个坑的例子来演示抽象工厂模式:
public interface AbsHole { public void printHoleSize () ; } public interface AbsTurnips { public void printTuripsSize () ; } public interface AbstractFactory { public AbsHole createHole () ; public AbsTurnips createTurnips () ; } public class BigHole implements AbsHole { public void printHoleSize () { System.out .println("大坑" ); } } public class BigTurnips implements AbsTurnips { public void printTuripsSize () { System.out .println("大萝卜" ); } } public class SmallHole implements AbsHole { public void printHoleSize () { System.out .println("小坑" ); } } public class SmallTurnips implements AbsTurnips { public void printTuripsSize () { System.out .println("小萝卜" ); } } public class ConcreBigFactory implements AbstractFactory { public AbsHole createHole () { return new BigHole(); } public AbsTurnips createTurnips () { return new BigTurnips(); } } public class ConcreSmallFactory implements AbstractFactory { public AbsHole createHole () { return new SmallHole(); } public AbsTurnips createTurnips () { return new SmallTurnips(); } } public class Client { public static void main (String args[] ) { AbstractFactory factory = new ConcreBigFactory(); factory.createHole().printHoleSize(); factory.createTurnips().printTuripsSize(); factory = new ConcreSmallFactory(); factory.createHole().printHoleSize(); factory.createTurnips().printTuripsSize(); } }