图解设计模式 - Abstract Factory 模式

本文介绍抽象工厂模式的应用,通过创建不同类型但属于同一族的对象,无需指定具体类即可组装出完整的产品。文中详细解释了各个角色的功能,并提供了一个使用抽象工厂模式生成HTML文件的例子。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

读书笔记 仅供参考

Abstract Factory

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

UML 和角色

AbstractProduct

负责定义 AbstractFactory 角色所生成的抽象零件和产品的接口(API)

AbstractFactory

负责定义用于生成抽象产品的接口(API)

ConcreteProduct

负责实现 AbstractProduct 角色的接口(API)
#### ConcreateFactory
负责实现 AbstractFactory 角色的接口(API)
#### UML这里写图片描述

例子

例子大体是使用抽象工厂模式来组装一个 html 文件,零件就要 Link 和 Tray,最后组装成一个 Page,写入文件。

类名说明
factoryFactory抽象类,代表工厂, 根据不同情况返回不同工厂
factoryItem抽象类,所有零件的父类(不包括 Page)
factoryLink抽象类,代表链接
factoryTray抽象类,代表容器
factoryPage抽象类,代表网页
Main测试
listFactoryListFactory工厂,可以生产下面三种零件
listFactoryListLink链接,输出 HTML 字符串
listFactoryListTray容器,输出 HTML 字符串
listFactoryListPage页面,输出 HTML 字符串
tableFactoryTableFactory工厂,可以生产下面三种零件
tableFactoryTableLink链接,输出 HTML 字符串
tableFactoryTableTray容器,输出 HTML 字符串
tableFactoryTablePage页面,输出 HTML 字符串
public abstract class Factory {
    //根据不同参数得到不同工厂的实例
    public static Factory getFactory(String className) {
        Factory factory = null;
        try {
            factory = (Factory) Class.forName(className).newInstance();
        } catch (ClassNotFoundException e) {
            System.out.println("not found " + className + " class");
        } catch (Exception 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);
}
//代表项目,是 Link 和 Tray 的父类
public abstract class Item {
    //项目的标题
    protected String caption;

    public Item(String caption) {
        this.caption = caption;
    }

    public abstract String makeHtml();
}
//表示 HYML 超链接的类
public abstract class Link extends Item{

    protected String url;

    public Link(String caption, String url) {
        super(caption);
        this.url = url;
    }
}
//抽象地表示 HTML 页面的类,可以看作是零件组成的产品
public abstract class Page {
    protected String title;
    protected String author;
    protected List<Item> content = new ArrayList<>();

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

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

    public void output() {
        try {
            String fileNmae = "file/abstractFactory/" + title + ",html";
            Writer writer = new FileWriter(fileNmae);
            writer.write(this.makeHtml());
            writer.close();
            System.out.println(fileNmae + "编写完成");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public abstract String makeHtml();
}
//Tray 类表示一个含有多个 Link 类和 Tray 类的容器。
public abstract class Tray extends Item{
    protected List<Item> tray = new ArrayList<>();

    public Tray(String caption) {
        super(caption);
    }
    public void add(Item item) {
        tray.add(item);
    }
}
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);
    }
}
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";
    }
}
public class ListPage extends Page {
    public ListPage(String title, String author) {
        super(title, author);
    }

    @Override
    public String makeHtml() {
        StringBuffer buffer = new StringBuffer();
        buffer.append("<html><head><title>" + title + "</title></head>\n");
        buffer.append("<body>\n");
        buffer.append("<h1>" + title + "</h1>\n");
        buffer.append("<ul>\n");
        Iterator<Item> it = content.iterator();
        while (it.hasNext()) {
            Item item = it.next();
            buffer.append(item.makeHtml());
        }
        buffer.append("</ul>\n");
        buffer.append("<hr><address>" + author + "</address>");
        buffer.append("</body></html>\n");
        return buffer.toString();
    }
}
public class ListTray extends Tray {
    public ListTray(String caption) {
        super(caption);
    }

    @Override
    public String makeHtml() {
        StringBuffer buffer = new StringBuffer();
        buffer.append("<li>\n");
        buffer.append(caption + "\n");
        buffer.append("<ul>\n");
        Iterator<Item> it = tray.iterator();
        while (it.hasNext()) {
            Item item = it.next();
            buffer.append(item.makeHtml());
        }
        buffer.append("</ul>\n");
        buffer.append("</li>\n");
        return buffer.toString();
    }
}
UML

这里写图片描述

优缺点

优点是易于添加新的具体的工厂,方法都已经定义好了。
缺点是难以添加新的零件,需要修改所有的工厂。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值