淺談abstractfactory抽象工廠模式

1、前言html

上次咱們學習了Builder模式,用來組裝複雜的實例,Builder就是咱們蓋房子的一塊塊磚頭,鋼筋和水泥,以及簡單的用法,使用監工將這些元素有機的組合在了一塊兒就可以建造整個建築了,是監工將這些原材料按照必定的次序和特定的處理流程糅合在一塊兒,這個過程就是組裝。而如今咱們學習了抽象工廠模式,將關鍵零件組裝成產品。java

在此以前,讓咱們對前面的幾種模式作簡單的回顧,首先咱們學習了迭代器模式,使用了工廠方法創造迭代器,而且完成了元素的內部實現和遍歷的分離,所以成爲「器」,也算是一種配合,其次咱們學習了適配器,有類適配器和對象適配器,這二者只是實現的方式不一樣,本質是同樣的,都是經過在原素材上加入一個適配器使得可以知足如今的須要,通常用在版本之間的兼容上使得新版本的內容可以在舊版本上使用(適配),以及一些複用的時候須要適當的修改(適配)的場合;以後咱們學習了模板模式和工廠模式,模板方法的一個特殊實現其實就是工廠方法,模板方法就是經過在父類之中定義職責,而後讓子類實現各自的子任務,最後經過父類進行調用,提升了代碼的可修改性和可擴展性,工廠方法則是在模板方法的基礎上,經過生產產品的方式將框架的實現分離,遵循了高內聚低耦合的原則;在以後咱們學習了單例模式和原型模式,單例模式是保證全局關於某個類只有一個對象,在某些多線程或者編碼誤用的條件下很是重要,原型模式則是實現了對象的深淺拷貝,使得通過了很長時間才獲得的對象可以保存以及複製和使用,省去了不少沒必要要的new操做。以後咱們學習了Builder模式,經過增長一個監工類來將父類中定義的方法組合起來實現某種功能,實現了類的隔離,便於代碼的複用,是模板模式的升級版。編程

學習了這麼多模式,不知道你們對設計模式有沒有什麼感悟,能夠說就是經過接口、抽象類。繼承、多態等機制遵循高內聚低耦合、封閉原則、裏式代換原則等實現代碼的可複用性,可擴展性,儘管比之前變得複雜了,其實成都越大擴展就越簡單。那麼爲何又是抽象工廠模式呢?設計模式

抽象工廠模式是一個很是複雜的模式,和工廠方法鍵值差異太大了,可是也有相同之處,那就是抽象工廠也是用了工廠方法來創造產品,只不過抽象工廠模式中包含了零件、產品、工廠、抽象等概念,這樣就很是的複雜了,通常還要用到模板方法、迭代器甚至原型模板等,就「抽象」兩個字來講,就是將全部的角色分紅兩部分,一部分是這個角色的抽象類,另外一部分是這個角色的實現類,工廠就是沿用了工廠模式,所以抽象工廠模式分爲兩大部分,抽象部分和具體實現部分,如圖所示:多線程

上面的抽象部分,最重要的就是抽象的工廠類(Link)、抽象的零件類(Tray)、抽象的產品類(Page),這兩個零件有共同之處,所以經過item類進行抽象便於二者之間的互通。下面的具體實現部分即便對抽象的實現了,以後咱們使用main類來進行整合,能夠發現咱們只用對抽象類進行編程,徹底不用使用任何的具體類就能實現咱們想要的功能,甚至致使編譯器在編譯的時候還須要指出須要編譯的具體類,由於咱們使用了Class.forName()方法實現了反射。這樣的結構看似很是的龐大,其實仔細的推敲,反而妙不可言,當咱們還想建立一個具體的工廠的時候實在是太簡單了,原來抽象工廠的代碼都不用修改,只用按照響應的抽象實現就能夠了,以後咱們就能夠直接使用了,只用在main中將Class.forName()所指定的類改一下就能夠了,很是的方便。凡有利就有弊,若是咱們對抽象工廠中的某些定義不滿意了呢,這個時候若是咱們對抽象方法進行必定的調整和更改(增長或刪除),那麼全部實現了該抽象工廠的具體工廠的類都須要進行修改,若是有100個具體工廠,無疑是很是可怕的,所以咱們應該理智的取捨,廢話少說,讓咱們看一下代碼。app

