设计模式学习笔记以及java代码实现



创建模式:
1.工厂模式
简单工厂模式(Simple Factory)

提供工厂,把实际的工作转移到具体的子类。

//: creational.factory.TestSimpleFactory.java package creational.factory; public class TestSimpleFactory { public static void main(String[] args) { Animal animal = AnimalFacotry.getAnimal("Dog"); animal.cry(); } } abstract class Animal { public void cry() { } } class Dog extends Animal { @Override public void cry() { System.out.println("woof woof ... "); } } class Cat extends Animal { @Override public void cry() { System.out.println("meow meow ... "); } } class Sheep extends Animal { @Override public void cry() { System.out.println("baa baa ... "); } } class AnimalFacotry { public static Animal getAnimal(String name) { if (name.equals("Dog")) { return new Dog(); } else if (name.equals("Cat")) { return new Cat(); } return new Sheep(); } }


工厂方法模式(Factory Method)
多态性工厂模式,创建一个产品的工厂接口,把实际的工作转移到具体的子类。

//: creational.factory.TestFactoryMethod.java package creational.factory; public class TestFactoryMethod { public static void main(String[] args) { GraphFactory graphFactory = new CircleFactory(); Circle graph = (Circle) graphFactory.getGraph(); graph.draw(); } } abstract class Graph { public void draw() { } } class Circle extends Graph { @Override public void draw() { System.out.println("Circle"); } } class Triangle extends Graph { @Override public void draw() { System.out.println("Triangle"); } } class Square extends Graph { @Override public void draw() { System.out.println("Square"); } } abstract class GraphFactory { public abstract Graph getGraph(); } class CircleFactory extends GraphFactory { public Graph getGraph() { return new Circle(); } } class TriangleFactory extends GraphFactory { public Graph getGraph() { return new Triangle(); } } class SquareFactory extends GraphFactory { public Graph getGraph() { return new Square(); } }
抽象工厂模式(Abstract Factory)
针对多个产品等级的情况,而工厂方法模式针对单一产品等级的情况。

//: creational.factory.TestAbstractFactory.java package creational.factory; import java.awt.*; import javax.swing.*; public class TestAbstractFactory { public static void main(String[] args) { // new a Factory GUIFactory fact = new AWTFactory(); //GUIFactory fact = new SwingFacotry(); Frame f = fact.getFrame(); Component c1 = fact.getButton(); Component c2 = fact.getTextField(); f.setSize(500, 300); f.setLayout(new FlowLayout()); f.add(c1); f.add(c2); f.setVisible(true); } } abstract class GUIFactory { public abstract Component getButton(); public abstract Component getTextField(); public abstract Frame getFrame(); } class AWTFactory extends GUIFactory { @Override public Component getButton() { return new Button("AWT Button"); } @Override public Frame getFrame() { return new Frame("AWT Frame"); } @Override public Component getTextField() { return new TextField("AWT TextField"); } } class SwingFacotry extends GUIFactory { @Override public Component getButton() { return new JButton("Swing Button"); } @Override public Frame getFrame() { return new JFrame("Swing Frame"); } @Override public Component getTextField() { return new JTextField("Swing TextField"); } }
2.单例模式(Singleton)
系统中只有一个实例,因此构造方法应该为私有
饿汉式:类加载时直接创建静态实例
懒汉式:第一次需要时才创建一个实例,那么newInstance方法要加同步
饿汉式比懒汉式要好,尽管资源利用率要差。但是不用同步。

//: creational.singleton.TestSingleton.java package creational.singleton; public class TestSingleton { public static void main(String[] args) { EagerHusband ha1 = EagerHusband.newInstance(); EagerHusband ha2 = EagerHusband.newInstance(); LazyHusband hb1 = LazyHusband.newInstance(); LazyHusband hb2 = LazyHusband.newInstance(); } } class EagerHusband { // Eager public static EagerHusband instance = new EagerHusband(); public static EagerHusband newInstance() { System.out.println("EagerHusband newInstance()"); return instance; } private EagerHusband() { System.out.println("EagerHusband()"); } } // think multi thread, could be create multi Object, so need synchronized class LazyHusband { // Lazy private static LazyHusband instance = null; public static synchronized LazyHusband newInstance() { // need ... System.out.println("LazyHusband newInstance()"); if (instance == null) { instance = new LazyHusband(); } return instance; } private LazyHusband() { System.out.println("LazyHusband()"); } }
3.多例模式(Multiton)

