图解设计模式
2018-01-21 本文已影响43人
V_coa
Iterator 模式
如果使用具体的类来解决问题,很容易导致类之间的强耦合,这些类也难以作为组件被再次利用,为了弱化类之间的耦合,进而使得类更加容易作为组件被再次利用,需要引入抽象类和接口
image.pngpublic 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.pngpublic 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
方法
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 模式中,父类决定实例的生成方式,并不决定生成的具体的类,具体的类
全部交给子类负责
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 模式
- 对象种类繁多,无法将它们整合到一个类中
- 难以根据类生成实例
- 想解耦框架与生成的实例
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.pngpublic 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();
}
}