工廠模式(Factory Pattern)是 Java 中最經常使用的設計模式之一。這種類型的設計模式屬於建立型模式,它提供了一種建立對象的最佳方式。咱們熟悉的Spring 的 bean 工廠等。java
直接上demo.先代碼,後介紹。spring
Shape .java設計模式
/** * 一個接口:關於形狀 */
public interface Shape {
/** * 描述方法 */
void describe();
}複製代碼
Circle .javabash
public class Circle implements Shape {
/** * 描述方法 */
@Override
public void describe() {
System.out.println("我是個圓形");
}
}
複製代碼
Rectangle .java框架
public class Rectangle implements Shape {
/** * 描述方法 */
@Override
public void describe() {
System.out.println("我是一個長方形");
}
}
複製代碼
ShapeFactory .javaide
/** * 形狀工廠 */
public class ShapeFactory {
public Shape getShape(String type){
if (type == null){
return null;
}
if ("CIRCLE".equals(type)){
return new Circle();
}else if ("RECTANGLE".equals(type)){
return new Rectangle();
}
return null;
}
}
複製代碼
public class Test {
public static void main(String[] args) {
ShapeFactory shapeFactory = new ShapeFactory();
//獲取 圓形 實例化對象
Shape circle = shapeFactory.getShape("CIRCLE");
//調用對象方法
circle.describe();
//獲取 長方形 實例化對象
Shape rectangle = shapeFactory.getShape("RECTANGLE");
//調用方法
rectangle.describe();
}
}
複製代碼
我是個圓形
我是一個長方形
複製代碼
提問:若是你是一個愛動腦筋的人,你會發現,它和Bean工廠的做用是類似的,可是Bean工廠是這樣實現的嗎?它會自動去寫if語句去建立實例對象嗎?學習
答案確定是否是的。測試
固然,在這裏不會像spring 的bean工廠同樣,把它的邏輯寫出來,由於人家已是通過不少年的迭代的產品,封裝的已經(目不忍視)太厚了,因此把它的實現原理說明。優化
可能有些人都想到了,對,就是框架離不開的:反射機制。spa
ShapeFactory.java
/** * 反射 */
public Object getShape(Class<? extends Shape> clazz){
Object object = null;
try {
object = Class.forName(clazz.getName()).newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return object;
}
複製代碼
Object shape = (Rectangle)shapeFactory.getShape(Rectangle.class);
((Rectangle) shape).describe();
複製代碼
若是忘記去對shapeFactory 作強制類型轉換的話,那就是一個徹底的object對象,使用不方便,那如何可以省略類型轉換的這一步驟呢?
/** * 反射 + 泛型 */
public <T> T getShape(Class<? extends T> clazz){
T object = null;
try {
//實例化,並在這裏作 類型轉換
object = (T) Class.forName(clazz.getName()).newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return object;
}
複製代碼
Rectangle shape = shapeFactory.getShape(Rectangle.class);
shape.describe();
複製代碼
我是一個長方形
複製代碼
能夠看到,事實上也是作了強制類型轉換的,只不過在ShapeFactory裏作的,看不到而已,這種作法會大大方便咱們使用。
通過第五點和第六點的學習,想一想,spring 框架裏 其實只有一個工廠,那就是BeanFactory,ApplicationContext 也須要用它來建立對象。那如何去寫一個針對多個接口實現一個公共的工廠類呢?
/** * 針對多個接口實現一個公共的工廠類 */
public <T> Object getObject(Class<T> clazz) {
if (clazz == null ) {
return null;
}
Object obj = null;
try {
obj = Class.forName(clazz.getName()).newInstance();
} catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) {
e.printStackTrace();
}
return obj;
}
複製代碼
一個思考題,咱們在Spring 框架下,@Autowired 裝配Bean 具體是完成什麼樣的操做呢,這可能也是工廠模式最好的總結說明。