定義:Define an interface for creating an object, but let subclasses decide which class instance. Factory Method lets a class defer instantiation to subclasses.
(定義一個用於建立對象的接口 [這裏的接口一詞並不指Java中的接口構造,它能夠是Java接口或抽象類] ,可是讓子類決定去實例化哪一個類。工廠方法將對象的實例化推遲到其子類。)java
優點:
[1].良好的封裝性,代碼結構清晰。若是一個調用者須要一個具體的產品對象,只要知道這個產品的類名就能夠了,不用關心對象是如何建立的,下降了模塊見得耦合。
[2].工廠方法模式擴展性很是優秀。若是想增長一個產品類,只須要適當的修改具體的工廠類或擴展一個工廠類就能夠完成。
[3].屏蔽品類。產品的實現如何變化,調用者都不須要關心,它只須要關心產品的接口,只要接口保持不變,系統中的上層模塊就不須要發生變化。由於產品的實例化工做是由工廠類負責的,一個產品對象具體由哪個產品生成是由工廠類決定的。 例如:在數據庫開發中,若是使用 JDBC 鏈接數據庫,數據庫從 MySQL 且款到 Oracle,只須要改動的地方就是切換一下驅動名稱。
[4].工廠方法模式是典型的解耦框架。高層模塊值只須要知道產品的抽象類,其餘的實現類都不用關心,符合迪米特法則,我不須要的就不要去交流;也符合依賴倒置原則,只依賴產品的抽象;也符合里氏替換原則,使用產品子類替換父類。數據庫
基本組成 |
---|
產品抽象類Product |
具體產品類ConcreteProduct1 ConcreteProduct2 |
工廠類Creator |
public abstract class Product {
public abstract void method();
}
複製代碼
public class ConcreteProduct1 extends Product{
@Override
public void method() {
// do something...
}
}
public class ConcreteProduct2 extends Product{
@Override
public void method() {
// do something...
}
}
複製代碼
public class Creator{
public static <T extends Product> T createProduct(Class<T> c) {
Product product=null;
try {
product=(Product)Class.forName(c.getName()).newInstance();
}catch(Exception e) {
// do something...
}
return (T)product;
}
}
複製代碼
特色:工廠是一個具體類,非抽象類 非接口,它的
create
方法,是利用反射機制生成對象返回,增長一種產品時,不須要修改工廠的代碼。
缺點:不一樣的產品須要不一樣額外參數的時候 不支持。框架
public class Creator{
public static final int PRODUCT_ONE = 1;
public static final int PROCUCT_TWO = 2;
public static Product createProduct(int type) {
switch(type){
case PRODUCT_ONE:
return new ConcreteProduct1();
case PROCUCT_TWO:
default:
return new ConcreteProduct2();
}
}
}
複製代碼
特色:工廠是一個具體類,非抽象類 非接口,
create
方法一般是靜態的,因此也稱之爲靜態工廠。
缺點:擴展性差,當咱們須要增長一個產品類時還須要修改工廠類; 不一樣的產品須要不一樣額外參數的時候 不支持。ide
簡單工廠模式的一個問題是 當產品須要不一樣額外參數的時候 不支持。 並且若是使用時傳遞的 type
、Class
出錯,將不能獲得正確的對象,容錯性不高。
而多方法的工廠模式爲不一樣產品,提供不一樣的生產方法。this
基本組成 |
---|
產品抽象類Product |
具體產品類ConcreteProduct1 ConcreteProduct2 |
工廠類Creator |
public abstract class Product {
public abstract void method();
}
複製代碼
public class ConcreteProduct1 extends Product{
private String name;
public ConcreteProduct1(String name){
this.name = name;
}
@Override
public void method() {
// do something...
}
}
public class ConcreteProduct2 extends Product{
private String name;
private int size;
public ConcreteProduct2(String name, int size){
this.name = name;
this.size = size;
}
@Override
public void method() {
// do something...
}
}
複製代碼
public class Creator{
public static Procuct createProduct1(String name){
return new ConcreteProduct1(name);
}
public static Procuct createProduct2(String name, int size){
return new ConcreteProduct2(name, size);
}
}
複製代碼
優勢:方便建立 同種類型的 複雜參數 對象spa
基本組成 |
---|
產品抽象類Product |
工廠抽象類Creator |
具體產品類ConcreteProduct1 ConcreteProduct2 |
具體工廠類ConcreteCreator1 ConcreteCreator2 |
public abstract class Product {
public abstract void method();
}
複製代碼
public abstract class Creator{
public abstract Product create();
}
複製代碼
public class ConcreteProduct1 extends Product{
@Override
public void method() {
// do something...
}
}
public class ConcreteProduct2 extends Product{
@Override
public void method() {
// do something...
}
}
複製代碼
public class ConcreteCreator1 extends Creator{
@Override
public Product create(){
return new ConcreteCreator1();
}
}
public class ConcreteCreator2 extends Creator{
@Override
public Product create(){
return new ConcreteCreator2();
}
}
複製代碼
特色:不單單產品須要抽象, 工廠也須要抽象;工廠方法使一個產品類的實例化延遲到其具體工廠子類。
優勢:擁抱變化,當需求變化,只須要增刪相應的類,不須要修改已有的類。而簡單工廠須要修改工廠類的create
方法,多方法靜態工廠模式須要增長一個靜態方法。
缺點:引入抽象工廠層後,每次新增一個具體產品類,也要同時新增一個具體工廠類。code