设计模式——抽象工厂模式
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();
} }
使用抽象工厂的好处:
在这种模式下,增加具体的工厂是很容易的,就像如果有新的数据库厂商过来想要开发,直接让他们实现具体的规范即可。
不过这种模式也是具有缺陷的:
不方便增加新的产品。
实现效果:
- 生成文件

- 打开效果

设计模式——抽象工厂模式的更多相关文章
- Java设计模式(三) 抽象工厂模式
原创文章,同步发自作者个人博客,转载请注明出处 http://www.jasongj.com/design_pattern/abstract_factory/ 抽象工厂模式解决的问题 上文<工厂 ...
- PHP设计模式(三)抽象工厂模式(Abstract Factory)
一.什么是抽象工厂模式 抽象工厂模式的用意为:给客户端提供一个接口,可以创建多个产品族中的产品对象 ,而且使用抽象工厂模式还要满足以下条件: 系统中有多个产品族,而系统一次只可能消费其中一族产品. 同 ...
- [设计模式]<<设计模式之禅>>抽象工厂模式
1 女娲的失误 上一篇讲了女娲造人的故事.人是造出来了,世界也热闹了,可是低头一看,都是清一色的类型,缺少关爱.仇恨.喜怒哀乐等情绪,人类的生命太平淡了,女娲一想,猛然一拍 脑袋,忘记给人类定义性别了 ...
- 设计模式(3)抽象工厂模式(Abstract Factory)
设计模式(0)简单工厂模式 设计模式(1)单例模式(Singleton) 设计模式(2)工厂方法模式(Factory Method) 源码地址 0 抽象工厂模式简介 0.0 抽象工厂模式定义 抽象工厂 ...
- <十一>读<<大话设计模式>>之抽象工厂模式
学习设计模式有一段时间了,对设计模式有一个体会,就是没那么难.就是设计程序遵循一些原则,让代码可复用,在改动的时候不用涉及太多的类,扩展方便.抽象工厂模式名字听起来抽象.但理解起来一点也不抽象,用语言 ...
- Java设计模式学习笔记(四) 抽象工厂模式
前言 本篇是设计模式学习笔记的其中一篇文章,如对其他模式有兴趣,可从该地址查找设计模式学习笔记汇总地址 1. 抽象工厂模式概述 工厂方法模式通过引入工厂等级结构,解决了简单工厂模式中工厂类职责太重的问 ...
- PHP设计模式(三)抽象工厂模式(Abstract Factory For PHP)
一.什么是抽象工厂模式 抽象工厂模式的用意为:给客户端提供一个接口,可以创建多个产品族中的产品对象 ,而且使用抽象工厂模式还要满足以下条件: 系统中有多个产品族,而系统一次只可能消费其中一族产品. 同 ...
- .NET设计模式(2):1.2 抽象工厂模式(Abstract Factory)
概述 抽象工厂模式(Abstract Factory)是所有形态的工厂模式中最为抽象和最具一般性的一种形态.抽象工厂模式是指当有多个抽象角色时,使用的一种工厂模式.抽象工厂模式可以向客户端提供一个接口 ...
- 设计模式(四)抽象工厂模式(Abstract Factory Pattern)
一.引言 在上一专题中介绍了工厂方法模式,工厂方法模式是为了克服简单工厂模式的缺点而设计出来的,简单工厂模式的工厂类随着产品类的增加需要增加额外的代码,而工厂方法模式每个具体工厂类只完成单个实例的创建 ...
- 设计模式(3)--抽象工厂模式(Absrtact Factory Pattern)
定义 抽象工厂模式的实质就是提供接口来创建一系列相关或独立的对象而不指定这些对象的具体类. 理解 在软件系统中,经常面临着"一系列相互依赖的对象"的创建工作:同时由于需求的变化,往 ...
随机推荐
- filter函数和map函数
filter filter()函数接收一个函数 f 和一个可迭代对象,这个函数 f 的作用是对每个元素进行判断,返回 True或 False,filter()根据判断结果自动过滤掉不符合条件的元素,返 ...
- linux的RMP命令(rmp包的安装与反安装)
RMP 是 LINUX 下的一种软件的可执行程序,你只要安装它就可以了.这种软件安装包通常是一个RPM包(Redhat Linux Packet Manager,就是Redhat的包管理器),后缀是. ...
- 华中农业大学校赛 I Catching Dogs
Catching Dogs Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 1140 Solved: 298[Submit][Status][Web B ...
- 突破MIME限制上传
方法:找一个正常的可上传的查看其的MIME类型,然后将马子的MIME改成合法的MIME即可.
- 跟着百度学PHP[13]-文件处理 文件后缀验证、设置随机文件名....
目录: 文件的处理:00x1 判断错误 文件的处理:00x2 判断类型 文件的处理:00x3 文件大小 ++++++++++++++++++++++++++++++++++++++++++++++++ ...
- lucene 内存索引存储每个field里内容的相关代码
相关的类调用关系 DocumentsWriterPerThread ——>DocFieldProcessor DocumentsWriterPerThread里的consumer对象(类型是 ...
- Groovy学习()Groovy是啥?
Groovy是啥? groovy是英文中的一个单词,有marvelous.wonderful和excellen的意思. groovy是轻量级的,动态的,面向对象的,并且运行在JVM上的. groovy ...
- No output operations registered, so nothing to execute
SparkStreaming和KafKa结合报错!报错之前代码如下: object KafkaWordCount{ val updateFunc = (iter:Iterator[(String,Se ...
- asp.net曲线图
highcharts的曲线图控件真的很强大,自己研究了下,做了一个简单的,给自己留个备忘,希望能帮到需要的朋友 Dome下载:http://files.cnblogs.com/linyijia/asp ...
- JavaScript的gzip静态压缩方法记录
传统的JS压缩(删除注释,删除多余空格等)提供的压缩率有时还是不尽不意,幸亏现在的浏览器都支持压缩传输(通过设置http header的Content-Encoding=gzip),可以通过服务器的配 ...