2、代碼實現框架

咱們將類分紅三個部分,這樣思路更加清晰,第一部分是抽象工廠中的類,第二部分是具體實現的具體工廠類,第三部分是測試使用的Main類。ide

抽象工廠包:post

 Item 抽象類:學習

package designMode.abstractfactory.factory;

public abstract class Item {
    protected String caption;
    public Item(String caption){
        this.caption=caption;
    }
    public abstract String makeHTML();
}

 Link抽象類:

package designMode.abstractfactory.factory;

public abstract class Link extends  Item{
    public String url;
    public Link(String caption,String url) {
        super(caption);
        this.url = url;
    }
}

 Tray抽象類:

package designMode.abstractfactory.factory;

import java.util.ArrayList;

public class Tray extends Item {
    protected ArrayList items = new ArrayList();
    public Tray(String caption) {
        super(caption);
    }

    @Override
    public String makeHTML() {
        return null;
    }

    public void add(Item item){
        items.add(item);
    }
}

Page抽象類: 

package designMode.abstractfactory.factory;

import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
import java.util.ArrayList;

public abstract class Page {
    protected String title;
    protected String author;
    protected ArrayList content = new ArrayList();

    public Page(String title,String author) {
        this.author = author;
        this.title=title;
    }

    public void add(Item item){
        content.add(item);
    }

    public void output(){
        String filename = title + ".html";
        try {
            Writer writer = new FileWriter(filename);
            writer.write(this.makeHTML());
            writer.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        System.out.println("寫入文件:"+filename+"已成功!");
    }
    public abstract String makeHTML() ;
}

Factory工廠抽象類: 

package designMode.abstractfactory.factory;

//Factory工廠抽象類:
public abstract class Factory {
    public static Factory getFactory(String classname){
        Factory factory = null;
        try {
            factory = (Factory) Class.forName(classname).newInstance();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        return factory;
    }
    public abstract Link createLink(String caption,String url);
    public abstract Tray createTray(String caption);
    public abstract Page createPage(String title,String author);
}

具體實現工廠類:

ListLink類:

package designMode.abstractfactory.listfactory;

import designMode.abstractfactory.factory.Link;

public class ListLink extends Link {
    public ListLink(String caption, String url) {
        super(caption, url);
    }

    @Override
    public String makeHTML() {
        return "<li>"+"<a href=\""+url+"\" >"+caption+"</a></li>\n";
    }
}

 ListTray類:(迭代器模式)ArrayList自己實現了迭代器。 

package designMode.abstractfactory.listfactory;

import designMode.abstractfactory.factory.Item;
import designMode.abstractfactory.factory.Tray;

import java.util.Iterator;

public class ListTray extends Tray {
    public ListTray(String caption) {
        super(caption);
    }

    public String makeHTML() {
        StringBuffer sb=new StringBuffer();
        sb.append("<li>\n");
        sb.append(caption+"\n");
        sb.append("<ul>\n");

        Iterator it=items.iterator();
        while(it.hasNext()){
            Item item=(Item)it.next();
            sb.append(item.makeHTML());
        }
        sb.append("</ul>\n");
        sb.append("</li>\n");
        return sb.toString();
    }
}

 ListPage類:(迭代器模式)ArrayList自己實現了迭代器。

package designMode.abstractfactory.listfactory;

import designMode.abstractfactory.factory.Item;
import designMode.abstractfactory.factory.Page;

import java.util.Iterator;

public class ListPage extends Page {
    public ListPage(String title, String autor) {
        super(title, autor);
    }

