Java设计模式-抽象工厂模式(八)

目录

 

一、什么是抽象工厂模式

二、示例程序

三、UML

四、拓展思路与注意事项

1、易于增加具体的工厂

2、难以增加新的零件


一、什么是抽象工厂模式

 为创建一组相关或相互依赖的对象提供一个接口,而且无需指定他们的具体类,这称之为抽象工厂模式(Abstract Factory)。我们并不关心零件的具体实现,而是只关心接口(API)。我们仅使用该接口(API)将零件组装称为产品。

二、示例程序

 

1、抽象的零件:Item类

package com.as.module.abstractfactory;

/**
 * 抽象的零件
 * @author Andy
 * @date 2021/4/29 23:16
 */
public abstract class Item {
    protected String caption;

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

    public abstract String makeHTML();
}

2、抽象的零件:Link类

package com.as.module.abstractfactory;

/**
 * TODO
 *
 * @author Andy
 * @date 2021/4/29 23:18
 */
public abstract class Link extends Item {
    protected String url;
    public Link(String caption,String url) {
        super(caption);
        this.url = url;
    }



}

3、抽象的零件:Tray类

package com.as.module.abstractfactory;

import java.util.ArrayList;

/**
 * TODO
 *
 * @author Andy
 * @date 2021/4/29 23:20
 */
public abstract class Tray extends Item{
    protected ArrayList tray = new ArrayList();

    public Tray(String caption) {
        super(caption);
    }
    public void add(Item item){
        tray.add(item);
    }
}

4、抽象的产品:Page类

package com.as.module.abstractfactory;

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

/**
 * 抽象的产品
 * @author Andy
 * @date 2021/4/29 23:22
 */
public abstract class Page {
    protected String title;
    protected String author;
    protected ArrayList 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(){
        String filename = title+".html";
        try {
            Writer writer = new FileWriter(filename);
            writer.write(this.makeHTML());
            writer.close();
            System.out.println(filename+"编写完成");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    public abstract String makeHTML();

}

5、抽象的工厂:Factory类

package com.as.module.abstractfactory;

/**
 * 抽象的工厂
 * @author Andy
 * @date 2021/4/29 23:31
 */
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();
        } 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);

}

6、具体的工厂:ListFactory类

package com.as.module.abstractfactory;

/**
 * 具体的工厂
 * @author Andy
 * @date 2021/4/29 23:36
 */
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);
    }
}

7、具体的零件:ListLink类
 

package com.as.module.abstractfactory;

/**
 * 具体的零件
 * @author Andy
 * @date 2021/4/29 23:37
 */
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";
    }


}

8、具体的零件:ListTray类

package com.as.module.abstractfactory;

import java.util.Iterator;

/**
 * TODO
 *
 * @author Andy
 * @date 2021/4/29 23:43
 */
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 it =  tray.iterator();
        while(it.hasNext()){
            Item item = (Item)it.next();
            buffer.append(item.makeHTML());
        }
        buffer.append("</ul>\n");
        buffer.append("</li>\n");
        return buffer.toString();
    }
}

9、具体的零件:ListPage类

package com.as.module.abstractfactory;

import java.util.Iterator;

/**
 * 具体的产品
 * @author Andy
 * @date 2021/5/4 10:42
 */
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 it = content.iterator();
        while(it.hasNext()){
            Item 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();
    }
}

10、抽象工厂方法测试用例

package com.as.module.abstractfactory;

import java.util.List;

/**
 *
 * @author Andy
 * @date 2021/5/4 10:54
 */
public class TestAbstractFactory {

    public static void main(String[] args) {
        Factory factory = Factory.getFactory("com.as.module.abstractfactory.ListFactory");
        Link people = factory.createLink("人民日报","http://www.people.com.cn/");
        Link gmw = factory.createLink("光明日报","http://www.gmw.cn/");

        Link baidu = factory.createLink("Baidu","http://www.baidu.com/");
        Link google = factory.createLink("Google","http://www.google.com/");

        Tray traynews = factory.createTray("日报");
        traynews.add(people);
        traynews.add(gmw);

        Tray traysearch = factory.createTray("搜索引擎");
        traysearch.add(baidu);
        traysearch.add(google);

        Page page = factory.createPage("LinkPage","Andy");
        page.add(traynews);
        page.add(traysearch);
        page.output();

    }
}

运行结果:

三、UML

 

 

登场角色:

1、AbstractProduct(抽象产品)

AbstractProduct角色负责定义AbstractPFactory角色所生成的抽象零件和产品的接口。在示例程序中,由Link类,Tray类和Page类扮演此角色

2、AbstractFactory(抽象工厂)

AbstractFactory角色负责定义用于生成抽象产品的接口。在示例程序中,由Factory

3、Client(委托者)

Client角色仅会调用AbstractProduct角色和AbstractFactory角色来进行工作,对于具体的零件,产品,工厂一无所知。示例程序中,由具体的TestAbstractFactory 扮演此角色

4、ConcreteProduct(具体产品)

ConcreteProduct角色负责实现抽象产品角色的接口,示例程序中,由ListLink,ListTray,ListPage类扮演此角色

5、ConcreteFactory(具体工厂)

ConcreteFactory角色负责实现AbstractFactory的接口,示例程序中ListFactory扮演此角色

四、拓展思路与注意事项

1、易于增加具体的工厂

在AbstractFactory模式中增加具体的工厂是非常容易的。这里说的“容易"是指需要编写哪些类和需要实现哪些方法都非常清楚。

假设我们现在要在示例程序中增加新的具体工厂,那么需要做的就是编写Factory、Tray、Link、Page的子类,并实现他们定义的抽象方法,也就是将factory包中的抽象部分全部具体化即可。

这样一来,无论要增加多少个具体工厂,都无需修改抽象工厂和Main部分

2、难以增加新的零件

试想一下要在AbstractFactory模式增加新的零件时应当如何做。例如,我们要在factory包中增加一个表示图像的Picture零件。这时,我们必须要对所有的具体工厂进行相应的修改才行。例如,在listFactory包中,我们必须要做以下修改

(1)在ListFactory包中加入createPicture方法

(2)新增listPicture类

已经完成的具体的工厂越多,修改的工作量越大

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值