4.建造模式(Builder)
将一个对象的内部表象和建造过程分割,一个建造过程可以造出不同表象的对象。可简化为模版方法模式.

//: creational.builder.TestBuilder.java package creational.builder; public class TestBuilder { public static void main(String[] args) { BuilderImpl1 builder = new BuilderImpl1(); Director director = new Director(builder); Product product = director.createProduct(); System.out.println(product); } } interface Builder { void buildPart1(); void buildPart2(); void buildPart3(); Product getProduct(); } class BuilderImpl1 implements Builder { private int part1; private double part2; private String part3; // public void buildPart1() { System.out.println("create part1"); this.part1 = 1; } public void buildPart2() { System.out.println("create part2"); this.part2 = 2.0; } public void buildPart3() { System.out.println("create part3"); this.part3 = "three"; } public Product getProduct() { return new Product(part1, part2, part3); } } class Product { private int part1; private double part2; private String part3; public Product(int part1, double part2, String part3) { this.part1 = part1; this.part2 = part2; this.part3 = part3; } public Product() { this.part1 = 0; this.part2 = 0.0; this.part3 = ""; } @Override public String toString() { StringBuilder sb = new StringBuilder(); sb.append("Product{part1="); sb.append(part1); sb.append(", part2="); sb.append(part2); sb.append(", part3="); sb.append(part3); sb.append("}"); return sb.toString(); } } class Director { Builder b; public Director(Builder b) { this.b = b; } public Product createProduct() { b.buildPart1(); b.buildPart2(); b.buildPart3(); return b.getProduct(); } }
5.原型模式(ProtoType)
通过一个原型对象来创建一个新对象(克隆)。Java中要给出Clonable接口的实现,具体类要实现这个接口,并给出clone()方法的实现细节,这就是简单原型模式的应用。
浅拷贝:只拷贝简单属性的值和对象属性的地址
深拷贝:拷贝本对象引用的对象,有可能会出现循环引用的情况。可以用串行化解决深拷贝。写到流里再读出来,这时会是一个对象的深拷贝结果。

//: creational.prototype.TestCloneable.java package creational.prototype; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.Serializable; public class TestCloneable { public static void main(String[] args) throws CloneNotSupportedException { User u1 = new User("123456", new Father()); User u2 = (User)u1.clone(); // compare address System.out.println(u1 == u2); System.out.println(u1.f == u2.f); // System.out.println("u1.password=" + u1.password); System.out.println("u2.password=" + u2.password); System.out.println("After modify "); u2.password = "654321"; System.out.println("u1.password=" + u1.password); System.out.println("u2.password=" + u2.password); } } class Father implements Cloneable, Serializable { } class User implements Cloneable, Serializable { String password; Father f; public User(String password,Father f) { this.password = password; this.f = f; } public Object clone() throws CloneNotSupportedException { // return super.clone(); // shawdon copy ObjectOutputStream out = null; ObjectInputStream in = null; Object o = null; try { ByteArrayOutputStream bo = new ByteArrayOutputStream(); out = new ObjectOutputStream(bo); out.writeObject(this); out.flush(); byte[] bs = bo.toByteArray(); ByteArrayInputStream bi = new ByteArrayInputStream(bs); in = new ObjectInputStream(bi); o = in.readObject(); return o; } catch (IOException e) { e.printStackTrace(); return null; } catch (ClassNotFoundException e) { e.printStackTrace(); return null; } finally { try { if (out != null) { out.close(); } if (in != null) { in.close(); } } catch (IOException e) { e.printStackTrace(); } } } }



结构模式:如何把简单的类根据某种结构组装为大的系统
6.适配器模式(Adapter)
用一个适配器类把一个接口转成另一个接口。

