1、前言html
上次咱们学习了Builder模式,用来组装复杂的实例,Builder就是咱们盖房子的一块块砖头,钢筋和水泥,以及简单的用法,使用监工将这些元素有机的组合在了一块儿就可以建造整个建筑了,是监工将这些原材料按照必定的次序和特定的处理流程糅合在一块儿,这个过程就是组装。而如今咱们学习了抽象工厂模式,将关键零件组装成产品。java
在此以前,让咱们对前面的几种模式作简单的回顾,首先咱们学习了迭代器模式,使用了工厂方法创造迭代器,而且完成了元素的内部实现和遍历的分离,所以成为“器”,也算是一种配合,其次咱们学习了适配器,有类适配器和对象适配器,这二者只是实现的方式不一样,本质是同样的,都是经过在原素材上加入一个适配器使得可以知足如今的须要,通常用在版本之间的兼容上使得新版本的内容可以在旧版本上使用(适配),以及一些复用的时候须要适当的修改(适配)的场合;以后咱们学习了模板模式和工厂模式,模板方法的一个特殊实现其实就是工厂方法,模板方法就是经过在父类之中定义职责,而后让子类实现各自的子任务,最后经过父类进行调用,提升了代码的可修改性和可扩展性,工厂方法则是在模板方法的基础上,经过生产产品的方式将框架的实现分离,遵循了高内聚低耦合的原则;在以后咱们学习了单例模式和原型模式,单例模式是保证全局关于某个类只有一个对象,在某些多线程或者编码误用的条件下很是重要,原型模式则是实现了对象的深浅拷贝,使得通过了很长时间才获得的对象可以保存以及复制和使用,省去了不少没必要要的new操做。以后咱们学习了Builder模式,经过增长一个监工类来将父类中定义的方法组合起来实现某种功能,实现了类的隔离,便于代码的复用,是模板模式的升级版。编程
学习了这么多模式,不知道你们对设计模式有没有什么感悟,能够说就是经过接口、抽象类。继承、多态等机制遵循高内聚低耦合、封闭原则、里式代换原则等实现代码的可复用性,可扩展性,尽管比之前变得复杂了,其实成都越大扩展就越简单。那么为何又是抽象工厂模式呢?设计模式
抽象工厂模式是一个很是复杂的模式,和工厂方法键值差异太大了,可是也有相同之处,那就是抽象工厂也是用了工厂方法来创造产品,只不过抽象工厂模式中包含了零件、产品、工厂、抽象等概念,这样就很是的复杂了,通常还要用到模板方法、迭代器甚至原型模板等,就“抽象”两个字来讲,就是将全部的角色分红两部分,一部分是这个角色的抽象类,另外一部分是这个角色的实现类,工厂就是沿用了工厂模式,所以抽象工厂模式分为两大部分,抽象部分和具体实现部分,如图所示:多线程
上面的抽象部分,最重要的就是抽象的工厂类(Link)、抽象的零件类(Tray)、抽象的产品类(Page),这两个零件有共同之处,所以经过item类进行抽象便于二者之间的互通。下面的具体实现部分即便对抽象的实现了,以后咱们使用main类来进行整合,能够发现咱们只用对抽象类进行编程,彻底不用使用任何的具体类就能实现咱们想要的功能,甚至致使编译器在编译的时候还须要指出须要编译的具体类,由于咱们使用了Class.forName()方法实现了反射。这样的结构看似很是的庞大,其实仔细的推敲,反而妙不可言,当咱们还想建立一个具体的工厂的时候实在是太简单了,原来抽象工厂的代码都不用修改,只用按照响应的抽象实现就能够了,以后咱们就能够直接使用了,只用在main中将Class.forName()所指定的类改一下就能够了,很是的方便。凡有利就有弊,若是咱们对抽象工厂中的某些定义不满意了呢,这个时候若是咱们对抽象方法进行必定的调整和更改(增长或删除),那么全部实现了该抽象工厂的具体工厂的类都须要进行修改,若是有100个具体工厂,无疑是很是可怕的,所以咱们应该理智的取舍,废话少说,让咱们看一下代码。app
2、代码实现框架
咱们将类分红三个部分,这样思路更加清晰,第一部分是抽象工厂中的类,第二部分是具体实现的具体工厂类,第三部分是测试使用的Main类。ide
抽象工厂包:post
Item 抽象类:学习
package designMode.abstractfactory.factory; public abstract class Item { protected String caption; public Item(String caption){ this.caption=caption; } public abstract String makeHTML(); }
Link抽象类:
package designMode.abstractfactory.factory; public abstract class Link extends Item{ public String url; public Link(String caption,String url) { super(caption); this.url = url; } }
Tray抽象类:
package designMode.abstractfactory.factory; import java.util.ArrayList; public class Tray extends Item { protected ArrayList items = new ArrayList(); public Tray(String caption) { super(caption); } @Override public String makeHTML() { return null; } public void add(Item item){ items.add(item); } }
Page抽象类:
package designMode.abstractfactory.factory; import java.io.FileWriter; import java.io.IOException; import java.io.Writer; import java.util.ArrayList; public abstract class Page { protected String title; protected String author; protected ArrayList content = new ArrayList(); public Page(String title,String author) { this.author = author; this.title=title; } 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(); } catch (IOException e) { e.printStackTrace(); } System.out.println("写入文件:"+filename+"已成功!"); } public abstract String makeHTML() ; }
Factory工厂抽象类:
package designMode.abstractfactory.factory; //Factory工厂抽象类: 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(); } return factory; } public abstract Link createLink(String caption,String url); public abstract Tray createTray(String caption); public abstract Page createPage(String title,String author); }
具体实现工厂类:
ListLink类:
package designMode.abstractfactory.listfactory; import designMode.abstractfactory.factory.Link; 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"; } }
ListTray类:(迭代器模式)ArrayList自己实现了迭代器。
package designMode.abstractfactory.listfactory; import designMode.abstractfactory.factory.Item; import designMode.abstractfactory.factory.Tray; import java.util.Iterator; public class ListTray extends Tray { public ListTray(String caption) { super(caption); } public String makeHTML() { StringBuffer sb=new StringBuffer(); sb.append("<li>\n"); sb.append(caption+"\n"); sb.append("<ul>\n"); Iterator it=items.iterator(); while(it.hasNext()){ Item item=(Item)it.next(); sb.append(item.makeHTML()); } sb.append("</ul>\n"); sb.append("</li>\n"); return sb.toString(); } }
ListPage类:(迭代器模式)ArrayList自己实现了迭代器。
package designMode.abstractfactory.listfactory; import designMode.abstractfactory.factory.Item; import designMode.abstractfactory.factory.Page; import java.util.Iterator; public class ListPage extends Page { public ListPage(String title, String autor) { super(title, autor); } @Override public String makeHTML() { StringBuffer sb=new StringBuffer(); sb.append("<html><head><title>"+title+"</title></head>"); sb.append("<body>\n"); sb.append("<h1>"+title+"</h1>"); sb.append("<ul>\n"); Iterator it=content.iterator(); while(it.hasNext()){ Item item=(Item)it.next(); sb.append(item.makeHTML()); } sb.append("</ul>\n"); sb.append("<hr><address>"+author+"</address>"); sb.append("</body></html>\n"); return sb.toString(); } }
ListFactory类:(工厂方法模式)
package designMode.abstractfactory.listfactory; import designMode.abstractfactory.factory.Factory; import designMode.abstractfactory.factory.Link; import designMode.abstractfactory.factory.Page; import designMode.abstractfactory.factory.Tray; 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); } }
Main类:
package designMode.abstractfactory.test; import designMode.abstractfactory.factory.Factory; import designMode.abstractfactory.factory.Link; import designMode.abstractfactory.factory.Page; import designMode.abstractfactory.factory.Tray; public class Main { public static void main(String[] args) { String[] choice = {"designMode.abstractfactory.listfactory.listFactory.ListFactory"}; Factory factory = Factory.getFactory(choice[0]); Tray tray_life=factory.createTray("个人生活"); Link link_graduate=factory.createLink("个人本科", "http://www.swjtu.edu.cn"); Link link_postgraduate=factory.createLink("个人研究生","http://www.uestc.edu.cn"); tray_life.add(link_graduate); tray_life.add(link_postgraduate); Tray tray_blog=factory.createTray("个人博客"); Link link_iterator=factory.createLink("迭代器","https://www.cnblogs.com/zyrblog/p/9217673.html"); Link link_adapter=factory.createLink("适配器", "https://www.cnblogs.com/zyrblog/p/9218316.html"); tray_blog.add(link_iterator); tray_blog.add(link_adapter); Tray tray_blog_all=factory.createTray("博客园"); Link link_other1=factory.createLink("解释器模式", "https://www.cnblogs.com/Answer-Geng/p/9231042.html"); Link link_other2=factory.createLink("OAuth 2.0", "https://www.cnblogs.com/cjsblog/p/9230990.html"); tray_blog_all.add(tray_blog); tray_blog_all.add(link_other1); tray_blog_all.add(link_other2); Page page=factory.createPage("zyr", "朱彦荣"); page.add(tray_life); page.add(tray_blog_all); page.output(); } }
能够看到彻底组成了一个网页。看到这里你们可能很质疑,难道废了这么大的功夫就是为了实现这么简单的功能?其实这里咱们能够看到抽象工厂的强大之处,零件的组装与嵌套,相互关联,经过迭代器、模板模式、工厂模式等最终实现了这种功能,可扩展性很是强大,若是还要生成其它种类的工厂,将很是的方便,直接写实现类就能够了,其它代码基本不须要改动,这样的功能能够说很是强大了,至今为止咱们不少的代码都是强耦合的,很难实现复用,而这个抽象的工厂模式就能够实现高层次的复用,只须要知道实现类的类名就能够执行了,咱们彻底能够实现其余工厂,从而实现其余的功能。抽象工厂模式最重要的就是可复用性和完美的隔离性,其中使用了makeHTML()不少次,经过迭代器来展示了这个方法的多台。灵活使用抽象工厂模式能够说是设计模式真正入门的起点。抽象工厂将抽象零件组装成抽象产品,易于增长具体的工厂难于增长新的零件。