图解设计模式

2018-01-21  本文已影响43人  V_coa

Iterator 模式

如果使用具体的类来解决问题,很容易导致类之间的强耦合,这些类也难以作为组件被再次利用,为了弱化类之间的耦合,进而使得类更加容易作为组件被再次利用,需要引入抽象类和接口

image.png
public interface Aggregate {
    public abstract Iterator iterator();
}

public interface Iterator {
    public abstract boolean hasNext();
    public abstract Object next();
}

public class BookShelf implements Aggregate {

    private Book[] books;
    private int last;

    BookShelf(int maxSize) {
        books = new Book[maxSize];
        last = 0;
    }

    Book getBookAt(int index) {
        return books[index];
    }

    void appendBook(Book book) {
        books[last++] = book;
    }

    int getLength() {
        return last;
    }

    @Override
    public Iterator iterator() {
        return new BookShelfIterator(this);
    }
}

public class Book {
    private String name;
    Book(String name) {
        this.name = name;
    }

    String getName() {
        return name;
    }
}

public class BookShelfIterator implements Iterator {
    private BookShelf bookShelf;
    private int index;
    BookShelfIterator(BookShelf bookShelf) {
        this.bookShelf = bookShelf;
        index = 0;
    }

    @Override
    public boolean hasNext() {
        return index < bookShelf.getLength();
    }

    @Override
    public Object next() {
        return bookShelf.getBookAt(index++);
    }
}

public class Main {
    public static void main(String[] args) {
        BookShelf bookShelf = new BookShelf(4);
        bookShelf.appendBook(new Book("Around the World in 80 Days"));
        bookShelf.appendBook(new Book("Bible"));
        bookShelf.appendBook(new Book("Cinderella"));
        bookShelf.appendBook(new Book("Daddy-Long-Legs"));
        Iterator it = bookShelf.iterator();
        while (it.hasNext()) {
            Book book = (Book)it.next();
            System.out.println(book.getName());
        }
    }
}

/* output
Around the World in 80 Days
Bible
Cinderella
Daddy-Long-Legs
*/

Adapter 模式

类适配器

image.png

使用 Print 接口来编程,对 Main 类来说,隐藏了 Banner 类的方式,Main 不知道 PrintBanner 是如何实现的,可以不对 Main 修改的情况下,修改 PrintBanner 的实现

public class Banner {
    private String name;

    Banner(String name) {
        this.name = name;
    }

    void showParen() {
        System.out.println("(" + name + ")");
    }

    void showAster() {
        System.out.println("*" + name + "*");
    }

}

public interface Print {
    public void printWeak();
    public void printStrong();
}

public class PrintBanner extends Banner implements Print {

    PrintBanner(String name) {
        super(name);
    }

    @Override
    public void printWeak() {
        showParen();
    }

    @Override
    public void printStrong() {
        showAster();
    }
}

对象适配器

image.png
public abstract class Print {
    public abstract void printWeak();
    public abstract void printStrong();
}

public class PrintBanner extends Print  {

    private Banner banner;
    PrintBanner(String name) {
        banner = new Banner(name);
    }

    @Override
    public void printWeak() {
        banner.showParen();
    }

    @Override
    public void printStrong() {
        banner.showAster();
    }
}

Template Method 模式

在父类中现实的处理流程,在子类中实现, display 方法调用了由子类实现的 open,print, close 方法

image.png image.png
public abstract class AbstractDisplay {
    public abstract void open();
    public abstract void print();
    public abstract void close();
    public final void display() {
        open();
        for (int i = 0; i < 5; i++) {
            print();
        }
        close();
    }
}

public class CharDisplay extends AbstractDisplay {
    private char ch;
    public CharDisplay(char ch) {
        this.ch = ch;
    }

    @Override
    public void open() {
        System.out.print("<<<");
    }

    @Override
    public void print() {
        System.out.print(ch);
    }

    @Override
    public void close() {
        System.out.println(">>>");
    }
}

Factory Method

Factory 模式中,父类决定实例的生成方式,并不决定生成的具体的类,具体的类
全部交给子类负责

image.png
public abstract class Factory {
    public final Product create(String string) {
        Product p = createProduct(string);
        registerProduct(p);
        return p;
    }

    protected abstract  Product createProduct(String string);
    protected abstract void registerProduct(Product p);
}

public class IDCardFactory extends Factory {
    private List owners = new ArrayList();
    @Override
    protected Product createProduct(String string) {
        return new IDCard(string);
    }

    @Override
    protected void registerProduct(Product p) {
        owners.add(p);
    }
}

public class IDCard extends Product {
    private String id;

    IDCard(String id) {
        this.id = id;
    }

    @Override
    public void use() {
        System.out.println(id);
    }
}

public abstract class Product {
    public abstract void use();
}

Prototype 模式

image.png
public interface Product extends Cloneable {
    public abstract void use(String s);
    public Product createClone();
}

public class Manager {
    private HashMap showcase = new HashMap();
    public void register(String key, Object value) {
        showcase.put(key, value);
    }

    public Product create(String key) {
        Product p = (Product)showcase.get(key);
        return p.createClone();
    }
}

public class MessageBox implements Product {
    private char decochar;
    public MessageBox(char decochar) {
        this.decochar = decochar;
    }