//: structural.adapter.TestAdapter.java package structural.adapter; public class TestAdapter { public static void main(String[] args) { PC pc = new PC(); USB usbmouse = new USBMouse(); //pc.useMouse(mouse); // error PS2 adapter = new USBToPS2Adapter(usbmouse); pc.useMouse(adapter); } } interface PS2 { void usePs2(); } interface USB { void useUsb(); } class USBMouse implements USB { public void useUsb() { System.out.println("Use USB working"); } } class USBToPS2Adapter implements PS2 { private USB usb; public USBToPS2Adapter(USB usb) { this.usb = usb; } public void usePs2() { System.out.println("ps2 mouse adapter to usb "); usb.useUsb(); } } class PC { public void useMouse(PS2 ps2Mouse) { ps2Mouse.usePs2(); } }

 

//: structural.adapter.TestAdapter2.java package structural.adapter; import java.util.Enumeration; import java.util.Iterator; import java.util.Properties; public class TestAdapter2 { public static void main(String[] args) { Properties ps = new Properties(); ps.setProperty("P1","aaa"); ps.setProperty("P2","bbb"); ps.setProperty("P3","ccc"); Enumeration<?> e = ps.propertyNames(); Adapter a = new Adapter(e); print(a); } public static void print(Iterator<Object> it) { while (it.hasNext()) { System.out.println(it.next()); } } } class Adapter implements Iterator<Object> { Enumeration<?> e; public Adapter(Enumeration<?> e) { this.e = e; } public boolean hasNext() { return this.e.hasMoreElements(); } public Object next() { return this.e.nextElement(); } public void remove() { } }

7.组合模式(Composite)
把整体和局部的关系用树状结构描述出来,使得客户端把整体对象和局部对象同等看待。

//: structural/composite/TestComposite.java package structural.composite; import java.util.*; public class TestComposite { public static void main(String[] args) { Node n1 = new LeafNode(3); Node n2 = new LeafNode(4); Node n3 = new LeafNode(6); Node n4 = new LeafNode(5); Node n5 = new LeafNode(2); Node n6 = new LeafNode(9); Node n7 = new LeafNode(12); Node n8 = new LeafNode(7); Node n9 = new LeafNode(8); Node c3 = new CompositeNode(n8, n9); Node c4 = new CompositeNode(n5, c3); Node c1 = new CompositeNode(n1, n2, n3); Node c2 = new CompositeNode(n4, c4); Node c5 = new CompositeNode(n6, n7); Node root = new CompositeNode(c1, c2, c5); System.out.println(root.getValue()); } } abstract class Node { public abstract int getValue(); } class LeafNode extends Node { private int value; public LeafNode(int value) { this.value = value; } public int getValue() { return value; } } class CompositeNode extends Node { private List<Node> child = new ArrayList<Node>(); public CompositeNode(Node... nodes) { for (Node n : nodes) { child.add(n); } } public int getValue() { int result = 0; for (Node n : child) { result += n.getValue(); } return result; } }
8.装饰模式(Decorator)
以对客户透明的方式来扩展对象的功能。
用户根据功能需求随意选取组成对象的成分,通过方法的链式调用来实现。
可以给对象动态的增加功能,比继承灵活性更大。

//: structural/decorator/TestDecorator.java package structural.decorator; public class TestDecorator { public static void main(String[] args) { Teacher t1 = new SimpleTeacher(); Teacher t2 = new JavaTeacher(t1); Teacher t3 = new CppTeacher2(t2); t3.teach(); } } abstract class Teacher { public abstract void teach(); } class SimpleTeacher extends Teacher { public void teach() { System.out.println("Good Good Study, Day Day Up"); } } class JavaTeacher extends Teacher { Teacher teacher; public JavaTeacher(Teacher t) { this.teacher = t; } public void teach() { teacher.teach(); System.out.println("Teach Java"); } } class CppTeacher2 extends Teacher { Teacher teacher; public CppTeacher2(Teacher t) { this.teacher = t; } public void teach() { teacher.teach(); System.out.println("Teach Cpp"); } } class OracleTeacher extends Teacher { Teacher teacher; public OracleTeacher(Teacher teacher) { this.teacher = teacher; } public void teach() { System.out.println("teach Oracle."); teacher.teach(); } }
9.代理模式(Proxy)
用一个代理对象来作为另一个对象的代理,对客户来说是透明的。
存在一个抽象主题类,具体主题类和代理主题类都继承(实现)抽象主题,代理主题类中的方法会调用具体主题类中相对应的方法。

