Abstract Factory模式,即抽象工厂模式,该模式要求Factory类为抽象的,并且里面的生产出来的产品也是抽象的!

这里需要着重说的一点就是,抽象类和抽象方法的作用——规范了子类的实现,以及当使用时候,直接可以面向抽象父类/接口的方式进行操作,利用多态的面向对象特性。

同时,需要注意的是,所有抽象的类全都是封装到一个包中的,与调用的不同。

这种方式的一个应用就是JDBC的规范,SUN公司在jdk中提供了相应的接口/抽象父类作为规范,而对应的数据库厂商则根据这个接口/抽象父类去写具体实现。这样一来,我们在操作数据库时候,直接使用sun公司提供的抽象父/接口,而不需要关注具体是怎么实现的,因为不管什么样的数据库,我们操作的代码都是一样的,唯一不同的就是导包不同。

在本次是实例中,使用的一个抽象工厂,以及三个抽象产品。最终希望的就是在E盘的根目录,生成对应的HTML页面。

在factory抽象类的包中,定义了抽象的类

  • Factory 抽象的 工厂类
package site.wangxin520.gof.abstractfactory.factory;

/**
* 抽象工厂的类,制作Link,Tray,Page
* 定义了抽象方法,规范了实现该方法的具体工厂类
* @author wangXgnaw
*
*/
public abstract class Factory { /**
* 根据实例工厂的全限定名,获取工厂实例,采用反射的方法
* @param factoryName 实例化工厂的全限定名
* @return Factory 返回实例化工厂
*/
public static Factory getFactory(String factoryName) { Factory factory=null;
try {
// factory = (Factory) Class.forName(factoryName).newInstance();
factory = (Factory) ClassLoader.getSystemClassLoader().loadClass(factoryName).newInstance();
} catch (Exception e) {
e.printStackTrace();
}
return factory;
} /**
* 抽象类,规范了创建Link和Tray和Page的方法
* @param caption
* @param url
* @return
*/
public abstract Link createLink(String caption,String url);
public abstract Tray createTray(String caption);
public abstract Page createPage(String title,String author);
}
  • Item 所有产品类的父类
package site.wangxin520.gof.abstractfactory.factory;

/**
* 方便统一处理Link和Tray的类
* Item类是,Link和Tray的父类
* @author wangXgnaw
*
*/
public abstract class Item { //caption字段表示标题
protected String caption; /**
* 构造函数
* @param caption
*/
public Item(String caption){
this.caption=caption;
} /**
* 制作html,返回HTML文件的内容
* 本方法是抽象方法,需要子类去实现
* @return String
*/
public abstract String makeHTML();
}
  • Link抽象的工厂中的产品,用于记录超链接的
package site.wangxin520.gof.abstractfactory.factory;

/**
* Link类抽象的表示HTML的链接的类
* @author wangXgnaw
*
*/
public abstract class Link extends Item{ //url字段保存的是超链接所指向的地址
protected String url; /**
* 构造函数,由于继承了一个抽象类,且抽象父类只有一个有参构造
* 所以,构造函数必须提供,并且调用的是父类的有参构造
* @param caption
* @param url
*/
public Link(String caption,String url) {
super(caption);
this.url=url;
} }
  • Tray抽象工厂的产品,用于存放元素的
package site.wangxin520.gof.abstractfactory.factory;

import java.util.ArrayList;

/**
* Tray类也要是一个抽象类
* Tray类表示的是一个含有多喝Link类和Tray类的容器
* Tray有托盘的意思
* @author wangXgnaw
*
*/
public abstract class Tray extends Item{ //用于保存Tray和Link类,作为容器
protected ArrayList<Item> tray=new ArrayList<>(); /**
* 构造方法,调用父类的有参构造
* @param caption
*/
public Tray(String caption) {
super(caption);
} /**
* 使用add方法将Link和Tray类集合在一起
* @param item
*/
public void add(Item item){
tray.add(item);
}
}
  • Page抽象工厂的产品,页面相关
package site.wangxin520.gof.abstractfactory.factory;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList; /**
* 抽象的表示HTML页面的类
* @author wangXgnaw
*
*/
public abstract class Page { //姓名和作者
protected String title;
protected String author; //用于保存页面中的元素
protected ArrayList<Item> content=new ArrayList<>(); /**
* page的构造,传入标题和作者
* @param title
* @param author
*/
public Page(String title,String author){
this.title=title;
this.author=author;
} /**
* 在页面中存入元素
* @param item
*/
public void add(Item item){
content.add(item);
} /**
* 向文件中写入,这里固定是向E盘根目录中写入一个html文件
*/
public void output(){
String filename=title+".html"; FileWriter fw=null;
try {
fw = new FileWriter(new File("E:/",filename));
fw.write(this.makeHTML());
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
fw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
System.out.println(filename+"编写完成");
} /**
* 定义一个制作HTML的方法为子类提供规范
* @return
*/
public abstract String makeHTML();
}

在其他包中,实现了以上的接口,方便使用

