概述
工厂模式是Java中常用的设计模式,主要思想将Bean的初始化、创建等过程交由工厂处理。调用端无需关系bean的初始化及创建信息,只需了解Bean提供的API。
一、简单工厂模式
简单工厂模式(静态工厂模式 - StaticFactory)简单来说,工厂根据参数创建并返回不同bean的实例。
IBook接口:
package com.miselehe.pattern.factory.bean; /** * 书籍 * */ public interface IBook { /** * 获取书籍名称 * @return */ public String getBookName(); }
Book实现类:
package com.miselehe.pattern.factory.bean; /** * Java 书籍 * */ public class JavaBook implements IBook { public String getBookName() { // TODO Auto-generated method stub return "Java Book!"; } }
package com.miselehe.pattern.factory.bean; /** * Javascript 书籍 * */ public class JavascriptBook implements IBook { public String getBookName() { // TODO Auto-generated method stub return "Javascript Book!"; } }
package com.miselehe.pattern.factory.bean; /** * .net 书籍 * */ public class NetBook implements IBook { public String getBookName() { // TODO Auto-generated method stub return ".Net Book!"; } }
工厂:
package com.miselehe.pattern.factory.simple; import com.miselehe.pattern.factory.bean.IBook; import com.miselehe.pattern.factory.bean.JavaBook; import com.miselehe.pattern.factory.bean.JavascriptBook; import com.miselehe.pattern.factory.bean.NetBook; /** * 简单工厂 (静态工厂) * */ public class SimpleFactory { /** * 获取Bean * @param bookFlag * @return */ public IBook getBook(String bookFlag) { if ("java".equals(bookFlag)) { return new JavaBook(); } else if ("javasciprt".equals(bookFlag)) { return new JavascriptBook(); } else if (".net".equals(bookFlag)) { return new NetBook(); } else { return null; } } }
测试代码:
package com.miselehe.pattern.factory.simple; /** * 简单工厂模式 使用 * @author * */ public class SimpleFactoryTest { public static void main(String[] args) { SimpleFactory simpleFactory = new SimpleFactory(); System.out.println(simpleFactory.getBook("java").getBookName()); // Java Book! System.out.println(simpleFactory.getBook("javasciprt").getBookName()); // Javascript Book! System.out.println(simpleFactory.getBook(".net").getBookName()); // .Net Book! } }
这种方式很少使用。在使用时,调用端需要了解不同Bean的标记,标记错误无法获取到想要的结果。再需要扩展Bean时,Factory需要也需要增加标记。
二、工厂方法模式
不同业务Bean的实例,由不同工厂创建。
工厂接口:
package com.miselehe.pattern.factory.method; import com.miselehe.pattern.factory.bean.IBook; /** * 工厂接口 * */ public interface IFactory { /** * 获取实例 */ public IBook getBook(); }
工厂实现类:
package com.miselehe.pattern.factory.method; import com.miselehe.pattern.factory.bean.IBook; import com.miselehe.pattern.factory.bean.JavaBook; /** * Java 书籍工厂 * */ public class JavaBookFactory implements IFactory { public IBook getBook() { // TODO Auto-generated method stub return new JavaBook(); } }
package com.miselehe.pattern.factory.method; import com.miselehe.pattern.factory.bean.IBook; import com.miselehe.pattern.factory.bean.JavascriptBook; /** * javascript 书籍工厂 * */ public class JavascriptBookFactory implements IFactory { public IBook getBook() { // TODO Auto-generated method stub return new JavascriptBook(); } }
package com.miselehe.pattern.factory.method; import com.miselehe.pattern.factory.bean.IBook; import com.miselehe.pattern.factory.bean.NetBook; /** * .net 书籍工厂 * */ public class NetBookFactory implements IFactory { public IBook getBook() { // TODO Auto-generated method stub return new NetBook(); } }调用测试:
package com.miselehe.pattern.factory.method; /** * 工厂方法模式测试 * */ public class MethodFactoryTest { public static void main(String[] args) { /** * 通过不同工厂获取不容bean */ JavaBookFactory javaBookFactory = new JavaBookFactory(); System.out.println(javaBookFactory.getBook().getBookName()); // Java Book! JavascriptBookFactory javascriptBookFactory = new JavascriptBookFactory(); System.out.println(javascriptBookFactory.getBook().getBookName()); // Javascript Book! NetBookFactory netBookFactory = new NetBookFactory(); System.out.println(netBookFactory.getBook().getBookName()); // .Net Book! } }这种模式和简单工厂相比较:
- 在调用时需要根据不同工厂来获取Bean,不再需要标记,相对使用标记来说避免了标记错误而造成的错误,程序更加健壮;
- 在需要扩展时,不但需要增加新的Bean,而且可能需要增加新的Factory,但是避免了修改其他Factory,符合开闭原则;
这种方式一般比较常见(搭配抽象工厂);
三、抽象工厂模式
创建抽象类工厂,
抽象类工厂:
package com.miselehe.pattern.factory.abstractf; import com.miselehe.pattern.factory.bean.IBook; /** * 抽象工厂 * */ public abstract class AbstractBookFactory { /** * 获得java书籍 * @return */ public abstract IBook getJavaBook(); /** * 获得javascript书籍 * @return */ public abstract IBook getJavascriptBook(); /** * 获得.net书籍 * @return */ public abstract IBook getNetBook(); }
实现类工厂:
package com.miselehe.pattern.factory.abstractf; import com.miselehe.pattern.factory.bean.IBook; import com.miselehe.pattern.factory.bean.JavaBook; import com.miselehe.pattern.factory.bean.JavascriptBook; import com.miselehe.pattern.factory.bean.NetBook; /** * 工厂实现类 * @author sdc * */ public class BookFactory extends AbstractBookFactory { @Override public IBook getJavaBook() { // TODO Auto-generated method stub return new JavaBook(); } @Override public IBook getJavascriptBook() { // TODO Auto-generated method stub return new JavascriptBook(); } @Override public IBook getNetBook() { // TODO Auto-generated method stub return new NetBook(); } }
调用测试:
package com.miselehe.pattern.factory.abstractf; /** * 调用抽象工厂 * */ public class AbstractFactoryTest { public static void main(String[] args) { // TODO Auto-generated method stub BookFactory bookFactory = new BookFactory(); System.out.println(bookFactory.getJavaBook().getBookName()); // Java Book! System.out.println(bookFactory.getJavascriptBook().getBookName()); // Javascript Book! System.out.println(bookFactory.getNetBook().getBookName()); // .Net Book! } }
比较:
相比于简单工厂,由标记参数转换为了具体的方法。在扩展时,如果增加业务Bean则静态工厂和工厂实现类都需要扩展。
在实际使用中,往往会将三种方式混合使用,比如抽象工厂实现类中,创建Bean部分,再由工厂方法模式实现等。