//: structural/proxy/TestProxy.java package structural.proxy; public class TestProxy { public static void main(String[] args) { MoneyMakerImpl mmi = new MoneyMakerImpl(); MoneyMaker m2 = new MoneyIssuer(mmi); m2.printMoney(); } } interface MoneyMaker { void printMoney(); } class MoneyMakerImpl implements MoneyMaker { @Override public void printMoney() { System.out.println("free print money"); } } class MoneyIssuer implements MoneyMaker { private MoneyMaker h; public MoneyIssuer(MoneyMaker h) { this.h = h; } @Override public void printMoney() { System.out.println("print money need salary "); h.printMoney(); } }

10.享元模式(Flyweight)
对象的状态分为内蕴状态和外蕴状态。内蕴状态不随环境变化而变化,因此可以作成系统共享.

 

11.门面模式(Facade)
访问子系统的时候,通过一个Façade对象访问。Facade类是单例的。
客户代码只需要和门面对象通信,不需要和具体子系统内部的对象通信,使得他们之间的耦合关系减弱。

 

12.桥梁模式(Bridge)
将抽象和实现脱耦,使得二者可以单独变化。使得一个继承关系不承担两个变化因素,使用组合来代替继承的一种体现.
//: structural/bridge/TestBridge.java package structural.bridge; public class TestBridge { public static void main(String[] args) { BankAccount account = new CreditAccount(); BankUser user = new DollarUser(account); user.getMoney(); } } interface BankAccount { void deposit(); void withdraw(); } class SavingAccount implements BankAccount { @Override public void deposit() { System.out.println("Save"); } @Override public void withdraw() { System.out.println("withdraw can't be ceiling"); } } class CreditAccount implements BankAccount { @Override public void deposit() { System.out.println("Save"); } @Override public void withdraw() { System.out.println("withdraw can be ceiling"); } } abstract class BankUser { protected BankAccount account; public BankUser(BankAccount account) { super(); this.account = account; } public abstract void saveMoney(); public abstract void getMoney(); } class RenminbiUser extends BankUser { public RenminbiUser(BankAccount account) { super(account); } @Override public void getMoney() { System.out.print("RMB "); super.account.withdraw(); } @Override public void saveMoney() { System.out.println("RMB "); super.account.deposit(); } } class DollarUser extends BankUser { public DollarUser(BankAccount account) { super(account); } @Override public void getMoney() { System.out.println("Dollar "); super.account.withdraw(); } @Override public void saveMoney() { System.out.println("Dollar "); super.account.deposit(); } }

行为模式:描述如何在对象之间划分责任
13.策略模式(Strategy)
如同LayoutManager和具体的布局管理器的关系,在抽象策略类中定义方法,在具体策略子类中实现。客户代码根据不同的需要选择相应的具体类,例如电子商务中多种价格算法。
一种策略一旦选中,整个系统运行期是不变化的

//: behavioral/stragegy/TestStrategy.java package behavioral.stragegy; public class TestStrategy { public static void main(String[] args) { Strategy strategy = new June1Strategy(); Book book = new Book(100); book.setStrategy(strategy); System.out.println(book.getPrice()); } } class Book { Strategy strategy; private double price; public Book(double price) { this.price = price; this.strategy = new GeneralStrategy(); } public double getPrice() { return price * strategy.getDiscount(); } public void setStrategy(Strategy strategy) { this.strategy = strategy; } } interface Strategy { double getDiscount(); } class GeneralStrategy implements Strategy { public double getDiscount() { return 1.0; } } class May1Strategy implements Strategy { public double getDiscount() { return 0.8; } } class June1Strategy implements Strategy { public double getDiscount() { return 0.7; } }
14.模板方法(Template Method)
准备一个抽象类,把部分确定的逻辑定义在某些方法中,用其他抽象方法实现剩余的逻辑。不同子类对这些逻辑有不同的实现。
用法:定义多个抽象操作,定义并实现一个模板方法,将步骤放在这个具体方法里,推迟到子类实现。子类可以改变父类的可变部分,但不能改变模板方法所代表的顶级逻辑。