    @Override
    public void use(String s) {
        int length = s.getBytes().length;
        for (int i = 0; i < length + 4; i++) {
            System.out.print(decochar);
        }

        System.out.println("");
        System.out.println(decochar + " " + s + " " + decochar);
        for (int i = 0; i < length + 4; i++) {
            System.out.print(decochar);
        }
        System.out.println("");
    }


    @Override
    public Product createClone() {
        Product p = null;
        try {
            p = (Product)clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return p;
    }
}

public class UnderlinePen implements Product {
    private char ulchar;
    public UnderlinePen(char ulchar) {
        this.ulchar = ulchar;
    }

    @Override
    public void use(String s) {
        int length = s.getBytes().length;
        System.out.println("\"" + s + "\"");
        System.out.print(" ");
        for (int i = 0; i < length; i ++) {
            System.out.print(ulchar);
        }
        System.out.println("");
    }

    public Product createClone() {
        Product p = null;
        try {
            p = (Product)clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return p;
    }
}

public class Main {
    public static void main(String[] args) {
        Manager mgr = new Manager();
        UnderlinePen upen = new UnderlinePen('~');
        MessageBox mbox = new MessageBox('*');
        MessageBox sbox = new MessageBox('/');
        mgr.register("strong message", upen);
        mgr.register("warning box", mbox);
        mgr.register("slash box", sbox);

        Product p1 = mgr.create("strong message");
        p1.use("Hello, world");

        Product p2 = mgr.create("warning box");
        p2.use("Hello, world");

        Product p3 = mgr.create("slash box");
        p3.use("Hello, world");
    }
}


/* output
"Hello, world"
 ~~~~~~~~~~~~
****************
* Hello, world *
****************
////////////////
/ Hello, world /

*/

Builder 模式

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

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

public class Director {
    private Builder builder;
    public Director(Builder builer) {
        this.builder = builer;
    }

    public void construct() {
        builder.makeTitle("Greeting");
        builder.makeString("从早上到下午");
        builder.makeItems(new String[] {
                "早上好",
                "下午好",
        });

        builder.makeString("晚上");
        builder.makeItems(new String[] {
                "晚上好",
                "晚安",
                "再见"
        });
        builder.close();
    }
}

public class Main {
    public static void main(String[] args) {
        TextBuilder textBuilder = new TextBuilder();
        Director director = new Director(textBuilder);
        director.construct();
        System.out.println(textBuilder.getResult());
    }
}

/*
========

*从早上到下午

   .早上好
   .下午好

*晚上

   .晚上好
   .晚安
   .再见

========
*/

Abstract Factory 模式

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

image.png

抽象的零件: Item 类

/*
* Item 有 caption 表示标题
* makeHTML 方法是抽象方法,让子类实现
* */
public abstract class Item {
    protected String caption;
    
    public Item(String caption) {
        this.caption = caption;
    }
    
    public abstract String makeHTML();
}

抽象的零件: Link 类

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

抽象的零件: Tray 类

/*
* Tray 类表示的是一个含有多个 Link 类和 Tray 类的容器。
* */
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);
    }
}

抽象的产品: Page 类


/*
* Page 类是抽象地表示 HTML 页面的类,抽象产品
* */
public abstract class Page {
    protected String title;
    protected String author;
    protected ArrayList content = new ArrayList();
    public Page(String title, String author) {
        this.title = title;
        this.author = author;
    }

    public void add(Item item) {
        content.add(item);
    }

    public void output() {
        try {
            String filename = title + ".html";
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public abstract String makeHTML();

}

抽象的工厂: Factory 类

public abstract class Factory {
    public static Factory getFactory(String classname) {
        Factory factory = null;
        try {
            factory = (Factory)Class.forName(classname).newInstance();
        } catch (ClassNotFoundException e) {

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

具体工厂类: ListFactory

/*
* 生成零件和产品
* */
public class ListFactory extends Factory {
    public Link createLink(String caption, String url) {
        return new ListLink(caption, url);
    }
    public Tray createTray(String caption) {
        return new ListTray(caption);
    }
    public Page createPage(String title, String author) {
        return new ListPage(title, author);
    }
}

具体的零件: ListLink 和 ListTray

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


具体产品类: ListPage

import java.util.Iterator;

public class ListPage extends Page {
    public ListPage(String title, String author) {
        super(title, author);
    }
    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();
    }
}

Main

通过抽象零件,抽象产品,抽象工厂,可以方便的通过这个模式产生各种产品,通过子类,的实现不同,来实现,不同产品,不同工厂的实现,能产生不同的产品。

public class Main {
    public static void main(String[] args) {
        Factory factory = Factory.getFactory("ListFactory");

        Link baidu = factory.createLink("百度", "http://www.baidu.com/");

        Link bing = factory.createLink("bing", "https://cn.bing.com/");

        Tray tray1 = factory.createTray("1");
        Tray tray2 = factory.createTray("2");

        tray1.add(baidu);
        tray2.add(bing);

        Page page = factory.createPage("LinkPage", "ptyuan");
        page.add(tray1);
        page.add(tray2);
        page.output();
    }
}

上一篇下一篇

猜你喜欢

热点阅读