设计模式有很多...
一. 工厂模式
工厂方法
抽象类(或接口):
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 test
public 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();
}
}
抽象工厂总结:
抽象工厂:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
二. Prototype
①为了获取对象的一份拷贝,我们可以利用Object类的clone()方法。
②在派生类中覆盖基类的clone()方法,并声明为public。
③在派生类的clone()方法中,调用super.clone()。
④在派生类中实现Cloneable接口。
优点:可以节省大量的接口实现类的编写。采用工厂模式的话,如果分别为用户指定的每种场合都提供一个用户接口工厂类,将会为我们带来繁重的工作量。未来避免用户接口工厂类不断增加,可以考虑使用Prototype模式。
缺点:Java中的原型方法不允许新对象拥有与父对象不同的方法。这时候,在使用原型方法之前,需要仔细考虑原型方法的利弊,甚至要试一下Prototype模式是否满足需求。
三. Builder模式(建造者模式)
将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示.
四. Singleton(单例模式)
形式一:
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();
}
}
一、定义
代理模式(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)) {
} else
System.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);
}
}
}
。。。