// behavioral/template/TestTemplateMethod.java package behavioral.template; public class TestTemplateMethod { public static void main(String[] args) { Testcase testcase = new ATestcase(); testcase.test(); } } abstract class Testcase { public abstract void beforeTest(); public abstract void doTest(); public abstract void afterTest(); public final void test() { beforeTest(); doTest(); afterTest(); } } class ATestcase extends Testcase { @Override public void beforeTest() { System.out.println("A: <before>"); } @Override public void doTest() { System.out.println("A: <test>"); } @Override public void afterTest() { System.out.println("A: <after>"); } } class BTestcase extends Testcase { @Override public void beforeTest() { System.out.println("B: <before>"); } @Override public void doTest() { System.out.println("B: <test>"); } @Override public void afterTest() { System.out.println("B: <after>"); } }
15.观察者模式(Observer)
多个观察者同时监听某一主题对象,这个主题对象状态发生变化时,会通知所有观察者对象,使他们自动更新自己。在低耦合的对象间完成协调。
Java中的事件模型就是一个应用。

//: behavioral/observer/TestObserver.java package behavioral.observer; import java.util.*; public class TestObserver { public static void main(String[] args) { Subject s=new Subject(); Observer o1=new Observer1(); Observer o2=new Observer2(); s.addObserver(o1); s.addObserver(o2); s.fire(); } } class Subject{ Collection<Observer> os=new ArrayList<Observer>(); public void addObserver(Observer o){ os.add(o); } public void fire(){ for(Observer o:os){ o.method(); } } } interface Observer{ void method(); } class Observer1 implements Observer{ public void method(){ System.out.println("Observer1 "); } } class Observer2 implements Observer{ public void method(){ System.out.println("Observer2 "); } }
16.迭代器模式(Iterator)
类似于集合中的Iterator,使用迭代器来统一不同集合对象的遍历方式,隐藏内部细节,用一个抽象迭代器,每个具体的集合类来实现特有的迭代器。

//: behavioral/iterator/TestIterator.java package behavioral.iterator; public class TestIterator { public static void main(String[] args) { Stack s = new Stack(); s.push("Stack a"); s.push("Stack b"); s.push("Stack c"); s.push("Stack d"); s.push("Stack e"); print(s.iterator()); LinkedList l = new LinkedList(); l.add("List a"); l.add("List b"); l.add("List c"); l.add("List d"); l.add("List e"); print(l.iterator()); } public static void print(Iter iter) { while (iter.hasNext()) { System.out.println(iter.next()); } } } interface Iter { boolean hasNext(); Object next(); } class Stack { Object[] os = new Object[10]; int index = 0; private void expand() { Object[] os2 = new Object[os.length * 2]; System.arraycopy(os,0,os2,0,os.length); os = os2; } public void push(Object o) { if (index == os.length) expand(); os[index] = o; index++; } public Object pop() { index--; Object o = os[index]; os[index] = null; return o; } private class StackIter implements Iter { int cursor = index; public boolean hasNext() { return cursor > 0; } public Object next() { return os[--cursor]; } } public Iter iterator() { return new StackIter(); } } class LinkedList { static class Node { Object o; Node next; public Node(Object o, Node next) { this.o = o; this.next = next; } } Node head;// = new Node(null, null) Node cur; public LinkedList() { } public void add(Object o) { Node n = new Node(o, null); if (head == null) { head = n; cur = n; } cur.next = n; cur = n; } public Object remove() { Node n = head; head = head.next; return n.o; } private class LinkedListIter implements Iter { Node currentNode = head; public boolean hasNext() { return this.currentNode != null; } public Object next() { Node n = currentNode; currentNode = currentNode.next; return n.o; } } public Iter iterator() { return new LinkedListIter(); } }
17.责任链(Chain of Responsibility)
多个处理器对象连成一串,请求在这条链上传递,由该处理这个请求的处理器来处理。发出请求的客户端并不知道哪个对象处理请求。