    @Override
    public String makeHTML() {
        StringBuffer sb=new StringBuffer();
        sb.append("<html><head><title>"+title+"</title></head>");
        sb.append("<body>\n");
        sb.append("<h1>"+title+"</h1>");

        sb.append("<ul>\n");
        Iterator it=content.iterator();
        while(it.hasNext()){
            Item item=(Item)it.next();
            sb.append(item.makeHTML());
        }
        sb.append("</ul>\n");
        sb.append("<hr><address>"+author+"</address>");
        sb.append("</body></html>\n");
        return sb.toString();
    }
}

ListFactory類:(工廠方法模式)

package designMode.abstractfactory.listfactory;

import designMode.abstractfactory.factory.Factory;
import designMode.abstractfactory.factory.Link;
import designMode.abstractfactory.factory.Page;
import designMode.abstractfactory.factory.Tray;

public class ListFactory extends Factory {
    @Override
    public Link createLink(String caption, String url) {
        return new ListLink(caption,url);
    }

    @Override
    public Tray createTray(String caption) {
        return new ListTray(caption);
    }

    @Override
    public Page createPage(String title, String author) {
        return new ListPage(title,author);
    }
}

 Main類:

package designMode.abstractfactory.test;

import designMode.abstractfactory.factory.Factory;
import designMode.abstractfactory.factory.Link;
import designMode.abstractfactory.factory.Page;
import designMode.abstractfactory.factory.Tray;

public class Main {
    public static void main(String[] args) {
        String[] choice = {"designMode.abstractfactory.listfactory.listFactory.ListFactory"};
        Factory factory = Factory.getFactory(choice[0]);

        Tray tray_life=factory.createTray("個人生活");
        Link link_graduate=factory.createLink("個人本科", "http://www.swjtu.edu.cn");
        Link link_postgraduate=factory.createLink("個人研究生","http://www.uestc.edu.cn");
        tray_life.add(link_graduate);
        tray_life.add(link_postgraduate);
        Tray tray_blog=factory.createTray("個人博客");
        Link link_iterator=factory.createLink("迭代器","https://www.cnblogs.com/zyrblog/p/9217673.html");
        Link link_adapter=factory.createLink("適配器", "https://www.cnblogs.com/zyrblog/p/9218316.html");
        tray_blog.add(link_iterator);
        tray_blog.add(link_adapter);
        Tray tray_blog_all=factory.createTray("博客園");
        Link link_other1=factory.createLink("解釋器模式", "https://www.cnblogs.com/Answer-Geng/p/9231042.html");
        Link link_other2=factory.createLink("OAuth 2.0", "https://www.cnblogs.com/cjsblog/p/9230990.html");

        tray_blog_all.add(tray_blog);
        tray_blog_all.add(link_other1);
        tray_blog_all.add(link_other2);

        Page page=factory.createPage("zyr", "朱彥榮");

        page.add(tray_life);
        page.add(tray_blog_all);

        page.output();
    }
}

能夠看到徹底組成了一個網頁。看到這裏你們可能很質疑,難道廢了這麼大的功夫就是爲了實現這麼簡單的功能?其實這裏咱們能夠看到抽象工廠的強大之處,零件的組裝與嵌套,相互關聯,經過迭代器、模板模式、工廠模式等最終實現了這種功能,可擴展性很是強大,若是還要生成其它種類的工廠,將很是的方便,直接寫實現類就能夠了,其它代碼基本不須要改動,這樣的功能能夠說很是強大了,至今爲止咱們不少的代碼都是強耦合的,很難實現複用,而這個抽象的工廠模式就能夠實現高層次的複用,只須要知道實現類的類名就能夠執行了,咱們徹底能夠實現其餘工廠,從而實現其餘的功能。抽象工廠模式最重要的就是可複用性和完美的隔離性,其中使用了makeHTML()不少次,經過迭代器來展示了這個方法的多臺。靈活使用抽象工廠模式能夠說是設計模式真正入門的起點。抽象工廠將抽象零件組裝成抽象產品,易於增長具體的工廠難於增長新的零件。

 

淺談設計模式<最通俗易懂的講解>

相關文章
相關標籤/搜索