1. 程式人生 > >Spring中常見的設計模式——工廠模式

Spring中常見的設計模式——工廠模式

一、簡單工廠模式

  簡單工廠模式(Simple Factory Pattern)由一個工廠物件決定建立哪一種產品類的例項,簡單工廠模式適用於工廠類負責建立物件較少的情況,且客戶端只需要傳入工廠類的引數,對於如何建立物件不關心。

public interface IBlog {
    //寫隨筆
    public void write();
}
public class JavaBlog implements IBlog {
    @Override
    public void write() {
        System.out.println("寫java隨筆");
    }
}
public class WriteBlog {
    public static void main(String[] args) {
        IBlog blog = new JavaBlog();
        blog.write();
    }
}

  上述程式碼中,父類 IBlog 指向子類JavaBlog 的引用,應用層需要依賴JavaBlog,如果增加PythonBlog等等更多的課程,客戶端就會越來越臃腫。因此要把依賴減弱,把建立細節隱藏。現在我們用簡單工廠優化:

public class BlogFactory {
    public IBlog create(Class<? extends IBlog> clazz) {
        if (null != clazz) {
            try {
                return clazz.newInstance();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return null;
    }
}

客戶端改變:

  public static void main(String[] args) {
        BlogFactory blogFactory = new BlogFactory();
        IBlog blog = blogFactory.create(JavaBlog.class);
        blog.write();
    }

  簡單工廠模式在JDK中很常見,如Calender類(感興趣去看原始碼),還有logback,LoggerFactory中有很多過載的方法getLogger()。但是簡單工廠也有缺點:工廠類的職責相對過重,不易於擴充套件過於複雜的產品結構。

二、工廠方法模式

   工廠方法模式(Factory Method Pattern)是指定義一個建立物件的介面,但讓實現這個介面的類來決定例項化哪個類,工廠方法模式讓類的例項化推遲到子類中進行。在工廠方法模式中,使用者只需要關心所需產品對應工廠,無須關心建立的細節,而且加入新產品時符合開閉原則。

  工廠方法模式主要解決產品擴充套件問題。在簡單工廠模式中,隨著產品的增多,如果不同語言書寫隨筆的邏輯各不相同,工廠職責越來越多,那工廠裡面就會亂搞一氣,狗屁不通。根據單一職責原則,我們將只能進行拆分,不同工廠做不同事,Java隨筆由Java工廠建立,Python隨筆由Python工廠建立,對工廠本身進行抽象。

先建立工廠類:

public interface IBlogFactory {
    IBlog create();
}

再建立對應工廠:

public class JavaBlogFactory implements IBlogFactory {
    @Override
    public IBlog create() {
        return new JavaBlog();
    }
}

public class PythonBlogFactory implements IBlogFactory {
    @Override
    public IBlog create() {
        return new PythonBlog();
    }
}

客戶端:

public class CreateBlog {
    public static void main(String[] args) {
        IBlogFactory factory = new PythonBlogFactory();
        IBlog blog = factory.create();
        blog.write();

        factory = new JavaBlogFactory();
        blog = factory.create();
        blog.write();
    }
}

總結來說就是:不同工廠抽象出一個工廠頭子,不同的工廠建立不同的例項。

工廠方法模式適用於以下場景:

1.建立物件需要大量重複程式碼。

2.客戶端(應用層)不依賴於產品類例項如何被建立、如何被實現等細節。

3.一個類通過其子類來指定建立哪個物件。

缺點:

1.類的個數容易過多,增加複雜度。

2.增加了系統的抽象性和理解難度。

三、抽象工廠

  抽象工廠(Abstract Factory Pattern)提供一個黃健一系列相關或相互依賴物件的介面,無需指定具體類。客戶端(應用層)不依賴於產品類例項如何被建立、如何被實現等細節,強調的是一系列相關得產品物件(屬於同一產品族)一起使用建立物件需要大量重複程式碼。需要提供一個產品類的庫,所有產品以同樣接口出現,從而是客戶端不依賴於具體實現。

產品族:同一家的不同產品,比如小米,華為,蘋果;

產品等級:不同種類的產品,比如 手機,電視,電腦。

工廠要做的就是生產我們牌子的所有產品。以部落格為例,java分類的部落格有隨筆、文章、日記等。

首先建立文章和日記的抽象介面:

public interface IDocument {
    void write();
}

public interface INote {
    void make();
}

再建立抽象工廠:

public interface BlogFactory {
    INote createNote();

    IDocument createDocument();
}

實現Java文章和日記:

public class JavaDocument implements IDocument {
    @Override
    public void write() {
        System.out.println("寫Java文章");
    }
}

public class JavaNote implements INote {
    @Override
    public void make() {
        System.out.println("寫Java筆記");
    }
}

實現Java產品族具體工廠:

public class JavaBlogFactory implements BlogFactory {
    @Override
    public INote createNote() {
        return new JavaNote();
    }

    @Override
    public IDocument createDocument() {
        return new JavaDocument();
    }
}

實現Python文章和日記、實現Python具體工廠參考Java的。

客戶端呼叫:

public class BlogTest {
    public static void main(String[] args) {
        JavaBlogFactory factory = new JavaBlogFactory();
        factory.createDocument().write();
        factory.createNote().make();
    }
}

  上述程式碼描述了兩個產品族的工廠,如果想要擴充套件產品等級(就是再加點評啥的),要調整抽象工廠、具體工廠。由此可見抽象工廠模式的缺點:

1.規定所有可能被建立的產品集合,產品族(Java系列)中擴充套件新產品很困難,需要修改抽象工廠及實現;

2.增加系統抽象性和理解難度;

  我們可以利用工廠模式建立好資料來源連線池並放到容器中,業務需要時再取出。就避免了用一次建立一次的尷尬。

&n