图解设计模式 -- 生成实例(二)

代码Github连接 :https://github.com/tangbi123/Tab-Design-Pattern

Builder模式

Builder模式:用于组装具有复杂结构的实例

1、示例

图解设计模式 -- 生成实例(二)
图解设计模式 -- 生成实例(二)

代码清单

1)Builder类

public abstract class Builder {
    public abstract void makeTitle(String title);
    public abstract void makeString(String str);
    public abstract void makeItems(String[] items);
    public abstract void close();
}

2)Director类

public class Director {
    private Builder builder;

    public Director(Builder builder) {
        this.builder = builder;
    }
    /** used to edit content */
    public void construct(){
        builder.makeTitle("Greeting");
        builder.makeString("从早上至下午");
        builder.makeItems(new String[]{
                "早上好",
                "下午好"
        });
        builder.makeString("晚上");
        builder.makeItems(new String[] {
                "晚上好",
                "晚安。",
                "再见。"
        });
        builder.close();
    }
}

3)TextBuilder类

public class TextBuilder extends Builder{
    private StringBuffer buffer = new StringBuffer();

    @Override
    public void makeTitle(String title) {
        buffer.append("==============\n");
        buffer.append("[" + title + "]\n");
        buffer.append("\n");
    }

    @Override
    public void makeString(String str) {
        buffer.append("s " +str + "\n");
        buffer.append("\n");
    }

    @Override
    public void makeItems(String[] items) {
        for(String item : items){
            buffer.append("   ~" + item + "\n");
        }
        buffer.append("\n");
    }

    @Override
    public void close() {
        buffer.append("==============\n");
    }

    public String getResult(){
        return buffer.toString();
    }
}

4)HTMLBuilder

public class HTMLBuilder extends Builder{
    private String filename;
    private PrintWriter writer;

    @Override
    public void makeTitle(String title) {
        filename = title + ".html";
        try{
            writer = new PrintWriter(new FileWriter(filename));
        } catch (IOException e) {
            e.printStackTrace();
        }
        writer.println("<html><head><title>" + title + "</title></head><body>");
        writer.println("<h1>" + title + "</h1>");
    }

    @Override
    public void makeString(String str) {
        writer.println("<p>" + str + "</p>");
    }

    @Override
    public void makeItems(String[] items) {
        writer.println("<ul>");
        for(String item : items){
            writer.println("<li>" + item + "</li>");
        }
        writer.println("</ul>");
    }

    @Override
    public void close() {
        writer.println("</body></html>");
        writer.close();
    }

    public String gerResult(){
        return filename;
    }
}

2、角色

图解设计模式 -- 生成实例(二)
图解设计模式 -- 生成实例(二)
1)Builder(创建者)=》 Builder类
负责定义于生成实例的接口(API)。Builder角色中准备了用于生成实例的方法。
2)ConcreteBuilder(具体的建造者)=》TextBuilder、HTMLBuilder
负责实现Builder角色的接口的类。(在生成实例时被调用),
3)Director(监工)=》Dirctor类
负责使用Builder角色的接口(API)来生成实例。不依赖于ConcreteBuilder角色(不论ConcreteBuilder如何定义,Director角色都能正常工作),它只调用在Builder角色中被定义的方法。
4)Client(使用者)
使用了Builder模式。

3、思路要点

1)谁知道什么
1、main不知道builder类,只是调用了Director的construct方法,Director类就会开始工作。
2、Director直到Builder类,但不知道真正 使用了哪个类(TextBuilder、HTMLBuilder)。

可替换性: 正因为不知道才能替换,组件才具有高价值。

2)设计时能够决定和不能决定的事情
Builder类中定义的方法非常重要。

3)代码的阅读方法和修改方法
Director 《-》Builder -》 TextBuilder、HTMLBuilder。

Abstract Factory模式

抽象工厂的工作是将“抽象零件” 组装成为“抽象产品”
我们并不关心零件的具体实现,而是只关心接口(API)。我们呢仅使用该接口(API)将零件组装成为产品。