  • ListFactory工厂类的具体实现
package site.wangxin520.gof.abstractfactory.listfactory;

import site.wangxin520.gof.abstractfactory.factory.Factory;
import site.wangxin520.gof.abstractfactory.factory.Link;
import site.wangxin520.gof.abstractfactory.factory.Page;
import site.wangxin520.gof.abstractfactory.factory.Tray; /**
* 表示具体工厂的类
* 制作ListLink,ListTray,ListPage
* @author wangXgnaw
*
*/
public class ListFactory extends Factory{ /**
* 返回具体的ListLink实例,下同
*/
@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);
} }
  • ListLink上面Link类的具体实现
package site.wangxin520.gof.abstractfactory.listfactory;

import site.wangxin520.gof.abstractfactory.factory.Link;

/**
* 具体零件,表示HTML的连接的类
* @author wangXgnaw
*
*/
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><br/>";
} }
  • ListTray Tray类的具体实现
package site.wangxin520.gof.abstractfactory.listfactory;

import site.wangxin520.gof.abstractfactory.factory.Item;
import site.wangxin520.gof.abstractfactory.factory.Tray; /**
* 具体零件,表示含有Link和Tray的类
*
* @author wangXgnaw
*
*/
public class ListTray extends Tray { public ListTray(String caption) {
super(caption);
} @Override
public String makeHTML() { StringBuilder sb = new StringBuilder();
sb.append("<li>").append(caption).append("<ul>"); for (Item item : tray) {
sb.append(item.makeHTML());
} sb.append("</ul>").append("</li>"); return sb.toString();
} }
  • ListPage Page类的具体实现
package site.wangxin520.gof.abstractfactory.listfactory;

import site.wangxin520.gof.abstractfactory.factory.Item;
import site.wangxin520.gof.abstractfactory.factory.Page; /**
* 具体零件,表示HTML页面的类
* @author wangXgnaw
*
*/
public class ListPage extends Page{ public ListPage(String title, String author) {
super(title, author);
} @Override
public String makeHTML() { StringBuilder sb=new StringBuilder(); sb.append("<html><head><title>"+title+"</title></head>"); sb.append("<body>");
sb.append("<h1>"+title+"</h1>");
sb.append("<ul>");
for (Item item : content) {
sb.append(item.makeHTML());
}
sb.append("</ul>");
sb.append("<hr>");
sb.append("<address>"+author+"</address>"); sb.append("</body></html>"); return sb.toString();
} }

测试类以及测试方法

package site.wangxin520.gof.abstractfactory;

import site.wangxin520.gof.abstractfactory.factory.Factory;
import site.wangxin520.gof.abstractfactory.factory.Link;
import site.wangxin520.gof.abstractfactory.factory.Page;
import site.wangxin520.gof.abstractfactory.factory.Tray; /**
* 抽象工厂模式的测试类
* @author wangXgnaw
*
*/
public class Test { public static void main(String[] args){ //获取工厂实体,参数是实体工厂的全限定名
Factory factory=Factory.getFactory("site.wangxin520.gof.abstractfactory.listfactory.ListFactory"); //创建超链接
Link link1 = factory.createLink("王鑫", "http://www.wangxin520.site/");
Link link2 = factory.createLink("淘宝", "https://www.taobao.com/");
Link link3 = factory.createLink("京东", "https://www.jd.com/"); //创建序列,并且将超链接放到序列中
Tray t1 = factory.createTray("主页");
t1.add(link1);
Tray t2 = factory.createTray("购物");
t2.add(link2);
t2.add(link3); //创建页面,并且将序列放到页面里面
Page page = factory.createPage("首页", "王鑫");
page.add(t1);
page.add(t2); //调用page的output()方法去实现写入文件
page.output();
} }

使用抽象工厂的好处:

在这种模式下,增加具体的工厂是很容易的,就像如果有新的数据库厂商过来想要开发,直接让他们实现具体的规范即可。

不过这种模式也是具有缺陷的:

不方便增加新的产品。

实现效果:

  • 生成文件

  • 打开效果

