概念:
工厂方法模式:定义一个创建对象的接口,让子类决定实例化哪个类。工厂方法使一个类的实例化延迟到了子类。即在实例化对象时,我们不用自己new一个对象,而是将这个过程由另一个类通过反射或者new的方式创建对象并返回。
实现:
定义书籍接口
public interface Book { }
定义工厂接口
public interface BookFactory { /** * 定义创建Book对象的方法,所有工厂实现该接口创建对应的book。 * @return book */ Book create(); }
书籍类别(小说书籍、工具书籍...)
public class NovelBook implements Book { private String name; private BigDecimal price; public String getName() { return name; } public void setName(String name) { this.name = name; } public BigDecimal getPrice() { return price; } public void setPrice(BigDecimal price) { this.price = price; } }
public class ToolBook implements Book { private String name; private BigDecimal price; public String getName() { return name; } public void setName(String name) { this.name = name; } public BigDecimal getPrice() { return price; } public void setPrice(BigDecimal price) { this.price = price; } }
工厂类别
public class NovelBookFactory implements BookFactory { /** * 创建小说的工厂,返回的对象是Book的子类 * @return book */ @Override public Book create() { return new NovelBook(); } }
public class ToolBookFactory implements BookFactory { /** * 创建工具类书籍的工厂,返回的对象是Book的子类 * @return book */ @Override public Book create() { return new ToolBook(); } }
以上实现时常规的实现方式,一般类别比较少时没什么问题,但如果有一百多种类别,甚至更多种类别呢?不可能创建一百个工厂,所以还有一种扩展的实现方式,见下:
定义工厂接口:
public interface ExtendFactory { <T>T creatBook(Class<T> c); }
工厂实现类:
public class ExtendBookFactory implements ExtendFactory { @Override public <T> T creatBook(Class<T> c) { try { //Book book_1 = (Book) Class.forName(c.getName()).newInstance(); //Java9 以上标示过时, Book book_2 = (Book) Class.forName(c.getName()).getDeclaredConstructor().newInstance(); return (T) book_2; } catch (Exception e) { e.printStackTrace(); } return null; } }
分析:通过代码可以简单的分析一下
1.具有良好的封装性。需要什么对象时只需要对应的工厂,如果是扩展式实现,则更为简单,只需需要知道具体的对象类名就可以了。
2.扩展性良好。普通的实现方式,如果是需要扩展,不需要修改代码,只需要添加对象和对应的工厂,如果是扩展实现,只要添加相应的对象就可以了。
3.解耦合。在逻辑模块不关心对象的创建过程。
4.适用场景:
a.一般和单例等模式一起用,单例一般可能是为了创建一个工厂。
b.需要一个灵活可扩展的框架时,可以考虑使用。
……
经典框架中使用的:
Spring框架中,管理Bean,默认生成的对象就是以单例模式生成;Struts2框架中,工厂对象基本都是使用单例模式生成。等等……