1、示例

图解设计模式 -- 生成实例(二)
图解设计模式 -- 生成实例(二)

代码清单

1)factory.Item 类

package Abstract_Factory.factory;
public abstract class Item {
    protected String caption;

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

2)factory.Link 类

package Abstract_Factory.factory;

public abstract class Link extends Item{
    protected String url;
    public Link(String caption, String url) {
        super(caption);
        this.url = url;
    }
}

3)factory.Tray

package Abstract_Factory.factory;

import java.util.ArrayList;

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)factory.Factory

package Abstract_Factory.factory;

public abstract class Factory {
    public static Factory getFactory(String classname){
        Factory factory = null;
        try{
            factory = (Factory)Class.forName(classname).newInstance();
        } catch (ClassNotFoundException e) {
            System.out.println("没有找到" + classname + "类。");
        } 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);
}

5)listfactory.ListFactory

package Abstract_Factory.listfactory;

import Abstract_Factory.factory.Factory;
import Abstract_Factory.factory.Link;
import Abstract_Factory.factory.Page;
import Abstract_Factory.factory.Tray;

public class ListFactory extends Factory {
    @Override
    public Link createLink(String caption, String url) {
        return new ListLink(caption,url);
        //return null;
    }

    @Override
    public Tray createTray(String caption) {
        return new ListTray(caption);
        //return null;
    }

    @Override
    public Page createPage(String title, String author) {
        return new ListPage(title, author);
        //return null;
    }
}

6)listfactory.ListLink

package Abstract_Factory.listfactory;

import Abstract_Factory.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";
    }
}

7)listfactory.ListTray

package Abstract_Factory.listfactory;

import Abstract_Factory.factory.Item;
import Abstract_Factory.factory.Tray;

import java.util.Iterator;

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();
    }
}

8)listfactory.ListPage

package Abstract_Factory.listfactory;

import Abstract_Factory.factory.Item;
import Abstract_Factory.factory.Page;

import java.util.Iterator;

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();
    }
}

9)main

package Abstract_Factory;

import Abstract_Factory.factory.Factory;
import Abstract_Factory.factory.Link;
import Abstract_Factory.factory.Page;
import Abstract_Factory.factory.Tray;

public class AbstractFactoryMain {
    public static void main(String[] args) {
        if(args.length != 1){
            System.out.println("Usage: java Main class.name.of.ConcreteFactory");
            System.out.println("Example 1: java Main Abstract_Factory.listfactory.ListFactory");
            System.out.println("Example 2: java Main tablefactory.TableFactory");
            System.exit(0);
        }

        Factory factory = Factory.getFactory(args[0]);
        System.out.println(args[0]);
        Link people = factory.createLink("人民日报", "http://www.people.com.cn/");
        Link gmw = factory.createLink("光明日报","http://www.gmw.cn/");

        Link us_yahoo = factory.createLink("Yahoo", "http://www.yahoo.com");

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

        Page page = factory.createPage("linkPage", "杨文轩");
        page.add(traynews);
        //page.add(traynews)
        page.output();
    }
}

2、角色

图解设计模式 -- 生成实例(二)
1)AbstractProduct(抽象产品) =》 Link、Tray、Page
负责定义AbstractFactory角色所生成的抽象零件和产品的接口(API)。
2)AbstractFactory(抽象工厂) =》Factory
负责定义用于生成抽象产品的接口(API)。
3)Client(委托者) =>main
调用AbstractFactory角色和AbstractProduct角色接口来进行工作,对具体的零件、产品和工厂一无所知。
4)ConcreteProduct(具体产品) => Listfactory
负责实现AbstractProduct角色的接口(API)
5)ConcreteFactory(具体工厂) =》listfactory
负责实现AbstractFactory角色接口(API)

3、思路要点

易于增加具体的工厂

难以增加新的零件

上一篇:吉特仓库管理系统-- 后台管理开源啦,源码大放送


下一篇:接口,抽象类