package GOF;
interface Create {
public void create();
}
class A implements Create {
@Override
public void create() {
System.out.println("A");
}
}
class B implements Create {
@Override
public void create() {
System.out.println("B");
}
}
interface Produce {
public Create produce();
}
class C implements Produce {
@Override
public Create produce() {
return new A();
}
}
class D implements Produce {
@Override
public Create produce() {
return new B();
}
}
public class AbstractFactory {
public static void main(String[] args) {
Produce produce = new C();
Create create = produce.produce();
create.create();
}
}
如上图所示代码,是抽象工厂模式的实例。请问在实际的业务场景中如何使用?有什么优点。
大家讲道理2017-04-18 09:29:40
覺得你問的這個問題很有意義,很多人對設計模式都不能靈活的應用
下面我從分析問題的角度,談談為什麼要用工廠類的設計模式
第 1 個問題:我們經常一些功能類似的類,所以我們的思路是對進行抽象,使用接口暴露公共的方法,使用抽象類來提供公共的實現。
public interface IProduct {
void print(); // 这是要暴露的方法
}
public abstract class AbstractProduct implements IProduct {
protected void printBefore(){
System.out.println("before print"); // 这里所公共的实现
}
}
public class AProduct extends AbstractProduct {
private String name;
public AProduct(String name){
this.name = name;
}
@Override
public void print() {
this.printBefore();
System.out.println("print A >>>"+name);
}
}
public class BProduct extends AbstractProduct {
private String name;
public BProduct(String name){
this.name = name;
}
@Override
public void print() {
this.printBefore();
System.out.println("print B >>>"+name);
}
}
第 2 個問題:這些功能類似的類別的實例化變成了一個問題,每個類別的建構方法參數還不一樣,每次 new 物件都很麻煩,封裝成簡單工廠模式。
public class SimpleFactory {
public static IProduct getProduct(String name){
if("A".equals(name)){
return new AProduct(name);
}else if("B".equals(name)){
return new BProduct(name);
}else{
throw new IllegalArgumentException();
}
}
}
第3 個問題:簡單工廠模式不利於拓展,違背了開閉原則,每次添加一個類,都要修改工廠類(如果是工廠類和業務類是兩個小伙伴分開寫的,那不是要花很多時間來溝通...),所以就有工廠方法模式,其原理就是對簡單工廠也進行抽象。
public interface IFactory {
IProduct getProduct();
}
public class AFactory implements IFactory {
@Override
public IProduct getProduct() {
return new AProduct(AProduct.class.getName());
}
}
public class BFactory implements IFactory {
@Override
public IProduct getProduct() {
return new BProduct(BProduct.class.getName());
}
}
第 4 個問題:突然發現有些糟糕了,因為程式碼變得很多了,因為功能類似的產品我們進行 3 層抽象,針對每個產品我們還抽像出了 2 層的工廠類別。但是我們在某個具體的業務場景中,不單單是只實例化一個類別啊。舉一個例子,在遊戲中,我們要一個戰士配裝備,首先我們需要配一把槍械(槍械有很多,步槍,狙擊槍等,使用問題1 進行抽象),但是配了槍械之後,我們還需要配子彈啊(繼續用問題1 的方法進行抽象),好了,現在可以抽像出2 層的工廠類了,針對現在的情況我們是不是可以讓一個工廠既生產槍械,又生產子彈呢? 這就是抽象工廠模式。簡單來說,可以把有一些有聯繫或相似的產品,放到一個工廠去生產,沒有必要單獨再開一個工廠了。
另外修正一下,你貼的程式碼是工廠方法模式,不是抽象工廠模式。
看到題主還沒採納我的答案,我就多說幾句吧,給一個具體的應用案例。
我們都知道 Java 的泛型是採用型別擦除來實現的(在 javac 編譯過程的中把泛型去掉,加上強制型別轉換)。所以我們不能直接 new T()來實例化一個物件。其實可以用工廠方法模式設計模式來解決。
假設我們有一個類,裡面要用到了泛型的實例化。
public class Foo<T>(){
private T t;
public Foo(){
t = new T(); // 这个代码是有问题的,我们使用工厂设计模式进行改进
}
}
我們給出工廠介面如下:
public interface IFactory<T>(){
T create();
}
進而我們可以採用以下的方法來改進
public class Foo<T>(){
private T t;
public <F extends IFactory<T>> Foo(F factory){
// t = new T();
factory.create();
}
}
這個時候,我們可以用如下的方式實例化 Foo
new Foo(new Ifactory<Integer>(){
Integer create(){
return new Integer(0);
}
});
new Foo(new Ifactory<String>(){
String create(){
return "Hello";
}
});
ps: 為了顯得不會太囉嗦,所以工廠方法的實現,這裡採用內部類別來完成。