图解设计模式-Abstract Factory模式
抽象工厂的工作是将“抽象零件”组装成“抽象产品”。
我们不关心零件的具体实现,而是只关心接口API。我们仅适用该接口API将零件组装成为产品。
角色:
AbstractProduct抽象产品:负责定义AbstractFactory角色所生成的抽象零件和产品的接口。在示例中,友Link、Tray、Page类扮演。
AbstractFactory抽象工厂:负责定义用于生成抽象产品的API接口,在示例中,有Factory扮演。
Client委托者:该角色仅会调用AbstractProduct角色和AbstractFactory角色的接口API来进行工作。在示例中由Main类扮演。
ConcreteProduct具体产品:负责实现AbstractProduct角色的API接口。在示例中由listfactory包下的ListLink、ListTray、ListPage类与tablefactory包下的TableLink、TableTray、TablePage类来扮演。
ConcreteFactory具体工厂:负责实现AbstractFactory角色的API接口,在示例中,由listfactory包下的ListFactory与tablefactory包下的TableFactory类扮演。
优点:
易于增加具体的工厂:只需要Factory、Link、Tray、Page四个类即可。
代码:
public abstract class Item { protected String caption; public Item(String caption) { this.caption = caption; } public abstract String makeHTML(); }
public abstract class Link extends Item{ protected String url; public Link(String caption,String url) { super(caption); this.url = url; } }
public abstract class Tray extends Item { protected List trayList = new ArrayList(); public Tray(String caption) { super(caption); } public void add(Item item) { trayList.add(item); } }
public abstract class Page{ protected String author; protected String title; protected List content = new ArrayList(); public Page(String author,String title) { this.title = title; this.author = author; } public void add(Item item){ content.add(item); } public void out() { String filename = "D:\\"+title+".html"; try { PrintWriter printWriter = new PrintWriter(new FileWriter(filename)); printWriter.println(this.makeHTML()); printWriter.close(); } catch (IOException e) { e.printStackTrace(); } } public abstract String makeHTML(); }
public abstract class Factory { public static Factory getFactory(String classname) { Factory factory = null; try { factory = (Factory) Class.forName(classname).newInstance(); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InstantiationException e) { e.printStackTrace(); } return factory; } public abstract Link createLink(String caption,String url); public abstract Tray createTray(String caption); public abstract Page createPage(String author,String title); }
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 ListTray extends Tray { public ListTray(String caption) { super(caption); } @Override public String makeHTML() { StringBuilder builder = new StringBuilder(); builder.append("\n"); Iterator iterator = trayList.iterator(); while(iterator.hasNext()){ Item item = (Item) iterator.next(); builder.append(item.makeHTML()); } return builder.toString(); } }
public class ListPage extends Page { public ListPage(String author, String title) { super(author, title); } @Override public String makeHTML() { StringBuilder builder = new StringBuilder(); builder.append(title); builder.append(author); Iterator iterator = content.iterator(); while(iterator.hasNext()) { Item item = (Item) iterator.next(); builder.append(item.makeHTML()); } return builder.toString(); } }
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 author, String title) { return new ListPage(author,title); } }
public class Main { public static void main(String[] args) { Factory factory = ListFactory.getFactory("listfactory.ListFactory"); Link link = factory.createLink("111","222"); Tray tray = factory.createTray("33"); Page page = factory.createPage("作者","标题"); page.add(link); page.add(tray); page.out(); } }
重点:
Factory抽象类,通过className获得具体的类实例,可以灵活的获得继承Factory的实现类。
同时Factory抽象类提供了创建Link、Tray、Page的抽象方法。
ListFactory为实现了Factory的具体工厂,在ListFactory中定义了具体的使用哪些零件。
Page抽象类定义了out输出方法,在out输出方法中调用了抽象方法makeHTML方法,后续实现了Page的类可以根据需要自己定义个性化的makeHTML方法。
收藏文章数量从多到少与“把书读薄”是一个道理