设计模式学习笔记——抽象工厂(Abstract Factory)模式

设计模式学习笔记——抽象工厂(Abstract Factory)模式

@(设计模式)[设计模式, 设计模式中文名, 设计模式英文名]

  • 设计模式学习笔记抽象工厂Abstract Factory模式
    • 基本介绍
    • 抽象工厂案例
      • 抽象工厂的框架类
        • Item抽象类
        • Link抽象类
        • Tray抽象类
        • Page抽象类
        • Factory抽象类
      • List实现
        • 类图
        • 实现代码
          • ListLink类
          • ListTray类
          • ListPage类
          • ListFactory类
        • 测试类
        • 运行结果
          • 控制台输出
          • E盘下网站介绍列表版html的内容
          • 浏览器中运行结果
      • Table实现
        • 类图
        • 实现代码
          • TableLink类
          • TableTray类
          • TablePage类
          • TableFactory类
        • 测试类
        • 运行结果
          • 控制台输出
          • E盘下网站介绍表格版html的内容
          • 浏览器中运行结果
    • 抽象工厂模式中的角色
      • AbstractProduct抽象产品
      • AbstractFactory抽象工厂
      • Client委托者
      • ConcreteProduct具体产品
      • ConcreteFactory具体工厂
      • 类图

基本介绍

在抽象工厂模式中不仅有“抽象工厂”,还有”抽象零件”和”抽象产品” 。抽象工厂的工作是将”抽象零件”组装为”抽象产品” 。

在抽象工厂模式中并不关心零件的具体实现,而是只关心接口(API)。仅使用该接口(API) 将零件组装成为产品。

在模版模式和建造者模式中,子类这一层负责方法的具体实现。在在抽象工厂模式中也是一样的。在子类这一层中有具体的工厂,它负责将具体的零件组装成为具体的产品。

在抽象工厂模式中,我们可以很方便的创建不同种的实现。但是如果要添加新的“零件”确实非常困难的事,要修改所有的实现工厂类。

抽象工厂案例

抽象工厂的框架类

Item抽象类

package com.pc.abstractfactory.example.factory;

/**
 * HTML中的一项(抽象零件)
 * Created by Switch on 2017-02-17.
 */
public abstract class Item {
    // 标题
    protected String caption;

    /**
     * 构造方法,传入标题
     *
     * @param caption 标题
     */
    public Item(String caption) {
        this.caption = caption;
    }

    /**
     * 创建HTML
     *
     * @return HTML格式的字符串
     */
    public abstract String makeHTML();
}

Link抽象类

package com.pc.abstractfactory.example.factory;

/**
 * 链接类(抽象零件)
 * Created by Switch on 2017-02-17.
 */
public abstract class Link extends Item {
    // url
    protected String url;


    /**
     * 构造方法,传入标题和URL
     *
     * @param caption 标题
     * @param url     url
     */
    public Link(String caption, String url) {
        super(caption);
        this.url = url;
    }
}

Tray抽象类

package com.pc.abstractfactory.example.factory;

import java.util.ArrayList;
import java.util.List;

/**
 * 存放多个HTML项(抽象零件)
 * Created by Switch on 2017-02-17.
 */
public abstract class Tray extends Item {
    // HTML项列表
    protected List items = new ArrayList<>();

    /**
     * 构造方法,传入标题
     *
     * @param caption 标题
     */
    public Tray(String caption) {
        super(caption);
    }

    /**
     * 添加HTML项
     *
     * @param item HTML项
     */
    public void add(Item item) {
        this.items.add(item);
    }
}

Page抽象类

package com.pc.abstractfactory.example.factory;

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

/**
 * 页面类(抽象产品)
 * Created by Switch on 2017-02-17.
 */
public abstract class Page {
    // 标题
    protected String title;
    // 作者
    protected String author;
    // 页面内容列表
    protected List items = new ArrayList<>();

    /**
     * 构造方法,传入标题和作者
     *
     * @param title  标题
     * @param author 作者
     */
    public Page(String title, String author) {
        this.title = title;
        this.author = author;
    }

    /**
     * 添加HTML项到内容给列表
     *
     * @param item HTML项
     */
    public void add(Item item) {
        this.items.add(item);
    }