设计模式——抽象工厂模式的更多相关文章

  1. Java设计模式(三) 抽象工厂模式

    原创文章,同步发自作者个人博客,转载请注明出处 http://www.jasongj.com/design_pattern/abstract_factory/ 抽象工厂模式解决的问题 上文<工厂 ...

  2. PHP设计模式(三)抽象工厂模式(Abstract Factory)

    一.什么是抽象工厂模式 抽象工厂模式的用意为:给客户端提供一个接口,可以创建多个产品族中的产品对象 ,而且使用抽象工厂模式还要满足以下条件: 系统中有多个产品族,而系统一次只可能消费其中一族产品. 同 ...

  3. [设计模式]<<设计模式之禅>>抽象工厂模式

    1 女娲的失误 上一篇讲了女娲造人的故事.人是造出来了,世界也热闹了,可是低头一看,都是清一色的类型,缺少关爱.仇恨.喜怒哀乐等情绪,人类的生命太平淡了,女娲一想,猛然一拍 脑袋,忘记给人类定义性别了 ...

  4. 设计模式(3)抽象工厂模式(Abstract Factory)

    设计模式(0)简单工厂模式 设计模式(1)单例模式(Singleton) 设计模式(2)工厂方法模式(Factory Method) 源码地址 0 抽象工厂模式简介 0.0 抽象工厂模式定义 抽象工厂 ...

  5. &lt;十一&gt;读&lt;&lt;大话设计模式&gt;&gt;之抽象工厂模式

    学习设计模式有一段时间了,对设计模式有一个体会,就是没那么难.就是设计程序遵循一些原则,让代码可复用,在改动的时候不用涉及太多的类,扩展方便.抽象工厂模式名字听起来抽象.但理解起来一点也不抽象,用语言 ...

  6. Java设计模式学习笔记(四) 抽象工厂模式

    前言 本篇是设计模式学习笔记的其中一篇文章,如对其他模式有兴趣,可从该地址查找设计模式学习笔记汇总地址 1. 抽象工厂模式概述 工厂方法模式通过引入工厂等级结构,解决了简单工厂模式中工厂类职责太重的问 ...

  7. PHP设计模式(三)抽象工厂模式(Abstract Factory For PHP)

    一.什么是抽象工厂模式 抽象工厂模式的用意为:给客户端提供一个接口,可以创建多个产品族中的产品对象 ,而且使用抽象工厂模式还要满足以下条件: 系统中有多个产品族,而系统一次只可能消费其中一族产品. 同 ...

  8. .NET设计模式(2):1.2 抽象工厂模式(Abstract Factory)

    概述 抽象工厂模式(Abstract Factory)是所有形态的工厂模式中最为抽象和最具一般性的一种形态.抽象工厂模式是指当有多个抽象角色时,使用的一种工厂模式.抽象工厂模式可以向客户端提供一个接口 ...

  9. 设计模式(四)抽象工厂模式(Abstract Factory Pattern)

    一.引言 在上一专题中介绍了工厂方法模式,工厂方法模式是为了克服简单工厂模式的缺点而设计出来的,简单工厂模式的工厂类随着产品类的增加需要增加额外的代码,而工厂方法模式每个具体工厂类只完成单个实例的创建 ...

  10. 设计模式(3)--抽象工厂模式(Absrtact Factory Pattern)

    定义 抽象工厂模式的实质就是提供接口来创建一系列相关或独立的对象而不指定这些对象的具体类. 理解 在软件系统中,经常面临着"一系列相互依赖的对象"的创建工作:同时由于需求的变化,往 ...

随机推荐

  1. 关于linux下配置python3的virtualenvwrapper

    python版本管理&virtualenv管理 virtualenvwrapper是用来管理virtualenv的扩展包,用着很方便. 注意,在python3中,pip的安装:sudo apt ...

  2. css 盒子垂直居中

    面试的时候经常会被问到这样一个题目:让一个元素中内容垂直居中怎么做.其实之前,我就会两种,line-height和table-cell,今天做项目,遇到了这个问题,就系统的查了一下,总结一下方法: 1 ...

  3. dubbo异步调用三种方式

    异步通讯对于服务端响应时间较长的方法是必须的,能够有效地利用客户端的资源,在dubbo中,消费端<dubbp:method>通过 async="true"标识. < ...

  4. 词法分析器总结--flex&bison

    转自:项目总结之词法分析器 无论是词法分析,还是语法分析,给我的第一感觉就是逻辑要严谨.由于项目有自己一套完整的语言和语法,设计好其对应的词法分析器和语法分析器显得尤为重要. 我们采用flex进行词法 ...

  5. pycharm编写spark程序,导入pyspark包

    一种方法: File --> Default Setting --> 选中Project Interpreter中的一个python版本-->点击右边锯齿形图标(设置)-->选 ...

  6. 教程-Delphi中的GExperts搜索代码快捷键

    Shift+Ait+S  打开搜索 Ctrl+Ait+R 打开上次搜索结果

  7. php5共存php7

    PHP7与PHP5共存于CentOS7 原文参考 原理 思路很简单:PHP5是通过yum安装的在/usr/,套接字在/var/run/php-fpm.socket,PHP7自己编译装在/usr/loc ...

  8. php扩展安装

    [root@129-2-10-2 src]# cat kuozhan.sh #!/bin/bash###install redis extend #########cd /usr/local/srct ...

  9. I2C和SPI

    I2C(Inter-Integrated Circuit)总线 两线式串行总线,用于连接微控制器及其外围设备.是微电子通信控制领域广泛采用的一种总线标准.它是同步通信的一种特殊形式,具有接口线少,控制 ...

  10. opencv 摄像头人脸检测

    PYTHON ubuntu16.04 默认安装的Python版本2.7.12,当用pip install opencv-python 安装了opencv for python 3.3.0.10后,运行 ...