//: behavioral/chain/TestChain.java package behavioral.chain; public class TestChain { public static void main(String[] args) { String pass1 = "123456"; String pass2 = "1234567"; String personId = "362502198508115555"; String email = "[email protected]"; register(pass1,pass2,personId,email); } public static void register(String pass1,String pass2,String personId,String email) { Filter f1 = new PasswordFilter1(); Filter f2 = new PasswordFilter2(); Filter f3 = new PersonFilter(); Filter f4 = new EmailFilter(); f1.setNext(f2); f2.setNext(f3); f3.setNext(f4); System.out.println(f1.doFilter(pass1,pass2,personId,email)); Filter tf = null; Filter f = new PasswordFilter1(); tf = f; f = new PasswordFilter2(); tf.setNext(f); } } abstract class Filter { Filter next; public Filter getNext() { return next; } public void setNext(Filter next) { this.next = next; } public String doFilter(String pass1,String pass2,String personId,String email) { System.out.println("this:" + this); System.out.println("next:" + next); if (next == null) return "Success! "; return next.doFilter(pass1,pass2,personId,email); } } class PasswordFilter1 extends Filter { @Override public String doFilter(String pass1, String pass2, String personId, String email) { if (!(pass1.equals(pass2))) return "two password not same! "; return super.doFilter(pass1, pass2, personId, email); } } class PasswordFilter2 extends Filter { @Override public String doFilter(String pass1, String pass2, String personId, String email) { if (pass1.length() != 6 || pass2.length() != 6) return "length not 6! "; return super.doFilter(pass1, pass2, personId, email); } } class PersonFilter extends Filter { @Override public String doFilter(String pass1, String pass2, String personId, String email) { if (personId.length() != 18) return "PersonID not true! "; return super.doFilter(pass1, pass2, personId, email); } } class EmailFilter extends Filter { @Override public String doFilter(String pass1, String pass2, String personId, String email) { int i1 = email.indexOf("@"); int i2 = email.indexOf("."); if (i1 == -1 || i2 == -1 || i2-i1 <= 1 || i1 == 0 || i2 == email.length()) return "email not true! "; return super.doFilter(pass1, pass2, personId, email); } }
18.状态模式(State)
在对象内部状态改变时改变其行为。把所研究的对象的行为封装在不同的状态对象中。

//: behavioral/state/TestState.java package behavioral.state; public class TestState { public static void main(String[] args) { BBSUser u = new BBSUser(); u.publish(); u.setState("Normal"); u.publish(); } } class BBSUser { private String state = "Guest"; public void setState(String state) { this.state = state; } public void publish() { if (state.equals("Guest")) { System.out.println("You are Guest, Please Login"); } if (state.equals("Normal")) { System.out.println("You are Normal, Send OK"); } if (state.equals("Blocked")) { System.out.println("You are Blocked, Send Failure"); } } }
19.命令模式(Command)
以物件来代表实际行动,命令物件可以把行动及其参数封装起来。

//: behavioral/chain/TestCommand.java package behavioral.command; import java.util.HashMap; import java.util.Map; public class TestCommand { public static void main(String[] args) { CommandManager.executeCommand("go"); CommandManager.executeCommand("startup"); } } abstract class Command { public abstract void execute(); } class StartupCommand extends Command { @Override public void execute() { System.out.println("startup system"); } } class ShutdownCommand extends Command { @Override public void execute() { System.out.println("shutdown system"); } } class CommandManager { private static Map<String, Command> map = new HashMap<String, Command>(); static { map.put("startup", new StartupCommand()); map.put("shutdown", new ShutdownCommand()); } public static void executeCommand(String cmd) { Command command = map.get(cmd); if (null != command) { command.execute(); } else { System.out.println("no have this command, warn!!!"); } } }
20.备忘录模式(Memento)
备忘录对象用来存储另一个对象的快照对象,保存其内部状态,使得可以随时恢复。
备忘录角色:保存发起人对象的内部状态,保护内容不被除发起人对象之外的对象获取。窄接口:负责人对象和其他对象看到的接口,只允许把备忘录对象传给其他对象。宽接口:发起人能看到的接口,允许读取内部状态。
发起人角色:创建并使用备忘录对象来保存其状态
负责人角色:负责保存备忘录对象。
白箱实现:备忘录类对其他类也可见,这样发起人的状态可能会存在安全问题。
黑箱实现:把备忘录类作成发起人的内部类,对外提供一个标识接口。

你可能感兴趣的:(java,设计模式,String,object,filter,Class)