    public void output() {
        try {
            // 创建文件,并使用makeHTML将内容输出到文件中
            String filename = title + ".html";
            Writer writer = new FileWriter("E:\\" + filename);
            writer.write(this.makeHTML());
            writer.close();
            System.out.println(filename + "已编写完成。");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 创建HTML
     *
     * @return HTML格式的字符串
     */
    public abstract String makeHTML();

}

Factory抽象类

package com.pc.abstractfactory.example.factory;

/**
 * 抽象工厂类
 * Created by Switch on 2017-02-17.
 */
public abstract class Factory {
    /**
     * 获取工厂
     *
     * @param className 全限定符的类名
     * @return 工厂对象
     */
    public static Factory getFactory(String className) {
        Factory factory = null;
        try {
            factory = (Factory) Class.forName(className).newInstance();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return factory;
    }

    /**
     * 创建链接
     *
     * @param caption 标题
     * @param url     url
     * @return 链接对象
     */
    public abstract Link createLink(String caption, String url);

    /**
     * 创建Tray
     *
     * @param caption 标题
     * @return Tray对象
     */
    public abstract Tray createTray(String caption);

    /**
     * 创建页面
     *
     * @param title  标题
     * @param author 作者
     * @return 页面对象
     */
    public abstract Page createPage(String title, String author);

}

List实现

类图

设计模式学习笔记——抽象工厂(Abstract Factory)模式_第1张图片

实现代码

ListLink类
package com.pc.abstractfactory.example.listfactory;

import com.pc.abstractfactory.example.factory.Link;

/**
 * 列表链接类
 * Created by Switch on 2017-02-17.
 */
public class ListLink extends Link {
    /**
     * 构造方法,传入标题和URL
     *
     * @param caption 标题
     * @param url     url
     */
    public ListLink(String caption, String url) {
        super(caption, url);
    }

    @Override
    public String makeHTML() {
        return "
  • " + super.caption + "
  • \n"
    ; } }
    ListTray类
    package com.pc.abstractfactory.example.listfactory;
    
    import com.pc.abstractfactory.example.factory.Item;
    import com.pc.abstractfactory.example.factory.Tray;
    
    /**
     * 列表Tray类
     * Created by Switch on 2017-02-17.
     */
    public class ListTray extends Tray {
        /**
         * 构造方法,传入标题
         *
         * @param caption 标题
         */
        public ListTray(String caption) {
            super(caption);
        }
    
        @Override
        public String makeHTML() {
            // 创建StringBuilder对象
            StringBuilder builder = new StringBuilder();
            // 将HTML暂存至StringBuilder对象
            builder.append("
  • \n"); builder.append(super.caption + "\n"); builder.append("
      \n"); for (Item item : items) { builder.append(item.makeHTML()); } builder.append("
    \n"
    ); builder.append("
  • \n"
    ); // 转化为String return builder.toString(); } }
    ListPage类
    package com.pc.abstractfactory.example.listfactory;
    
    import com.pc.abstractfactory.example.factory.Item;
    import com.pc.abstractfactory.example.factory.Page;
    
    /**
     * 列表页面类
     * Created by Switch on 2017-02-17.
     */
    public class ListPage extends Page {
        /**
         * 构造方法,传入标题和作者
         *
         * @param title  标题
         * @param author 作者
         */
        public ListPage(String title, String author) {
            super(title, author);
        }
    
        @Override
        public String makeHTML() {
            // 创建StringBuilder对象
            StringBuilder builder = new StringBuilder();
    
            builder.append(""</span> + <span class="hljs-keyword">super</span>.title + <span class="hljs-string">"\n");
            builder.append("\n");
            builder.append("\n");
            builder.append("\n");
            builder.append("

    " + super.title + "

    \n"
    ); builder.append("
      \n"); for (Item item : items) { builder.append(item.makeHTML()); } builder.append("
    \n"
    ); builder.append("
    " + this.author + "
    \n"
    ); builder.append("\n"); // 转化为String return builder.toString(); } }
    ListFactory类
    package com.pc.abstractfactory.example.listfactory;
    
    import com.pc.abstractfactory.example.factory.Factory;
    import com.pc.abstractfactory.example.factory.Link;
    import com.pc.abstractfactory.example.factory.Page;
    import com.pc.abstractfactory.example.factory.Tray;
    
    /**
     * Created by Switch on 2017-02-17.
     */
    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);
        }
    }

    测试类

    package com.pc.abstractfactory.example.listfactory.test;
    
    import com.pc.abstractfactory.example.factory.Factory;
    import com.pc.abstractfactory.example.factory.Link;
    import com.pc.abstractfactory.example.factory.Page;
    import com.pc.abstractfactory.example.factory.Tray;
    import org.junit.Test;
    
    /**
     * 测试ListFactory
     * Created by Switch on 2017-02-17.
     */
    public class ListFactoryTest {
    
        @Test
        public void testListFactory() {
            Factory factory = Factory.getFactory("com.pc.abstractfactory.example.listfactory.ListFactory");
    
            Link blog = factory.createLink("博客", "http://blog.csdn.net/q547550831");
            Link github = factory.createLink("Github", "http://www.github.com/Switch-vov");
    
            Tray mySite = factory.createTray("个人网站");
            mySite.add(blog);
            mySite.add(github);
    
            Link alibaba = factory.createLink("Alibaba", "http://www.alibaba.com");
            Link baidu = factory.createLink("Baidu", "http://www.baidu.com");
    
            Tray portal = factory.createTray("大型网站");
            portal.add(alibaba);
            portal.add(baidu);
    
            Page page = factory.createPage("网站介绍(列表版)", "Switch");
            page.add(mySite);
            page.add(portal);
    
            page.output();
        }
    }

    运行结果

    控制台输出
    网站介绍(列表版).html已编写完成。
    E盘下网站介绍(列表版).html的内容
    <html><head><title>网站介绍(列表版)title>
    <meta charset='utf-8'/>
    head>
    <body>
    <h1>网站介绍(列表版)h1>
    <ul>
    <li>
    个人网站
    <ul>
    <li><a href='http://blog.csdn.net/q547550831'>博客a>li>
    <li><a href='http://www.github.com/Switch-vov'>Githuba>li>
    ul>
    li>
    <li>
    大型网站
    <ul>
    <li><a href='http://www.alibaba.com'>Alibabaa>li>
    <li><a href='http://www.baidu.com'>Baidua>li>
    ul>
    li>
    ul>
    <hr/><address>Switchaddress>
    body>html>
    浏览器中运行结果

    设计模式学习笔记——抽象工厂(Abstract Factory)模式_第2张图片

    Table实现

    类图

    设计模式学习笔记——抽象工厂(Abstract Factory)模式_第3张图片

    实现代码

    TableLink类
    package com.pc.abstractfactory.example.tablefactory;
    
    import com.pc.abstractfactory.example.factory.Link;
    
    /**
     * 表格链接类
     * Created by Switch on 2017-02-17.
     */
    public class TableLink extends Link {
        /**
         * 构造方法,传入标题和URL
         *
         * @param caption 标题
         * @param url     url
         */
        public TableLink(String caption, String url) {
            super(caption, url);
        }
    
        @Override
        public String makeHTML() {
            return "" + super.caption + "";
        }
    }
    TableTray类
    package com.pc.abstractfactory.example.tablefactory;
    
    import com.pc.abstractfactory.example.factory.Item;
    import com.pc.abstractfactory.example.factory.Tray;
    
    /**
     * 表格Tray类
     * Created by Switch on 2017-02-17.
     */
    public class TableTray extends Tray {
        /**
         * 构造方法,传入标题
         *
         * @param caption 标题
         */
        public TableTray(String caption) {
            super(caption);
        }
    
        @Override
        public String makeHTML() {
            // 创建StringBuilder对象
            StringBuilder builder = new StringBuilder();
    
            // 将HTML暂存至StringBuilder对象
            builder.append("");
            builder.append("");
            builder.append("");
            builder.append("\n");
            builder.append("\n");
            for (Item item : items) {
                builder.append(item.makeHTML());
            }
            builder.append("
    " + caption + "
    "
    ); builder.append(""); // 转化为String return builder.toString(); } }
    TablePage类
    package com.pc.abstractfactory.example.tablefactory;
    
    import com.pc.abstractfactory.example.factory.Item;
    import com.pc.abstractfactory.example.factory.Page;
    
    /**
     * 表格页面类
     * Created by Switch on 2017-02-17.
     */
    public class TablePage extends Page {
        /**
         * 构造方法,传入标题和作者
         *
         * @param title  标题
         * @param author 作者
         */
        public TablePage(String title, String author) {
            super(title, author);
        }
    
        @Override
        public String makeHTML() {
            // 创建StringBuilder对象
            StringBuilder builder = new StringBuilder();
    
            builder.append(""</span> + <span class="hljs-keyword">super</span>.title + <span class="hljs-string">"\n");
            builder.append("\n");
            builder.append("\n");
            builder.append("\n");
            builder.append("

    " + super.title + "

    \n"
    ); builder.append("\n"); for (Item item : items) { builder.append(item.makeHTML()); } builder.append("
    \n"
    ); builder.append("
    " + this.author + "
    \n"
    ); builder.append("\n"); // 转化为String return builder.toString(); } }
    TableFactory类
    package com.pc.abstractfactory.example.tablefactory;
    
    import com.pc.abstractfactory.example.factory.Factory;
    import com.pc.abstractfactory.example.factory.Link;
    import com.pc.abstractfactory.example.factory.Page;
    import com.pc.abstractfactory.example.factory.Tray;
    
    /**
     * 表格工厂类
     * Created by Switch on 2017-02-17.
     */
    public class TableFactory extends Factory {
        @Override
        public Link createLink(String caption, String url) {
            return new TableLink(caption, url);
        }
    
        @Override
        public Tray createTray(String caption) {
            return new TableTray(caption);
        }
    
        @Override
        public Page createPage(String title, String author) {
            return new TablePage(title, author);
        }
    }

    测试类

    package com.pc.abstractfactory.example.tablefactory.test;
    
    import com.pc.abstractfactory.example.factory.Factory;
    import com.pc.abstractfactory.example.factory.Link;
    import com.pc.abstractfactory.example.factory.Page;
    import com.pc.abstractfactory.example.factory.Tray;
    import org.junit.Test;
    
    /**
     * TableFactory Tester.
     *
     * @author Switch
     * @version 1.0
     */
    public class TableFactoryTest {
        @Test
        public void testTableFactory() {
            Factory factory = Factory.getFactory("com.pc.abstractfactory.example.tablefactory.TableFactory");
    
            Link blog = factory.createLink("博客", "http://blog.csdn.net/q547550831");
            Link github = factory.createLink("Github", "http://www.github.com/Switch-vov");
    
            Tray mySite = factory.createTray("个人网站");
            mySite.add(blog);
            mySite.add(github);
    
            Link alibaba = factory.createLink("Alibaba", "http://www.alibaba.com");
            Link baidu = factory.createLink("Baidu", "http://www.baidu.com");
    
            Tray portal = factory.createTray("大型网站");
            portal.add(alibaba);
            portal.add(baidu);
    
            Page page = factory.createPage("网站介绍(表格版)", "Switch");
            page.add(mySite);
            page.add(portal);
    
            page.output();
        }
    }

    运行结果

    控制台输出
    网站介绍(表格版).html已编写完成。
    E盘下网站介绍(表格版).html的内容
    <html><head><title>网站介绍(表格版)title>
    <meta charset='utf-8'/>
    head>
    <body>
    <h1>网站介绍(表格版)h1>
    <table width='80%' border='3'>
    <td><table width='100%' border='l'><tr><td bgcolor='#cccccc' align='center' colspan='2'><b>个人网站b>td>tr>
    <tr>
    <td><a href='http://blog.csdn.net/q547550831'>博客a>td><td><a href='http://www.github.com/Switch-vov'>Githuba>td>tr>table>td><td><table width='100%' border='l'><tr><td bgcolor='#cccccc' align='center' colspan='2'><b>大型网站b>td>tr>
    <tr>
    <td><a href='http://www.alibaba.com'>Alibabaa>td><td><a href='http://www.baidu.com'>Baidua>td>tr>table>td>table>
    <hr/><address>Switchaddress>
    body>html>
    浏览器中运行结果

    设计模式学习笔记——抽象工厂(Abstract Factory)模式_第4张图片

    抽象工厂模式中的角色

    AbstractProduct(抽象产品)

    AbstractProduct角色负责定义AbstractProduct角色所生成的抽象零件和产品的接口(API)。在案例中,由Link类、Tray 类和Page类扮演此角色。

    AbstractFactory(抽象工厂)

    AbstractFactory角色负责定义用于生成抽象产品的接口( API)。在案例中,由Factory类扮演此角色。

    Client(委托者)

    Client角色仅会调用AbstractFactory角色和AbstractProduct角色的接口(API)来进行工作,对于具体的零件、产品和工厂一无所知。在案例中,由测试类扮演此角色。类图中省略了Client这一角色。

    ConcreteProduct(具体产品)

    ConcreteProduct角色负责实现AbstractProduct角色的接口(API)。在案例中,由以下包中的以下类扮演此角色。

    • listfactory包:ListLink类、ListTray类和ListPage
    • tablefactory包:TableLink类、TableTray类和TablePage

    ConcreteFactory(具体工厂)

    ConcreteFactory角色负责实现AbstractFactory角色的接口(API)。在案例中,由以下包中的以下类扮演此角色。

    • listfactory包:ListFactory
    • tablefactory包:TableFactory

    类图

    设计模式学习笔记——抽象工厂(Abstract Factory)模式_第5张图片

    GitHub:DesignPatternStudy

    ——————参考《图解设计模式》

    你可能感兴趣的:(Design,Pattern)