个人理解设计模式
设计模式有很多...
?
一. 工厂模式
?
工厂方法
?
抽象类(或接口):
public abstract class Window {public abstract void func();}实现类:
public class WindowBig extends Window {public void func() {System.out.println("This is Big Window !");}}public class WindowSmall extends Window {public void func() {System.out.println("This is Small Window !");}}工厂类:
public class Factory {public Window CreateWindow(String type) {if (type.equals("Big")) {return new WindowBig();} else if (type.equals("Small")) {return new WindowSmall();} else {return new WindowBig();}}// The Main function only for our testpublic static void main(String[] args) {Factory myFactory = new Factory();Window myBigWindow = myFactory.CreateWindow("Big");myBigWindow.func();Window mySmallWindow = myFactory.CreateWindow("Small");mySmallWindow.func();}}?
抽象工厂:
沿用上面工厂方法的 抽象类以及实现类。
抽象工厂接口:
public interface IFactory {Window CreateWindow (Window window);}抽象工厂的实现类:
public class Factory implements IFactory { public Window CreateWindow (Window window) { return window; } // The Main function only for our test public static void main(String[] args) { IFactory myFactory = new Factory(); Window windowBig = new WindowBig(); Window myBigWindow = myFactory.CreateWindow(windowBig); myBigWindow.func(); Window windowSmall = new WindowSmall(); Window mySmallWindow = myFactory.CreateWindow(windowSmall); mySmallWindow.func(); }}抽象工厂总结:
public class Singleton {private Singleton() {}// 在自己内部定义自己一个实例,是不是很奇怪?// 注意这是private 只供内部调用private static Singleton instance = new Singleton();// 这里提供了一个供外部访问本class的静态方法,可以直接访问 public static Singleton getInstance() {return instance;}}形式二:
public class Singleton {private static Singleton instance = null;public static synchronized Singleton getInstance() {// 这个方法比上面有所改进,不用每次都进行生成对象,只是第一次// 使用时生成实例,提高了效率!if (instance == null)instance = new Singleton();return instance;}}上面第二中形式是lazy initialization,也就是说第一次调用时初始Singleton,以后就不用再生成了。
注意到lazy initialization形式中的synchronized,这个synchronized很重要,如果没有synchronized,那么使用getInstance()是有可能得到多个Singleton实例。关于lazy initialization的Singleton有很多涉及double-checked locking (DCL)的讨论,有兴趣者进一步研究。
?
五. Facade(外观)
为子系统中的一组接口提供一个一致的界面.
用自己的话来讲,就是对模块组件进行封装(提取重复的代码,工具类)。
?
六. 动态代理
接口:
public interface IHello {void sayHello(String name);void sayGoogBye(String name);}实现类:
public class Hello implements IHello {public void sayHello(String name) {System.out.println("Hello " + name);}public void sayGoogBye(String name) {System.out.println(name + " GoodBye!");}}写一个代理类.让这个类去实现java.lang.reflect.InvocationHandler接口
import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;import java.lang.reflect.Proxy;public class DynaProxyHello implements InvocationHandler {private Object delegate;public Object bind(Object delegate) {this.delegate = delegate;return Proxy.newProxyInstance(this.delegate.getClass().getClassLoader(), this.delegate.getClass().getInterfaces(), this);}public Object invoke(Object proxy, Method method, Object[] args)throws Throwable {Object result = null;try {// 执行原来的方法之前记录日志Logger.logging(Level.DEBUGE, method.getName() + " Method end .");// JVM通过这条语句执行原来的方法(反射机制)result = method.invoke(this.delegate, args);// 执行原来的方法之后记录日志Logger.logging(Level.INFO, method.getName() + " Method Start!");} catch (Exception e) {e.printStackTrace();}// 返回方法返回值给调用者return result;}}测试:
public class Test {public static void main(String[] args) {IHello hello = (IHello) new DynaProxyHello().bind(new Hello());hello.sayGoogBye("Double J");hello.sayHello("Double J");}}?
七. Adapter(适配器)模式
一、原理图:
?二、示例代码?
/* * 源角色 */public class Adaptee { public int get220v(){ return 220; }}? /* * 目标角色 */public interface Target { int get110v(); int get220v();} ?/* * 适配器角色:扩展源角色,实现目标角色,从而使得目标角色改动时候,不用改动源角色,只要改动适配器 */public class Adapter extends Adaptee implements Target{ public int get110v(){ return 110; }}?/* * 客户端 */public class Client { public static void main(String rags[]) { new Client().test(); } public void test() { Target target = new Adapter(); int v1 = target.get110v(); int v2 = target.get220v(); }}适配器通过扩展源角色,同时实现目标接口,从而满足了同时提供220v,110v电压的要求。 一、定义
代理模式(Proxy):为其他对象提供一种代理以控制对这个对象的访问。
适配器模式(Adapter):将一个类的接口转换成客户希望的另外一个接口,使得原本接口不兼容而不能一起工作的那些类可以一起工作。
外观模式(Facade):为子系统中的一组接口提供一个一致的界面,此模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。
二、理解
代理模式和适配器模式应该说很相像,但是他们的区别也很明显,代理模式和被代理者的接口是同一个,只是使用中客户访问不到被代理者,所以利用代理间接的访问,而适配器模式,是因为接口不同,为了让用户使用到统一的接口,把原先的对象通过适配器让用户统一的使用,大多数运用在代码维护的后期,或者借用第三方库的情况下,而外观模式,是大家经常无意中使用的,就是把错综复杂的子系统关系封装起来,然后提供一个简单的接口给客户使用,就类似于一个转接口,可以想象成一个漏斗,中间细的那一段,越细耦合度越低,外观模式就是为了降低耦合度。
三、代码
代理模式,代理者保存一个被代理的一个对象;适配器模式,保存了一个被适配的对象;而外观模式,就保存了各个子系统对象,然后根据实际逻辑组合。
?
八. Composite模式
将对象以树形结构组织起来,以达成“部分-整体” 的层次结构,使得客户端对单个对象和组合对象的使用具有一致性.
九. Decorator模式
装饰是在原有类上增加功能用的
代理是对原有类作限制用的(例如权限,进行限制)。
机制差不多,但语义上方向相反
package sd;/** * 项目 */interface Project {/** * 写代码 */void doCoding();}/** * 代码工人 */class Employe implements Project {/** * 编码 */public void doCoding() {System.out.println("代码工人 在编写代码,加班编啊编啊,终于编完了!");}}/** * 项目经理 */class Manager implements Project {private Project project; // 实际上存放的是代码工人对象public Manager(Project project) {this.project = project;}/** * 编码 */public void doCoding() {// 项目经理开始新的工作startNewWork();}/** * 模板:定义项目经理自己的事情 */public void startNewWork() {// 项目经理在做早期工作doEarlyWork();// 项目经理很牛,做完需求和设计后,直接将编码委派给代码工人干project.doCoding();// 项目经理在做收尾工作doEndWork();}/** * 项目经理自己的事情:做早期工作 */public void doEarlyWork() {}/** * 项目经理做收尾工作 */public void doEndWork() {}}/** * 具体的项目经理A */class ManagerA extends Manager {public ManagerA(Project project) {super(project);}/** * 项目经理自己的事情:做早期工作 */public void doEarlyWork() {System.out.println("项目经理A 在做需求分析");System.out.println("项目经理A 在做架构设计");System.out.println("项目经理A 在做详细设计");}}/** * 具体的项目经理B */class ManagerB extends Manager {public ManagerB(Project project) {super(project);}/** * 项目经理自己的事情:做早期工作 */public void doEarlyWork() {System.out.println("项目经理B 在做需求分析");System.out.println("项目经理B 在做详细设计");}/** * 项目经理做收尾工作 */public void doEndWork() {System.out.println("项目经理B 在做收尾工作");}}/** * 客户端测试 */public class Client {public static void main(String args[]) {Project employe = new Employe(); // 代码工人Project managerA = new ManagerA(employe); // 项目经理Project managerB = new ManagerB(employe); // 项目经理// 以经理的名义将编码完成,功劳都是经理的,实际编码的是工人managerA.doCoding();managerB.doCoding();}}??
行为模式:
?
Memento(备忘机制):
在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可将该对象恢复到原先保存的状态。
/* * 发起人角色 */class Originator {private String state;/** * 工厂方法,返回一个新的备忘录对象 */public Memento createMemento() {return new Memento(state);}/** * 将发起人恢复到备忘录对象所记载的状态 */public void restoreMemento(Memento memento) {this.state = memento.getState();}public String getState() {return state;}public void setState(String state) {this.state = state;}}/* * 备忘录角色 */class Memento {private String state;/** * 构造函数 */public Memento(String state) {this.state = state;}public String getState() {return state;}public void setState(String state) {this.state = state;}}/* * 负责人角色 */class Caretaker {private Memento memento;/** * 备忘录的取值方法 */public Memento retrieveMemento() {return this.memento;}/** * 备忘录的保存方法 */public void saveMemento(Memento memento) {this.memento = memento;}}/* * 客户端模拟实现 */public class Client {private static Originator ori = new Originator();private static Caretaker taker = new Caretaker();public static void main(String[] args) {// amigo当前的状态ori.setState("不爱打扮,做事拖拖拉拉,十足马大哈");// 保存amigo当前的状态taker.saveMemento(ori.createMemento());// mother要对amigo进行改造ori.setState("穿着时髦,做事精练");// mother发现改造后产生了很多副作用,于是反悔了,要恢复女儿以前的样子ori.restoreMemento(taker.retrieveMemento());// amigo被打回原型,^_^System.out.println("amigo当前情况: " + ori.getState());}}?
?观察者模式:
Observer模式定义对象间的一对多的依赖关系,当一个对象的状态发生改变时, 所有依赖于它的对象都得到通知并被自动更新。JDK里提供的Observer设计模式的实现由java.util.Observable类和java.util.Observer接口组成。从名字上可以清楚的看出两者在Observer设计模式中分别扮演的角色:Observer是观察者角色,Observable是被观察目标(subject)角色。
import java.util.*;/** * <p> * 使用Observer模式的例子。 自己的手机号码更改后,自己的朋友自动得到通知。 * </p> * * @version 1.0 */public class ObserverDesignPattern extends Observable {public ObserverDesignPattern() {super();// 有两个朋友addFriend(new Friend("Tom"));addFriend(new Friend("Jerry"));}public void addFriend(Friend n) {super.addObserver(n);}/** * 手机号码改变 */public void modifyPhoneNumber(final long l) {/** * 表明状态已经改变,不调用不会通知观察者 */setChanged();// 通知其他人自己的号码改变notifyObservers(new Long(l));}public static void main(String[] args) {ObserverDesignPattern op = new ObserverDesignPattern();// 更改手机号码System.out.println("我手机号码更改为13516816888!");op.modifyPhoneNumber(Long.parseLong("13516816888"));}}class Friend implements Observer {private String name;/** * 朋友的姓名 */public Friend(String name) {this.name = name;}public void setName(String name) {this.name = name;}public String getName() {return name;}public void update(Observable o, Object arg) {if (arg instanceof Long) {System.out.println(name + "已经知道你的手机号码改为:" + arg);}}}Chain of Responsibility(职责链):
Chain of Responsibility(CoR) 是用一系列类(classes)试图处理一个请求request,这些类之间是一个松散的耦合,唯一共同点是在他们之间传递request. 也就是说,来了一个请求,A类先处理,如果没有处理,就传递到B类处理,如果没有处理,就传递到C类处理,就这样象一个链条(chain)一样传递下去。
public class Test {public static void main(String[] args) {Manager aManager = new Manager();ProjectManager aPM = new ProjectManager();Programmer aProgrammer = new Programmer();QA aQA = new QA();Others others = new Others();aManager.addChain(aPM);aPM.addChain(aProgrammer);aProgrammer.addChain(aQA);aQA.addChain(others);aManager.sendToChain("Get Project");aManager.sendToChain("Design");aManager.sendToChain("Coding");aManager.sendToChain("Test");aManager.sendToChain("Kill La Deng !");}}interface Chain {public abstract void addChain(Chain c);public abstract void sendToChain(String mesg);public abstract Chain getChain();}class Manager implements Chain {private Chain nextChain = null;private String responsibility = "Get Project";;public Manager() {}public void addChain(Chain c) {nextChain = c;}public Chain getChain() {return nextChain;}public void sendToChain(String mesg) {if (mesg.equals(responsibility)) {System.out.println("A manager --> Get a Project");} else {if (nextChain != null) {nextChain.sendToChain(mesg);}}}}class ProjectManager implements Chain {private Chain nextChain = null;private String responsibility = "Design";public ProjectManager() {}public void addChain(Chain c) {nextChain = c;}public Chain getChain() {return nextChain;}public void sendToChain(String mesg) {if (mesg.equals(responsibility)) {System.out.println("A PM --> Design");} else {if (nextChain != null) {nextChain.sendToChain(mesg);}}}}class Programmer implements Chain {private Chain nextChain = null;private String responsibility = "Coding";public Programmer() {}public void addChain(Chain c) {nextChain = c;}public Chain getChain() {return nextChain;}public void sendToChain(String mesg) {if (mesg.equals(responsibility)) {System.out.println("A Programmer --> Coding");} else {if (nextChain != null) {nextChain.sendToChain(mesg);}}}}class QA implements Chain {private Chain nextChain = null;private String responsibility = "Test";public QA() {}public void addChain(Chain c) {nextChain = c;}public Chain getChain() {return nextChain;}public void sendToChain(String mesg) {if (mesg.equals(responsibility)) {System.out.println("A QA --> Test");} else {if (nextChain != null) {nextChain.sendToChain(mesg);}}}}class Others implements Chain {private Chain nextChain = null;private String responsibility = "";public Others() {}public void addChain(Chain c) {nextChain = c;}public Chain getChain() {return nextChain;}public void sendToChain(String mesg) {if (mesg.equals(responsibility)) {} elseSystem.out.println("No one can handle --> " + mesg);}}?
Command:
将这些命令封装成在一个类中,然后用户再对这个类进行操作,这就是Command模式。
Facade(外观)模式似乎比较相似。
?
Mediator(中介者):
各个对象之间的交互操作非常多;每个对象的行为操作都依赖彼此对方,修改一个对象的行为,同时会涉及到修改很多其他对象的行为,如果使用Mediator模式,可以使各个对象间的耦合松散,只需关心和 Mediator的关系,使多对多的关系变成了一对多的关系,可以降低系统的复杂性,提高可修改扩展性.
package t;class Anchor {private boolean free;private Mediator med;public Anchor(Mediator md) {med = md;}public boolean isFree() {return free;}public void setFree(boolean free) {this.free = free;}public void speak() {med.anchorSpeak();}public void stop() {med.anchorStop();}}class Guest {private boolean free;private Mediator med;public Guest(Mediator md) {this.med = md;}public boolean isFree() {return free;}public void setFree(boolean free) {this.free = free;}public void speak() {med.guestSpeak();}public void stop() {med.guestStop();}}class Mediator {private Anchor anchor;private Guest guest;public void regAnchor(Anchor anchor) {this.anchor = anchor;}public void regGuest(Guest guest) {this.guest = guest;}public void anchorSpeak() {if (!guest.isFree()) {guest.stop();}System.out.println("Anchor is speaking....");anchor.setFree(false);}public void guestSpeak() {if (anchor.isFree()) {System.out.println("Guest is speaking....");guest.setFree(false);} else {System.out.println("Anchor is speaking. Do not interrupt...");}}public void anchorStop() {System.out.println("Anchor stop speaking now....");anchor.setFree(true);}public void guestStop() {System.out.println("Guest stop speaking now...");guest.setFree(true);}}public class Demo {/** * @param args */public static void main(String[] args) {Mediator med = new Mediator();Anchor anchor = new Anchor(med);Guest guest = new Guest(med);med.regAnchor(anchor);med.regGuest(guest);anchor.speak();guest.speak();anchor.stop();guest.speak();anchor.speak();}}Interpreter(解释器):
?
?
定义语言的文法 ,并且建立一个解释器来解释该语言中的句子.
?
Interpreter似乎使用面不是很广,它描述了一个语言解释器是如何构成的,在实际应用中,我们可能很少去构造一个语言的文法.我们还是来简单的了解一下, 看代码:
import java.util.HashMap;import java.util.Map;/** * Interpreter(解释器) */public class Test {public static void main(String[] args) {// Test :// (true and x) and (y and (not x))Context context = new Context();VariableExp x = new VariableExp("X");VariableExp y = new VariableExp("Y");VariableExp bTure = new VariableExp("true");VariableExp bFalse = new VariableExp("false");// 规则context.Assign("true", true);context.Assign("false", false);context.Assign("X", false);context.Assign("Y", true);// (true and x) and (y and (not x))//BooleanExp expression = new AndExp(new AndExp(bTure, x), new AndExp(y, new NotExp(x)));// (y and (not x)) and (true and x)BooleanExp expression = new AndExp(new AndExp(y, new NotExp(x)), new AndExp(bTure, x));boolean result = expression.Evaluate(context);System.out.println("The result is:" + result);}}class Context {private Map<String, Boolean> context = new HashMap<String, Boolean>();public void Assign(String name, boolean val) {context.put(name, new Boolean(val));}public boolean LookUp(String name) {return ((Boolean) context.get(name)).booleanValue();}public Context() {}}interface BooleanExp {public abstract boolean Evaluate(Context c);public abstract BooleanExp Replace(String var, BooleanExp exp);public abstract BooleanExp Copy();}class VariableExp implements BooleanExp {private String name;public VariableExp(String _name) {name = _name;}public boolean Evaluate(Context c) {return c.LookUp(name);}public BooleanExp Copy() {return new VariableExp(name);}public BooleanExp Replace(String var, BooleanExp exp) {if (var.equals(name)) {return exp.Copy();} else {return new VariableExp(name);}}}class AndExp implements BooleanExp {private BooleanExp operand1;private BooleanExp operand2;public AndExp(BooleanExp oper1, BooleanExp oper2) {operand1 = oper1;operand2 = oper2;}public boolean Evaluate(Context c) {return operand1.Evaluate(c) && operand2.Evaluate(c);}public BooleanExp Copy() {return new AndExp(operand1.Copy(), operand2.Copy());}public BooleanExp Replace(String var, BooleanExp exp) {return new AndExp(operand1.Replace(var, exp), operand2.Replace(var, exp));}}class NotExp implements BooleanExp {private BooleanExp opernot1;public NotExp(BooleanExp oper1) {opernot1 = oper1;}public boolean Evaluate(Context c) {return !(opernot1.Evaluate(c));}public BooleanExp Copy() {return new NotExp(opernot1.Copy());}public BooleanExp Replace(String var, BooleanExp exp) {return new NotExp(opernot1.Replace(var, exp));}}?
Visitor模式:
作用于某个对象群中各个对象的操作. 它可以使你在不改变这些对象本身的情况下,定义作用于这些对象的新操作.
Visitor模式实际上是分离了collection结构中的元素和对这些元素进行操作的行为.
import java.util.ArrayList;import java.util.Iterator;import java.util.List;class Visitor {public void process(Saving service) {System.out.println("存款");}public void process(Draw service) {System.out.println("提款");}public void process(Fund service) {System.out.println("基金");}}// 定义业务基类。abstract class Service {public abstract void accept(Visitor visitor);}// 不同的业务类。class Saving extends Service {public void accept(Visitor visitor) {visitor.process(this);}}class Draw extends Service {public void accept(Visitor visitor) {visitor.process(this);}}class Fund extends Service {public void accept(Visitor visitor) {visitor.process(this);}}public class Client {public static void main(String[] args) {// 定义一个用户Visitor visitor = new Visitor();// 定义三个服务Service s1 = new Saving();Service s2 = new Draw();Service s3 = new Fund();// 一个用户需要受理如下业务。/*s1.accept(visitor);s2.accept(visitor);s3.accept(visitor);*/List<Service> services = new ArrayList<Service>();services.add(s1);services.add(s2);services.add(s3);Iterator<Service> iterator = services.iterator();while (iterator.hasNext()) {Service service = iterator.next();service.accept(visitor);}}}??
?
?
。。。