??xml version="1.0" encoding="utf-8" standalone="yes"?> 一、学习设计模式最重要的是了解模式的应用场景。编E遇到特定场景的话,要有意识联想到设计模式,哪怕细节忘了也没关p,ȝ书就扑ֈ了?/p>
二、提高设计的思想。学习设计模式的时候,要体会模式精妙之处,当想明白大师思想和自q差距的时候,差距q短了一点儿?/p>
有的模式qxE无奇Q应用却q泛。有的模式设计精巧,应用场景却不易遇到。无论如何,要么掌握工具Q要么学到思想Q都是收莗?/p>
最适合单概括设计模式的是UML图,攉了一个非常好的资源,分n在我的sky drive|络盘上,包含23U设计模式的UML?/p>
http://cid-d8b11f9bf86fecfa.office.live.com/self.aspx/.Public/books/designpatternscard.pdf 设计模式可以分ؓ三类Qbehavioural, structural, creational behavioural 11 U?/strong> 1. MementoQ备忘录Q?/p>
_yE度Q?5?/p>
应用q泛Q??/p>
memento适合保存/恢复状态的场景。分为宽接口和窄接口。学习就要学H接口! 具体误Q?http://www.aygfsteel.com/vcycyv/archive/2011/02/08/343949.html 2. Chain of Responsibility(责Q? _yE度Q?3?/p>
应用q泛Q?3?/p>
适合用在"一pdhandler”的场景下。分为纯和不U两U,好像奛_儿也可以q么分? 具体误Q?/p>
http://www.aygfsteel.com/vcycyv/archive/2011/02/12/344167.html 3. ObserverQ观察者) 因ؓjava里有Obserable和ObserverQ?所以通常在java里不会自p计观察者模式?/p>
4. Command(命o模式) _yE度Q??/p>
应用q泛Q??/p>
command模式用来解耦invoker和receiver. 具体误Q?/p>
http://www.aygfsteel.com/vcycyv/archive/2011/02/12/344168.html 5. State(状态模? _yE度Q??/p>
应用q泛Q??/p>
OO~程如果出现多个相同的if…else条gQ应该考虑用state模式重构。work flow的状态器也是ZState模式的?/p>
具体误Q?/p>
http://www.aygfsteel.com/vcycyv/archive/2011/02/09/343998.html 6. Interpreter _yE度Q?N/A 应用q泛Q?1?/p>
据说只有搜烦引擎才用得上q个模式Q反正我每次学设计模式的时候,都把q个跌去,是不喜Ƣ,抱歉?/p>
7. StrategyQ策略模式) _yE度Q?2?/p>
应用q泛Q??/p>
用来装不同法。从uml图上看和state模式一栗?因ؓq个太简单了Q所以没记笔讎ͼq个忘不了?/p>
8. Iterator(q代? Java Collection都可以P代,在java上不需要格外设计iterator?/p>
9. Template Method(模板Ҏ(gu)) _yE度Q??/p>
应用q泛Q??/p>
见名知义。太单了Q学q一遍就不会忘。但是这个应用非常广泛! 10. Mediator(仲裁? _yE度Q??/p>
应用q泛Q??/p>
用来解耦多个peer。个得这个模式多半会让mediator十分臃肿Qmediator本n需要有很清晰的设计才能使用。应用场景恐怕也?/p>
具体误Q?/p>
http://www.aygfsteel.com/vcycyv/archive/2011/02/08/343951.html 11. Visitor(讉K? _yE度Q??/p>
应用q泛Q??/p>
collection里存一个类pȝentryӞ使用visitor模式可以避免instance of的用。更重要的是方便扩展cȝ?/p>
具体误Q?/p>
http://www.aygfsteel.com/vcycyv/archive/2011/02/13/344194.html Structure 7U?/strong> 12. adapter(适配? _yE度Q??/p>
应用q泛Q??/p>
个h觉得Adapteeq三方提供的时候才可能用上q个模式[vcycyv~辑Q后来意识到Q这个评Z客观。adaptee实现核心功能Q通过adapter暴露多种讉K方式的情况下Qadaptee也是自己写的Q而不是第三方的]。简单应用范围又H,?/p>
13. Proxy(代理) _yE度Q??/p>
应用q泛Q??/p>
aop是代理模式的一U发挥。Spring和Hibernate都大量用proxy。可以引甛_学JDK的dynamic proxy。模式简单,略?/p>
14. Bridge _yE度Q?5?/p>
应用q泛Q?3?/p>
Bridge在技术上是strategy的进一步发挥,但侧重在实现与抽象的解耦?/p>
具体见: http://www.aygfsteel.com/vcycyv/archive/2011/02/08/343950.html 15. Composite _yE度Q?4?/p>
应用q泛Q?3?/p>
适用于树状结构?/p>
具体见: http://www.aygfsteel.com/vcycyv/archive/2011/02/13/344209.html 16. Decorator(装饰) _yE度Q?5?/p>
应用q泛Q??/p>
在java I/O中广泛用。ؓ了解?#8220;cȝ?#8221;的问题?/p>
具体误Q?/p>
http://www.aygfsteel.com/vcycyv/archive/2011/02/09/343997.html 17. Facade(门面) q个UMLN没有Q算马模式Q?/p>
18. Flyweight _yE度Q??/p>
应用q泛Q??/p>
?#8220;单纯”“复合”两种Q本w包含了工厂Ҏ(gu)模式。一pd对象如果他们都有某部分属于特定集合,p他们׃nq个特定集合以节省资源?/p>
具体误Q?/p>
http://www.aygfsteel.com/vcycyv/archive/2011/02/12/344169.html Creational 6 U?/strong> 19. Factory Method(工厂Ҏ(gu)) _yE度Q??/p>
应用q泛Q??/p>
两个变种Q一个是Ҏ(gu)参数创徏对象Q一个是factorycȝ对应产品cȝ。面向接口编E在创徏模式的体现?/p>
具体误Q?/p>
http://www.aygfsteel.com/vcycyv/archive/2011/02/13/344176.html 20. Abstract FactoryQ抽象工厂) _yE度Q??/p>
应用q泛Q??/p>
只有产品有两个类pȝ时候才用得上?/p>
具体误Q?/p>
http://www.aygfsteel.com/vcycyv/archive/2011/02/15/344390.html 21. Builder _yE度Q?5?/p>
应用q泛Q?2?/p>
产品分部分,q且build的过E不定的时候考虑用这U模式。是模板模式的一U发?/p>
具体误Q?/p>
http://www.aygfsteel.com/vcycyv/archive/2011/02/09/343995.html 22. Prototype(原型) java有cloneable的支持,所以通常不需要自p计prototype. java用prototype的时候注意深复制复制的问题。prototype之外的一个选择是提供一个constructor接受本类型对象作为参敎ͼq个方式更加实用Q?/p>
23. singleton(单? 古典的singleton分ؓ懒汉Q饿汉两U。JDK1.5之后可以用唯一entry 的enum作ؓsingleton的实现。好处有两点Q一是简单。二是不需要格外处理serializable的情?/p>
When dealing with tree-structured data, programmers often have to discriminate between a leaf-node and a branch. This makes code more complex, and therefore, error prone. The solution is an interface that allows treating complex and primitive objects uniformly. In object-oriented programming, a composite is an object designed as a composition of one-or-more similar objects, all exhibiting similar functionality. This is known as a "[2]. The key concept is that you can manipulate a single instance of the object just as you would manipulate a group of them. The operations you can perform on all the composite objects often have a least common denominator relationship. For example, if defining a system to portray grouped shapes on a screen, it would be useful to define resizing a group of shapes to have the same effect (in some sense) as resizing a single shape. Example interface CarElementVisitor { FactoryMethod是一U创建性模?它定义了一个创建对象的接口,但是却让子类来决定具体实例化哪一个类.当一个类无法预料要创建哪U类的对象或是一个类需要由子类来指定创建的对象时我们就需要用到Factory Method 模式?单说?Factory Method可以Ҏ(gu)不同的条件生不同的实例,当然q些不同的实例通常是属于相同的cd,h共同的父c?Factory Method把创些实例的具体q程装h?化了客户端的应用,也改善了E序的扩展?使得来可以做最的改动可以加入新的待创徏的类. 通常我们Factory Method作ؓ一U标准的创徏对象的方?当发现需要更多的灉|性的时?开始考虑向其它创建型模式转化 单分? ?是Factory Method 模式的结构图,q里提供了一些术?让我们可以进行更方便的描q? 由此可以清楚的看Lq对应关系: Product <====> Creator ; ConreteProduct <====> ConreteCreator 抽象产品对应抽象创徏?具体产品对应具体创徏?q样做的好处是什么呢?Z么我们不直接用具体的产品和具体的创徏器完成需求呢?实际上我们也可以q样?但通过Factory Method模式来完?客户(client)只需引用抽象的Product和Creater,对具体的ConcreteProduct和ConcreteCreator可以毫不兛_,q样做我们可以获得额外的好处: 现在,请再回头看看基本概念中的那段?开始也许觉得生涩难?现在是不是已l明朗化了很? 下面让我们看看在 Java 中如何实现Factory Method模式,q一步加深对它的认识. 具体实施 先说明一?用Factory Method模式创徏对象q不一定会让我们的代码更短,实事上往往更长,我们也用了更多的类,真正的目的在于这样可以灵zȝ,有弹性的创徏不确定的对象.而且,代码的可重用性提高了,客户端的应用化了,客户E序的代码会大大减少,变的更具可读? 1.a 首先定义一个抽象类Shape,定义两个抽象的方? 1.b 定义 Shape的两个子c? Circle, Square,实现Shape中定义的抽象Ҏ(gu) 1.c 定义抽象的创建器,anOperation调用factoryMethod创徏一个对?q对该对象进行一pd操作. 1.d 定义与circle和square相对应的两个具体创徏器CircleFactory,SquareFactory,实现父类的methodFactoryҎ(gu) 1.e 试c?h意这个客LE序多么z?既没有罗嗦的条g判断语句,也无需兛_ConcreteProduct和ConcreteCreator的细?因ؓq里我用anOperation装了Product里的两个Ҏ(gu),所以连Product的媄子也没看?当然把Product里方法的具体调用攑ֈ客户E序中也是不错的). q行l果如下:
The current shape is: Shape one (created by SquareFactory)
It will draw a square.
It will erase a square.
The current shape is: Shape two (created by CircleFactory)
It will draw a circle.
It will erase a circle. 2.a 我们在第一U方法的基础上进行修?首先自定义一个的异常,q样当传入不正确的参数时可以得到更明昄报错信息. 2.bL了ShapeFactory的两个子c?改ؓ由ShapeFactory直接负责实例的创? ShapeFactory自己变成一个具体的创徏?直接用参数化的方法实现factoryMethodq回多种对象. 2.c 试c?q里客户端必L定参数来军_具体创徏哪个c?q个例子里的anOperation是静态函?可以直接引用. q行l果如下: 有的时候我们会把ConcreteProduct的实例传l创建器作ؓ参数,q种情况?如果在创建器里完成创E?必d断参数的具体cd(用instanceof),然后才能产生相应的实?那么比较好的做法是利用Java的动态装载机制来完成qg?比如:
我们得到一个Shape的子cs,但不知道具体是那个子c?可以利用Classc自带的Ҏ(gu)newInstance()得到实例
return (Shape)s.getClass().newInstance();
q种Ҏ(gu)有兴得读者可以自己尝?限于幅,不写具体代码出来? java tip (http://www.javaworld.com/javaworld/javatips/jw-javatip68.html?page=3) l了cM的例子,多了Fan作ؓreceiver:
TestCommand.java Writing to stdout: Entering function y. Writing to stdout: Step1 completed. Sending via e-mail: Step1 completed. Writing to stdout: An error has occurred. Sending via e-mail: An error has occurred. Writing to stderr: An error has occurred. Note that this example should not be seen as a recommendation on how to write logging classes. Also, note that in a 'pure' implementation of the chain of responsibility pattern, a logger would not pass responsibility further down the chain after handling a message. In this example, a message will be passed down the chain whether it is handled or not. import java.util.*; 一、State模式定义: 允许一个对象在其状态改变时Q改变它的行为。看h对象g修改了它的类? 二、模式解? State模式主要解决的是在开发中时常遇到的根据不同的状态需要进行不同的处理操作的问?而这L问题,大部分h是采用switch-case语句q行处理?q样会造成一个问?分支q多,而且如果加入一个新的状态就需要对原来的代码进行编译。State模式采用了对q些不同的状态进行封装的方式处理q类问题,当状态改变的时候进行处理然后再切换到另一U状?也就是说把状态的切换责Q交给了具体的状态类去负?同时,State模式?Strategy模式有很多相似的地方,需要说明的是两者的思想都是一致的,只不q封装的东西不同:State模式装的是不同的状?而Stategy 模式装的是不同的算法? 三、结构图 State模式l构囑֦? 四、怎么使用Q? 1Q定义一个State接口Q接口中有一个统一的方法,用以装一个特定状态所对应的行为? 2Q定义具体不同状态类ConcreteSate实现State接口? 3Q每一个状态类都实现环境(ContextQ一个状态所对应的行为? 4Q定义一个状态管理器Context. 五、一个例?/p> 输出l果:
handle by ConcreteStateA
handle by ConcreteStateB
handle by ConcreteStateA
handle by ConcreteStateB
每请求一ơ,状态就更换一ơ,执行对应的行ؓ?
六、适用?
1Q一个对象的行ؓ取决于它的状态,q且它必dq行时刻Ҏ(gu)状态改变它的行为?
2Q一个对象含有庞大的条g分支语句Q这些分支依赖于它的状态。这个状态通常用一个或多个枚D帔R表示。通常有多个操作包含这一相同的结构。State 模式每一个分支放入一个独立的cM。这使得你可以根据对象自w的情况对象的状态作Z个对象,q一对象可以不依赖于其他对象而独立变化?
七、优~点
1)优点: 避免了ؓ判断状态而生的巨大的if或case语句?对象行Zl状态类l护后,对于上层E序而言Q仅需要维护状态之间的转换规则?
2)会导致某些系l有q多的具体状态类?
八、参?
http://www.cppblog.com/converse/archive/2006/08/07/10902.html
http://www.aygfsteel.com/flying/archive/2006/08/29/66472.html
]]> 1: import java.util.ArrayList;
2:
3: /** "Component" */
4: interface Graphic {
5:
6: //Prints the graphic.
7: public void print();
8: }
9:
10: /** "Composite" */
11: class CompositeGraphic implements Graphic {
12:
13: //Collection of child graphics.
14: private List<Graphic> mChildGraphics = new ArrayList<Graphic>();
15:
16: //Prints the graphic.
17: public void print() {
18: for (Graphic graphic : mChildGraphics) {
19: graphic.print();
20: }
21: }
22:
23: //Adds the graphic to the composition.
24: public void add(Graphic graphic) {
25: mChildGraphics.add(graphic);
26: }
27:
28: //Removes the graphic from the composition.
29: public void remove(Graphic graphic) {
30: mChildGraphics.remove(graphic);
31: }
32: }
33:
34: /** "Leaf" */
35: class Ellipse implements Graphic {
36:
37: //Prints the graphic.
38: public void print() {
39: System.out.println("Ellipse");
40: }
41: }
42:
43: /** Client */
44: public class Program {
45:
46: public static void main(String[] args) {
47: //Initialize four ellipses
48: Ellipse ellipse1 = new Ellipse();
49: Ellipse ellipse2 = new Ellipse();
50: Ellipse ellipse3 = new Ellipse();
51: Ellipse ellipse4 = new Ellipse();
52:
53: //Initialize three composite graphics
54: CompositeGraphic graphic = new CompositeGraphic();
55: CompositeGraphic graphic1 = new CompositeGraphic();
56: CompositeGraphic graphic2 = new CompositeGraphic();
57:
58: //Composes the graphics
59: graphic1.add(ellipse1);
60: graphic1.add(ellipse2);
61: graphic1.add(ellipse3);
62:
63: graphic2.add(ellipse4);
64:
65: graphic.add(graphic1);
66: graphic.add(graphic2);
67:
68: //Prints the complete graphic (four times the string "Ellipse").
69: graphic.print();
70: }
71: }
]]>
The following example is in the Java programming language, and shows how the contents of a tree of nodes (in this case describing the components of a car) can be printed. Instead of creating "print" methods for each subclass (Wheel, Engine, Body, and Car), a single class (CarElementPrintVisitor) performs the required printing action. Because different subclasses require slightly different actions to print properly, CarElementDoVisitor dispatches actions based on the class of the argument passed to it.
void visit(Wheel wheel);
void visit(Engine engine);
void visit(Body body);
void visit(Car car);
}
interface CarElement {
void accept(CarElementVisitor visitor); // CarElements have to provide accept().
}
class Wheel implements CarElement {
private String name;
public Wheel(String name) {
this.name = name;
}
public String getName() {
return this.name;
}
public void accept(CarElementVisitor visitor) {
visitor.visit(this);
}
}
class Engine implements CarElement {
public void accept(CarElementVisitor visitor) {
visitor.visit(this);
}
}
class Body implements CarElement {
public void accept(CarElementVisitor visitor) {
visitor.visit(this);
}
}
class Car implements CarElement{
CarElement[] elements;
public CarElement[] getElements() {
return elements.clone(); // Return a copy of the array of references.
}
public Car() {
this.elements = new CarElement[]
{ new Wheel("front left"), new Wheel("front right"),
new Wheel("back left") , new Wheel("back right"),
new Body(), new Engine() };
}
public void accept(CarElementVisitor visitor) {
for(CarElement element : this.getElements()) {
element.accept(visitor);
}
visitor.visit(this);
}
}
class CarElementPrintVisitor implements CarElementVisitor {
public void visit(Wheel wheel) {
System.out.println("Visiting "+ wheel.getName()
+ " wheel");
}
public void visit(Engine engine) {
System.out.println("Visiting engine");
}
public void visit(Body body) {
System.out.println("Visiting body");
}
public void visit(Car car) {
System.out.println("Visiting car");
}
}
class CarElementDoVisitor implements CarElementVisitor {
public void visit(Wheel wheel) {
System.out.println("Kicking my "+ wheel.getName() + " wheel");
}
public void visit(Engine engine) {
System.out.println("Starting my engine");
}
public void visit(Body body) {
System.out.println("Moving my body");
}
public void visit(Car car) {
System.out.println("Starting my car");
}
}
public class VisitorDemo {
static public void main(String[] args){
Car car = new Car();
car.accept(new CarElementPrintVisitor());
car.accept(new CarElementDoVisitor());
}
}
?: Factory Method 模式l构
abstract class Shape {
// 勄shape
public abstract void draw();
// 擦去 shape
public abstract void erase();
public String name;
public Shape(String aName){
name = aName;
}
}
// 圆Ş子类
class Circle extends Shape {
public void draw() {
System.out.println("It will draw a circle.");
}
public void erase() {
System.out.println("It will erase a circle.");
}
// 构造函?
public Circle(String aName){
super(aName);
}
}
// 方Ş子类
class Square extends Shape {
public void draw() {
System.out.println("It will draw a square.");
}
public void erase() {
System.out.println("It will erase a square.");
}
// 构造函?
public Square(String aName){
super(aName);
}
}
abstract class ShapeFactory {
protected abstract Shape factoryMethod(String aName);
// 在anOperation中定义Shape的一pd行ؓ
public void anOperation(String aName){
Shape s = factoryMethod(aName);
System.out.println("The current shape is: " + s.name);
s.draw();
s.erase();
}
}
// 定义q回 circle 实例?CircleFactory
class CircleFactory extends ShapeFactory {
// 重蝲factoryMethodҎ(gu),q回Circle对象
protected Shape factoryMethod(String aName) {
return new Circle(aName + " (created by CircleFactory)");
}
}
// 定义q回 Square 实例?SquareFactory
class SquareFactory extends ShapeFactory {
// 重蝲factoryMethodҎ(gu),q回Square对象
protected Shape factoryMethod(String aName) {
return new Square(aName + " (created by SquareFactory)");
}
}
class Main {
public static void main(String[] args){
ShapeFactory sf1 = new SquareFactory();
ShapeFactory sf2 = new CircleFactory();
sf1.anOperation("Shape one");
sf2.anOperation("Shape two");
}
}
class NoThisShape extends Exception {
public NoThisShape(String aName) {
super(aName);
}
}
abstract class ShapeFactory {
private static Shape s;
private ShapeFactory() {}
static Shape factoryMethod(String aName, String aType) throws NoThisShape{
if (aType.compareTo("square")==0)
return new Square(aName);
else if (aType.compareTo("circle")==0)
return new Circle(aName);
else throw new NoThisShape(aType);
}
// 在anOperation中定义Shape的一pd行ؓ
static void anOperation(String aName, String aType) throws NoThisShape{
s = factoryMethod(aName, aType);
System.out.println("The current shape is: " + s.name);
s.draw();
s.erase();
}
}
class Main {
public static void main(String[] args) throws NoThisShape{
ShapeFactory.anOperation("Shape one","circle");
ShapeFactory.anOperation("Shape two","square");
ShapeFactory.anOperation("Shape three", "delta");
}
}
The current shape is: Shape one
It will draw a circle.
It will erase a circle.
The current shape is: Shape two
It will draw a square.
It will erase a square.
Exception in thread "main" NoThisShape: delta
at ShapeFactory.factoryMethod(ShapeFactory.java:10)
at ShapeFactory.anOperation(ShapeFactory.java:15)
at Main.main(Main.java:5)
]]>
]]>/*the Invoker class*/
public class Switch {
private Command flipUpCommand;
private Command flipDownCommand;
public Switch(Command flipUpCmd, Command flipDownCmd) {
this.flipUpCommand = flipUpCmd;
this.flipDownCommand = flipDownCmd;
}
public void flipUp() {
flipUpCommand.execute();
}
public void flipDown() {
flipDownCommand.execute();
}
}
/*Receiver class*/
public class Light {
public Light() { }
public void turnOn() {
System.out.println("The light is on");
}
public void turnOff() {
System.out.println("The light is off");
}
}
/*the Command interface*/
public interface Command {
void execute();
}
/*the Command for turning on the light*/
public class FlipUpCommand implements Command {
private Light theLight;
public FlipUpCommand(Light light) {
this.theLight=light;
}
public void execute(){
theLight.turnOn();
}
}
/*the Command for turning off the light*/
public class FlipDownCommand implements Command {
private Light theLight;
public FlipDownCommand(Light light) {
this.theLight=light;
}
public void execute() {
theLight.turnOff();
}
}
/*The test class or client*/
public class PressSwitch {
public static void main(String[] args) {
Light lamp = new Light();
Command switchUp = new FlipUpCommand(lamp);
Command switchDown = new FlipDownCommand(lamp);
// See criticism of this model above:
// The switch itself should not be aware of lamp details (switchUp, switchDown)
// either directly or indirectly
Switch s = new Switch(switchUp,switchDown);
try {
if (args[0].equalsIgnoreCase("ON")) {
s.flipUp();
} else if (args[0].equalsIgnoreCase("OFF")) {
s.flipDown();
} else {
System.out.println("Argument \"ON\" or \"OFF\" is required.");
}
} catch (Exception e){
System.out.println("Arguments required.");
}
}
}
=====================
class Fan {
public void startRotate() {
System.out.println("Fan is rotating");
}
public void stopRotate() {
System.out.println("Fan is not rotating");
}
}
class Light {
public void turnOn( ) {
System.out.println("Light is on ");
}
public void turnOff( ) {
System.out.println("Light is off");
}
}
class Switch {
private Command UpCommand, DownCommand;
public Switch( Command Up, Command Down) {
UpCommand = Up; // concrete Command registers itself with the invoker
DownCommand = Down;
}
void flipUp( ) { // invoker calls back concrete Command, which executes the Command on the receiver
UpCommand . execute ( ) ;
}
void flipDown( ) {
DownCommand . execute ( );
}
}
class LightOnCommand implements Command {
private Light myLight;
public LightOnCommand ( Light L) {
myLight = L;
}
public void execute( ) {
myLight . turnOn( );
}
}
class LightOffCommand implements Command {
private Light myLight;
public LightOffCommand ( Light L) {
myLight = L;
}
public void execute( ) {
myLight . turnOff( );
}
}
class FanOnCommand implements Command {
private Fan myFan;
public FanOnCommand ( Fan F) {
myFan = F;
}
public void execute( ) {
myFan . startRotate( );
}
}
class FanOffCommand implements Command {
private Fan myFan;
public FanOffCommand ( Fan F) {
myFan = F;
}
public void execute( ) {
myFan . stopRotate( );
}
}
public class TestCommand {
public static void main(String[] args) {
Light testLight = new Light( );
LightOnCommand testLOC = new LightOnCommand(testLight);
LightOffCommand testLFC = new LightOffCommand(testLight);
Switch testSwitch = new Switch( testLOC,testLFC);
testSwitch.flipUp( );
testSwitch.flipDown( );
Fan testFan = new Fan( );
FanOnCommand foc = new FanOnCommand(testFan);
FanOffCommand ffc = new FanOffCommand(testFan);
Switch ts = new Switch( foc,ffc);
ts.flipUp( );
ts.flipDown( );
}
}
Command.java
public interface Command {
public abstract void execute ( );
}
abstract class Logger
{
public static int ERR = 3;
public static int NOTICE = 5;
public static int DEBUG = 7;
protected int mask;
// The next element in the chain of responsibility
protected Logger next;
public Logger setNext( Logger l )
{
next = l;
return l;
}
public void message( String msg, int priority )
{
if ( priority <= mask )
{
writeMessage( msg );
}
if ( next != null )
{
next.message( msg, priority );
}
}
abstract protected void writeMessage( String msg );
}
class StdoutLogger extends Logger
{
public StdoutLogger( int mask ) { this.mask = mask; }
protected void writeMessage( String msg )
{
System.out.println( "Writing to stdout: " + msg );
}
}
class EmailLogger extends Logger
{
public EmailLogger( int mask ) { this.mask = mask; }
protected void writeMessage( String msg )
{
System.out.println( "Sending via email: " + msg );
}
}
class StderrLogger extends Logger
{
public StderrLogger( int mask ) { this.mask = mask; }
protected void writeMessage( String msg )
{
System.err.println( "Sending to stderr: " + msg );
}
}
public class ChainOfResponsibilityExample
{
public static void main( String[] args )
{
// Build the chain of responsibility
Logger l,l1;
l1 = l = new StdoutLogger( Logger.DEBUG );
l1 = l1.setNext(new EmailLogger( Logger.NOTICE ));
l1 = l1.setNext(new StderrLogger( Logger.ERR ));
// Handled by StdoutLogger
l.message( "Entering function y.", Logger.DEBUG );
// Handled by StdoutLogger and EmailLogger
l.message( "Step1 completed.", Logger.NOTICE );
// Handled by all three loggers
l.message( "An error has occurred.", Logger.ERR );
}
}
]]> 1: interface State{
2: public void handle(Context ctx);
3: }
4: class ConcreteStateA implements State{
5:
6: public void handle(Context ctx) {
7: System.out.println("handle by ConcreteStateA");
8: if(ctx!=null){
9: ctx.ChangeState(new ConcreteStateB());
10: }
11:
12: }
13: }
14: class ConcreteStateB implements State{
15:
16: public void handle(Context ctx) {
17: System.out.println("handle by ConcreteStateB");
18: if(ctx!=null){
19: ctx.ChangeState(new ConcreteStateA());
20: }
21:
22: }
23: }
24: class Context{
25: private State _state;
26: public Context(State state){
27: _state=state;
28: }
29: public void request(){
30: if(_state!=null){
31: _state.handle(this);
32: }
33: }
34: public void ChangeState(State s){
35: if(_state!=null){
36: _state=null;
37: }
38: _state=s;
39: }
40: }
41: public class StateClient {
42:
43: public static void main(String[] args) {
44: State state=new ConcreteStateA();
45: Context context=new Context(state);
46: context.request();
47: context.request();
48: context.request();
49: context.request();
50:
51: }
52:
53: }
]]>
]]>
]]>
用一个中介者对象来装一pd的对象交互。中介者各对象不需要显式的怺引用Q从而其耦合松散Q而且可以独立的改变他们之间的交互?br>二?l构?br> (?
1) 抽象中介者:定义同事QColleagueQ对象到中介者(MediatiorQ对象的接口Q通常是一个事件方法?br>2) 具体中介者:具体中介者实现抽象中介者声明的Ҏ(gu)。知晓所有的具体同事c,从具体同事接收消息向另外的具体同事类发送命令?br>3) 抽象同事c:定义中介者到同事对象的接口,同事对象只知道中介者而不知道其他同事对象?br>三、一个例?br>
1: import java.util.ArrayList;
2:
3: abstract class AbstractMediator{
4: public abstract void register(AbstractColleague ac);
5: public abstract void ColleagueChanged(AbstractColleague ac);
6: }
7: abstract class AbstractColleague{
8: private AbstractMediator med;
9: public AbstractColleague(AbstractMediator mediator){
10: this.med=mediator;
11: }
12: public abstract void action();
13: public void changed(){
14: med.ColleagueChanged(this);
15: }
16: }
17: class ConcreteMediator extends AbstractMediator{
18:
19: private ArrayList<AbstractColleague> colleagueList=new ArrayList<AbstractColleague>();
20: public void register(AbstractColleague ac) {
21: colleagueList.add(ac);
22: }
23:
24: public void ColleagueChanged(AbstractColleague ac) {
25: for(int i=0;i<colleagueList.size();i++){
26: if(colleagueList.get(i)!=ac){
27: colleagueList.get(i).action();
28: }
29: }
30: }
31: }
32:
33: class ConcreteColleagueA extends AbstractColleague{
34: public ConcreteColleagueA(AbstractMediator mediator){
35: super(mediator);
36: mediator.register(this);
37: }
38: public void action() {
39: System.out.println("AAAAAAAAAAAAAAA");
40: }
41: }
42: class ConcreteColleagueC extends AbstractColleague{
43: public ConcreteColleagueC(AbstractMediator mediator){
44: super(mediator);
45: mediator.register(this);
46: }
47: public void action() {
48: System.out.println("CCCCCCCCCCCCCCC");
49: }
50: }
51: class ConcreteColleagueB extends AbstractColleague{
52: public ConcreteColleagueB(AbstractMediator mediator){
53: super(mediator);
54: mediator.register(this);
55: }
56: public void action() {
57: System.out.println("BBBBBBBBBBBBBBB");
58: }
59: }
60: class test{
61: public static void main(String[] args){
62: AbstractMediator mediator=new ConcreteMediator();
63: AbstractColleague colleagueA=new ConcreteColleagueA(mediator);
64: AbstractColleague colleagueB=new ConcreteColleagueB(mediator);
65: AbstractColleague colleagueC=new ConcreteColleagueC(mediator);
66: colleagueA.changed();
67: colleagueB.changed();
68: colleagueC.changed();
69: }
70: }
71:
五?优缺?br>1Q减了子类生成Mediator原本分布于多个对象间的行ؓ集中在一P改变q些行ؓ只需生成Mediator的子cd可,q样各个Colleaguecd被重用?br>2Q它?yu)各Colleague解耦。Mediator有利于各Colleague间的松耦合Q你可以独立的改变和复用各ColleaguecdMediatorcR?br>3Q它化了对象协议用Mediator和各Colleague间的一对多的交互来代替多对多的交互。一对多的关pL易于理解、维护和扩展?br>4Q它对对象如何协作进行了抽象中介作Z个独立的概念q将其封装在一个对象中Q你将注意力从对象各自本n的行{Ud它们之间的交互上来。这有助于弄清楚一个系l中的对象是如何交互的?br>5Q它使控刉中化Q中介者模式将交互的复杂性变Z介者的复杂性。因Z介者封装了协议Q它可能变得比Q一个Colleague都复杂。这可能使得中介者自w成Z个难于维护的庞然大物?br>六?适用?br>1Q一l对象以定义良好但是复杂的方式进行通信。生的怺依赖关系l构混ؕ且难以理解?br>2Q一个对象引用其他很多对象ƈ且直接与q些对象通信,D难以复用该对象?/p>
interface DrawingAPI {
public void drawCircle(double x, double y, double radius);
}
/** "ConcreteImplementor" 1/2 */
class DrawingAPI1 implements DrawingAPI {
public void drawCircle(double x, double y, double radius) {
System.out.printf("API1.circle at %f:%f radius %f\n", x, y, radius);
}
}
/** "ConcreteImplementor" 2/2 */
class DrawingAPI2 implements DrawingAPI {
public void drawCircle(double x, double y, double radius) {
System.out.printf("API2.circle at %f:%f radius %f\n", x, y, radius);
}
}
/** "Abstraction" */
interface Shape {
public void draw(); // low-level
public void resizeByPercentage(double pct); // high-level
}
/** "Refined Abstraction" */
class CircleShape implements Shape {
private double x, y, radius;
private DrawingAPI drawingAPI;
public CircleShape(double x, double y, double radius, DrawingAPI drawingAPI) {
this.x = x; this.y = y; this.radius = radius;
this.drawingAPI = drawingAPI;
}
// low-level i.e. Implementation specific
public void draw() {
drawingAPI.drawCircle(x, y, radius);
}
// high-level i.e. Abstraction specific
public void resizeByPercentage(double pct) {
radius *= pct;
}
}
/** "Client" */
class BridgePattern {
public static void main(String[] args) {
Shape[] shapes = new Shape[2];
shapes[0] = new CircleShape(1, 2, 3, new DrawingAPI1());
shapes[1] = new CircleShape(5, 7, 11, new DrawingAPI2());
for (Shape shape : shapes) {
shape.resizeByPercentage(2.5);
shape.draw();
}
}
}
Bridge遵@的是接口隔离原则的典型。比如,随着时代的发展,枪在不停的变化改q。与此同时枪的子弹也在改q,很多子弹赋予了新功能Q比如信号弹Q救援弹Q甚x炸弹。这P枪是抽象的同Ӟ子弹也是抽象的。二者组合v来变换无I仔l想一下《java与模式》中桥梁模式的例?-飞机和飞机制造商是不是也是这U灵zd换的l合Q?/p>