??xml version="1.0" encoding="utf-8" standalone="yes"?>亚洲精品v亚洲精品v日韩精品,一区在线影院,亚洲精品99久久久久中文字幕http://www.aygfsteel.com/czihong/category/52037.htmlzh-cnSat, 24 Nov 2012 00:20:51 GMTSat, 24 Nov 2012 00:20:51 GMT60Twelve: Iterator Design Patternhttp://www.aygfsteel.com/czihong/articles/390859.html明年今日明年今日Tue, 06 Nov 2012 02:49:00 GMThttp://www.aygfsteel.com/czihong/articles/390859.htmlhttp://www.aygfsteel.com/czihong/comments/390859.htmlhttp://www.aygfsteel.com/czihong/articles/390859.html#Feedback0http://www.aygfsteel.com/czihong/comments/commentRss/390859.htmlhttp://www.aygfsteel.com/czihong/services/trackbacks/390859.htmlIterator (aka Cursor) Overview
One object can traverse all of the elements of another object.




DvdListIterator.java - the Iterator Interface

package behavioral.interator.pattern;

public interface DvdListIterator {

    public void first();

    public void next();

    public boolean isDone();

    public String currentItem();
}

DvdList.java - the Concrete Aggregate (with a Concrete Iterator inner class)

package behavioral.interator.pattern;

public class DvdList {

    private String[]    titles;

    private int                titleCount;

    private int                arraySize;

    public DvdList() {
        titles = new String[3];
        titleCount = 0;
        arraySize = 3;
    }

    public int count() {
        return titleCount;
    }

    public void append(String titleIn) {
        if (titleCount >= arraySize) {
            String[] tempArray = new String[arraySize];
            for (int i = 0; i < arraySize; i++) {
                tempArray[i] = titles[i];
            }
            titles = null;
            arraySize = arraySize + 3;
            titles = new String[arraySize];
            for (int i = 0; i < (arraySize - 3); i++) {
                titles[i] = tempArray[i];
            }
        }
        titles[titleCount++] = titleIn;
    }

    public void delete(String titleIn) {
        boolean found = false;
        for (int i = 0; i < (titleCount - 1); i++) {
            if (found == false) {
                if (titles[i].equals(titleIn)) {
                    found = true;
                    titles[i] = titles[i + 1];
                }
            } else {
                if (i < (titleCount - 1)) {
                    titles[i] = titles[i + 1];
                } else {
                    titles[i] = null;
                }
            }
        }

        if (found == true) {
            --titleCount;
        }
    }

    public DvdListIterator createIterator() {
        return new InnerIterator();
    }

    private class InnerIterator implements DvdListIterator {
        private int    currentPosition    = 0;

        private InnerIterator() {
        }

        public void first() {
            currentPosition = 0;
        }

        public void next() {
            if (currentPosition < (titleCount)) {
                ++currentPosition;
            }
        }

        public boolean isDone() {
            if (currentPosition >= (titleCount)) {
                return true;
            } else {
                return false;
            }
        }

        public String currentItem() {
            return titles[currentPosition];
        }
    }
}


Try the Design Patterns Video Tutorial from SourceMaking

TestDvdIterator.java - testing the iterator

package behavioral.interator.pattern;

public class TestDvdIterator {
    public static void main(String[] args) {
        DvdList fiveShakespeareMovies = new DvdList();
        fiveShakespeareMovies.append("10 Things I Hate About You");
        fiveShakespeareMovies.append("Shakespeare In Love");
        fiveShakespeareMovies.append("O (2001)");
        fiveShakespeareMovies.append("American Pie 2");
        fiveShakespeareMovies.append("Scotland, PA.");
        fiveShakespeareMovies.append("Hamlet (2000)");

        DvdListIterator fiveShakespeareIterator = fiveShakespeareMovies.createIterator();
        while (!fiveShakespeareIterator.isDone()) {
            System.out.println(fiveShakespeareIterator.currentItem());
            fiveShakespeareIterator.next();
        }

        fiveShakespeareMovies.delete("American Pie 2");

        System.out.println(" ");
        fiveShakespeareIterator.first();
        while (!fiveShakespeareIterator.isDone()) {
            System.out.println(fiveShakespeareIterator.currentItem());
            fiveShakespeareIterator.next();
        }
    }
}

Test Results

10 Things I Hate About You
Shakespeare In Love
O (2001)
American Pie 2
Scotland, PA.
Hamlet (2000)
 
10 Things I Hate About You
Shakespeare In Love
O (2001)
Scotland, PA.
Hamlet (2000)

UML

References



明年今日 2012-11-06 10:49 发表评论
]]>
Eleven: Memento Design Patternhttp://www.aygfsteel.com/czihong/articles/390848.html明年今日明年今日Tue, 06 Nov 2012 01:45:00 GMThttp://www.aygfsteel.com/czihong/articles/390848.htmlhttp://www.aygfsteel.com/czihong/comments/390848.htmlhttp://www.aygfsteel.com/czihong/articles/390848.html#Feedback0http://www.aygfsteel.com/czihong/comments/commentRss/390848.htmlhttp://www.aygfsteel.com/czihong/services/trackbacks/390848.htmlRefer to:http://blog.sina.com.cn/s/blog_4a2100f8010142n1.html
1.1.1.概述
备忘录是一个非常容易理解的模式Q只需要看一下后面的客户端测试代码就能明白备忘录模式的用意。备忘录模式是用来保存对象的某一个状态,q样在一定时候,可以通过备忘录来恢复对象的状态?/div>
针对上面所说的用意Q实现v来就需要一个类来保存这个状态,q个cd是备忘录cR鉴于备忘录很容易理解,q接看后面的代码实现吧?/div>
1.1.2.代码实现
在代码实CQ备忘录模式一共有三个c,OriginatorcL原始的对象,正是q个对象的状态需要备忘,q样是ؓ了在一个时_q个对象可以恢复到备忘的状态。还有一个类是MementoQ这个是备忘录,用于保存Originatorcȝ状态。还有一个类CareTaker用来理备忘录?/div>
首先看Originator的代码实现?/div>
    /// <summary>
    /// 用于创徏备忘录的原发器,记录当前的内部状?/span>
    /// </summary>
    public class Originator
    {
        /// <summary>
        /// 当前的状?/span>
        /// </summary>
        private string state;
 
        /// <summary>
        /// 创徏一个当前状态的备忘?/span>
        /// </summary>
        /// <returns></returns>
        public Memento CreateMemento()
        {
            return new Memento(this.state);
        }
 
        /// <summary>
        /// 恢复当前状态ؓ备忘录所保存的状?/span>
        /// </summary>
        /// <param name="memento"></param>
        public void RestoreMemento(Memento memento)
        {
            this.state = memento.GetState();
        }
 
        public string GetState()
        {
            return this.state;
        }
 
        public void SetState(string state)
        {
            this.state = state;
        }
 
    }
Originatorcd有一个状态属性,q个属性代表了Originator对象的实时状态,CreateMemento()Ҏ用来保存Originator对象的一个状态作为备忘,在以后需要的时候可以显C。也是说通过q个Ҏ可以给Originator对象产生一个备忘录。RestoreMemento()Ҏ用来从保存的备忘录中恢复Originator的状态,Originator的状态设|ؓ之前的一个备忘状态?/div>
下面是备忘录cMementocȝ代码实现?/div>
    /// <summary>
    /// 备忘录类
    /// </summary>
    public class Memento
    {
        /// <summary>
        /// 备忘录所保存的状?/span>
        /// </summary>
        private string state;
 
        /// <summary>
        /// 构造函?/span>
        /// </summary>
        /// <param name="state"></param>
        public Memento(string state)
        {
            this.state = state;
        }
 
        public string GetState()
        {
            return this.state;
        }
 
        public void SetState(string state)
        {
            this.state = state;
        }
    }
因ؓMementoc需要保存Originator对象的状态,所以Mementoh一个Originator状态一L属性stateQ这个state用来保存Originator的一个状态?/div>
Mementocȝ理者是CareTakerc,CareTakercȝ代码如下?/div>
    /// <summary>
    /// 负责保存备忘录的理?/span>
    /// </summary>
    public class CareTaker
    {
        /// <summary>
        /// 备忘?/span>
        /// </summary>
        private Memento memento;
 
        /// <summary>
        /// q回所拥有的备忘录
        /// </summary>
        /// <returns></returns>
        public Memento retrieveMemento()
        {
            return this.memento;
        }
 
        /// <summary>
        /// 保存一个备忘录
        /// </summary>
        /// <param name="memento"></param>
        public void SaveMemento(Memento memento)
        {
            this.memento = memento;
        }
    }
CareTakercȝ来管理Memento对象Q所以自w拥有一个Memento对象。ƈ且有一个设|Memento对象ҎQSaveMementoQ和一个取得Memento的方法(retrieveMementoQ?/div>
备忘录模式的核心代码已经定义好了Q下面通过客户端代码来试一下备忘录模式?/div>
        private static Originator o = new Originator();
        private static CareTaker c = new CareTaker();
        public static void Test()
        {
            o.SetState("On");
            c.SaveMemento(o.CreateMemento());
            Console.WriteLine("W一ơؓ" + o.GetState());
            o.SetState("Off");
            Console.WriteLine("W二ơؓ" + o.GetState());
            o.RestoreMemento(c.retrieveMemento());
            Console.WriteLine("恢复C一ơؓ" + o.GetState());
        }
在客L代码中,定义了一个Originator的对象o和CareTaker 的对象cQ首先对o讄了一个状态,q且通过cQc是管理备忘录的)来把o目前的状态备忘(保存为备忘录Q。然后l设|了一下o的状态,在此Ӟox复自q状态到之前Q因为想恢复的状态保存在了备忘录中,所以通过o的RestoreMemento可以状态恢复ؓ备忘录所记蝲的状态?/div>
客户端的试代码演示的是备忘录模式的意图Q而之前的代码演示的是备忘录模式的l构?/div>
 
1.1.3.模型表示
备忘录模式的UMLcd如下所C?/div>
在备忘录模式的类模型图中可以看出来,OriginatorQMemento和CareTaker三者之间的关系QMemento用来保存Originator的一个状态,Caretaker用来理Memento。在Originator需要Memento的时候,通过Caretaker卛_得到。在Originator需要备忘一个状态的时候,通过Caretaker卛_备忘?/div>
1.1.4.模式分析
备忘录模式就是用来在对象的外部可以保存对象的一个内部状态。用来存储另外一个对象内部状态的快照。备忘录卛_象的一个检查点Q也是一个还原点?/div>
查点Q某一个快照所处的位置Q即一个状态)?/div>
备忘录模式的意图是在不破坏封装性的前提下,捕获一个对象的内部状态,q在该对象之外保存这个状态,q样以后可以将该对象恢复到原先保存的状态?/div>
通过代码实现中的客户端测试代码即可看到备忘录模式的用场景:
1、必M存一个对象在某一个时ȝ状态,q样以后需要的时候就能恢复到之前的状态?/div>
2、如果用接口来让其他对象直接得到q些状态,会暴露对象的实现细节ƈ破坏对象的封装性?/div>
 
通过使用备忘录模式,可以辑ֈ一些效果:
1、保持封装边界。应用用备忘录模式Q将Originator对象中的一些细节隔d了Caretaker和Memento中。保持了Originatorcd部信息对其他对象的隐藏,从而保持了装边界?/div>
2、简化了Originatorc,OriginatorcM的一些操作交l了Caretaker和Memento?/div>
3、增加了额外的代P使用了备忘录模式Q就D了OriginatorcM的状态在产生备忘录的时候复制了信息Q这样如果需要备忘的信息量很大,那么备忘录模式会D额外大量的开销?/div>
4、定义窄接口和宽接口。一些语a中可能难以保证只有Originator可访问备忘录的状态。也是说Originator之外的对象可能会讉KMemento的状态,D不安全?/div>
5、维护备忘录存在潜在的代仗Caretaker在维护Memento的时候,因ؓCaretaker不知道备忘录Memento所保存的状态数量,所以在通过Caretaker来保存Memento的时候,可能会导致大量的存储开销?/div>
 
因ؓ效果4所说的潜在的安全问题,备忘录还有另外一U安全的实现方式Q也是Memento定义为Originator的内部类Q这L话Memento也就是只有Originator才能讉K了?/div>
安全模式的一U备忘录模式代码实现Q如下:
    public interface IMementoSafeMode
    {
    }
定义一个备忘录的接口,q样封装了备忘录的讉KQ外部的c都通过讉K接口来访问备忘录。备忘录模式的一个要点就是不破坏装性?/div>
下面是一U安全实现的备忘录管理员cȝ实现?/div>
    public class CareTakerSafeMode
    {
        private IMementoSafeMode memento;
        public IMementoSafeMode RetriveMemento()
        {
            return this.memento;
        }
        public void SaveMemento(IMementoSafeMode memento)
        {
            this.memento = memento;
        }
    }
通过接口的实玎ͼ理员完全不会访问备忘录cȝQ这样就使得备忘录类只会暴露l和他有关系的类Q这也是单一原则的体玎ͼ卌_c特法则QLODQ:只与你的朋友通信Q不和陌生h说话?/div>
下面是安全的备忘录模式的核心实现?/div>
    public class OriginatorSafeMode
    {
        private string state;
        public OriginatorSafeMode() { }
 
        public IMementoSafeMode CreateMemento()
        {
             MementoSafeMode mbox = new MementoSafeMode(this.state);
             return mbox;
        }
        public void RestoreMemento(IMementoSafeMode memento)
        {
            MementoSafeMode mementoSafeMode = (MementoSafeMode)memento;
            this.state = mementoSafeMode.State;
        }
        public string State
        {
            get { return this.state; }
            set { this.state = value; }
        }
 
        protected class MementoSafeMode : IMementoSafeMode
        {
            private string state;
            /// <summary>
            /// </summary>
            /// <param name="state"></param>
            public MementoSafeMode(string state)
            {
                this.state = state;
            }
            public string State
            {
                get { return this.state; }
                set { this.state = value; }
            }
        }
    }
在之前的备忘录模式中Q备忘录模式Memento和OriginatorcL分开的,q里Memento作ؓOriginator的内部类Q这样限制了Memento的访问范_卛_有Originatorcȝ内部才能讉K?/div>
注意C#和JAVA在处理内部类的时候有不一致的地方。C#中内部类的Public属性只能是外部c范围内讉KQ如果是private则外部类也无法访问,只有在内部类之内才能讉K。但是在java中要实现q样的效果,内部cȝ所有属性都必须是PrivateQ这h限制了只有外部类讉K。在java中,外部cȝg一个命名空_通过外部cd以看到内部类QOriginatorSafeMode.MementoSafeModeq样的写法就D了内部类的暴Ԍ只不q无法实例化而已Q。即使不能实例化Q但是也对外暴露了内部类。在C#中这一Ҏ所改进Q内部类在外面根本无法看到?/div>
实现了内部类的UMLcd省略Q内部类在UML中用圈里面包含的一个叉来显C,另一端是头Q箭头指向的是内部类。Visual Studio 2010中自带的UMLcd和Visio中的UMLcd都不支持内部cȝ表示Q用rose可以甅R?/div>
1.1.5.思想
目的Q在不破坏封装性的前提下,捕获一个对象的内部状态,q在该对象之外保存这个状态。这样以后就可以该对象恢复到原先保存的状态?/div>
实现思想Q用一个Memento的类来保存需要恢复的状态,可以是一个或者多个。ƈ且由另一个类CareTaker来负责恢复?/div>
1.1.6.应用
应用中如果有cM历史记录机制的功能,那么q个功能有可能就能用备忘录模式Q因为历史记录就是一个过ȝ状态,那么如果要访问历史记录就表示要恢复状态。保存历史记录的cd是一个备忘录cR?/div>
当然了,如果理解了之前的备忘录模式的实现Q那么根据其要点“恢复到原先保存的状?#8221;Q那么如果需要恢复一个类的状态到以前的某个状态,则备忘录基本上就可以搞定Q但是,切忌杀鸡用牛刀的悲剧?/div>


明年今日 2012-11-06 09:45 发表评论
]]>Ten: Mediator Design Patternhttp://www.aygfsteel.com/czihong/articles/390799.html明年今日明年今日Mon, 05 Nov 2012 03:45:00 GMThttp://www.aygfsteel.com/czihong/articles/390799.htmlhttp://www.aygfsteel.com/czihong/comments/390799.htmlhttp://www.aygfsteel.com/czihong/articles/390799.html#Feedback0http://www.aygfsteel.com/czihong/comments/commentRss/390799.htmlhttp://www.aygfsteel.com/czihong/services/trackbacks/390799.htmlRefer to: http://blog.sina.com.cn/s/blog_3fe961ae0100qbz6.html
意图
通过引入中介者模式来在对象之间传递消息(承担中介者)Q以化对象之间的通信?/div>
什么是中介者模?/div>
中介者模式包装了一pd对象怺作用的方式,使得q些对象不必互相明显引用。从而它们可以较松散地耦合。当q些对象中的某些对象之间的相互作用发生改变时Q不会立卛_响到其他的一些对象之间的怺作用。从而保证这些相互作用可以彼此独立地变化?/div>
在中介者模式中Q所有的成员对象者可以协调工作,但是又不直接怺理。这些对象都与一个处于中心地位的中介者对象发生紧密的关系Q由q个中介者对象进行协调工作。这个协调者对象叫做中介者(MediatorQ,而中介者所协调的成员对象称做同事(ColleagueQ对象?/div>
cd
角色
Q?Q抽象中介者(MediatorQ角Ԍ定义出同事对象到中介者对象的接口Q其中主要的Ҏ是一个(或者多个)事gҎ。在有些情况下,q个抽象对象可以省略?/div>
Q?Q具体中介者(ConcreteMediatorQ角Ԍ从抽象中介者承而来Q实C抽象类所声明的事件方法。具体中介者知晓所有的具体同事c,它从具体同事对象接收消息、向具体同事对象发出命o?/div>
Q?Q抽象同事类QColleagueQ角Ԍ定义Z介者到同事对象的接口。同事对象只知道中介者而不知道其余的同事对象?/div>
Q?Q具体同事类QConcreteColleagueQ角Ԍ所有的具体同事cd从抽象同事类l承而来。每一个具体同事类都很清楚它自己在范围内的行为,而不知道它在大范围内的目的。在C意性的cd中,具体同事cLColleague1和Colleague2?/div>
 
源代?/div>
package 中介者模?
//抽象中介?/span>
public abstract class Mediator {
 
//事gҎQ由子类实现
public abstract void colleagueChanged(Colleague c);
}
 
 
package 中介者模?
//抽象同事c?/span>
public abstract class Colleague {
  private Mediator mediator;
 
//构造函敎ͼ中介者作为参?/span>
public Colleague(Mediator m){
  this.mediator=m;
}
 
public Mediator getMediator(){
  return this.mediator;
}
 
//行动ҎQ由子类实现
public abstract void action();
 
//当同事对象发生变化时Q告知中介?/span>
public void change(){
  mediator.colleagueChanged(this);
}
}
 
 
package 中介者模?
 
public class Colleague1 extends Colleague {
 
public Colleague1(Mediator m) {
  super(m);
}
 
@Override
public void action() {
  System.out.println("Colleague1 action");
}
 
}
 
 
 
package 中介者模?
 
public class Colleague2 extends Colleague {
 
public Colleague2(Mediator m) {
  super(m);
}
 
@Override
public void action() {
  System.out.println("Colleague2 action");
}
 
}
 
 
 
package 中介者模?
//具体中介?/span>
public class ConcreteMediator extends Mediator{
 
private Colleague1 colleague1;
private Colleague2 colleague2;
 
@Override
public void colleagueChanged(Colleague c) {
//中介者通知其它同事对象作出响应Q实际的代码要复杂得?/span>
  if(c==colleague1){
    System.out.println("colleague1发生改变Q其他同事对象作出响?);
    this.colleague2.action();
  }else if(c==colleague2){
    System.out.println("colleague2发生改变Q其他同事对象作出响?);
    this.colleague1.action();
  }
}
 
public void createConcreteColleague(){
  colleague1=new Colleague1(this);
  colleague2=new Colleague2(this);
}
 
public Colleague1 getColleague1() {
  return colleague1;
}
 
public Colleague2 getColleague2() {
return colleague2;
}
}
 
 
package 中介者模?
 
public class Client {
public static void main(String[] args) {
  ConcreteMediator m = new ConcreteMediator();
  m.createConcreteColleague();
  Colleague c1=m.getColleague1();
  Colleague c2=m.getColleague2();
  c1.change();
  c2.change();
 }
}
 
输出Q?/div>
colleague1发生改变Q其他同事对象作出响?/div>
Colleague2 action
colleague2发生改变Q其他同事对象作出响?/div>
Colleague1 action


明年今日 2012-11-05 11:45 发表评论
]]>Nine: Interpreter Design Patternhttp://www.aygfsteel.com/czihong/articles/390784.html明年今日明年今日Mon, 05 Nov 2012 02:34:00 GMThttp://www.aygfsteel.com/czihong/articles/390784.htmlhttp://www.aygfsteel.com/czihong/comments/390784.htmlhttp://www.aygfsteel.com/czihong/articles/390784.html#Feedback0http://www.aygfsteel.com/czihong/comments/commentRss/390784.htmlhttp://www.aygfsteel.com/czihong/services/trackbacks/390784.htmlInterpreter解释器设计模式的定义Q给定一个语aQ定义其文法的一U表C,q定义一个解释器Q这个解释器使用该表C来解释语言中的句子?/p>

Interpreter解释器设计模式角色如下:

(1).抽象表达?AbstractExpression)角色Q声明一个所有的具体表达式角色都需要实现的抽象接口。这个接口主要定义一个interpret()ҎQ称做解释操作?nbsp;
(2).l结W表辑ּ(TerminalExpression)角色Q没有子节点的表辑ּ?nbsp;
(3).非终l符表达?NonterminalExpression)角色Q有子节点的表达式,解释操作以递归方式调用其子节点表达式?nbsp;

(4).上下?Context)角色Q上下文提供解释器之外的一些全局信息Q比如变量的真实量值等?nbsp;

Interpreter解释器设计模式结构如下:


通过~写一个模拟java中日期格式化为指定字W串的例子来演示Interpreter解释器设计模式,代码如下Q?/p>

[java] view plaincopy



package behavioral.interpreter.pattern;

import java.util.Date;

public interface AbstractExpression {

    public String format(Date date);;
}



package behavioral.interpreter.pattern;

import java.util.Calendar;
import java.util.Date;

public class DataFormatExpression implements AbstractExpression {

    private static final String        pattern1    = "yyyy-MM-dd";
    private static final String        pattern2    = "yyyy/MM/dd";
    private static final Calendar    calendar    = Calendar.getInstance();

    private String                                separator    = "";

    public DataFormatExpression() {
    };

    public DataFormatExpression(String pattern) {
        if (pattern1.equals(pattern)) {
            separator = "-";
        } else if (pattern.equals(pattern)) {
            separator = "/";
        }
    }

    public String getYear(Calendar cal) {
        return cal.get(Calendar.YEAR) + "";
    }

    public String getMonth(Calendar cal) {
        int month = cal.get(Calendar.MONTH) + 1;
        return month < 10 ? "0" + month : "" + month;
    }

    public String getDay(Calendar cal) {
        int day = cal.get(Calendar.DAY_OF_MONTH);
        return day < 10 ? "0" + day : "" + day;
    }

    @Override
    public String format(Date date) {
        calendar.setTime(date);
        return getYear(calendar) + separator + getMonth(calendar) + separator + getDay(calendar);
    }
}




package behavioral.interpreter.pattern;

import java.util.Date;

public class InterpreterDemo {

    public static void main(String[] args) {
        Date date = new Date();
        AbstractExpression expression1 = new DataFormatExpression();
        System.out.println(expression1.format(date));

        AbstractExpression expression2 = new DataFormatExpression("yyyy-MM-dd");
        System.out.println(expression2.format(date));

        AbstractExpression expression3 = new DataFormatExpression("yyyy/MM/dd");
        System.out.println(expression3.format(date));
    }
}

Interpreter解释器设计模式的应用场景Q?/p>

在Y件构E中Q若果某一特定领域的问题比较复杂,cM的模式不断重复出玎ͼ如果使用普通的~程方式来实现将面非常频繁的变化。在q种情况下,特定领域的问题表达为某U语法规则下的句子,再构Z个解释器来解释这L句子Q从而达到解决问题的目的?/p>

JDK中Interpreter解释器设计模式典型应用就是正则表辑ּ?/p>

明年今日 2012-11-05 10:34 发表评论
]]>
Eight: State Design Patternhttp://www.aygfsteel.com/czihong/articles/390681.html明年今日明年今日Fri, 02 Nov 2012 06:56:00 GMThttp://www.aygfsteel.com/czihong/articles/390681.htmlhttp://www.aygfsteel.com/czihong/comments/390681.htmlhttp://www.aygfsteel.com/czihong/articles/390681.html#Feedback0http://www.aygfsteel.com/czihong/comments/commentRss/390681.htmlhttp://www.aygfsteel.com/czihong/services/trackbacks/390681.html阅读全文

明年今日 2012-11-02 14:56 发表评论
]]>
Seven: Visitor Design Patternhttp://www.aygfsteel.com/czihong/articles/390677.html明年今日明年今日Fri, 02 Nov 2012 06:16:00 GMThttp://www.aygfsteel.com/czihong/articles/390677.htmlhttp://www.aygfsteel.com/czihong/comments/390677.htmlhttp://www.aygfsteel.com/czihong/articles/390677.html#Feedback0http://www.aygfsteel.com/czihong/comments/commentRss/390677.htmlhttp://www.aygfsteel.com/czihong/services/trackbacks/390677.htmlIn object-oriented programming and software engineering, the visitor design pattern is a way of separating an algorithm from an object structure on which it operates. A practical result of this separation is the ability to add new operations to existing object structures without modifying those structures. It is one way to easily follow the open/closed principle.

In essence, the visitor allows one to add new virtual functions to a family of classes without modifying the classes themselves; instead, one creates a visitor class that implements all of the appropriate specializations of the virtual function. The visitor takes the instance reference as input, and implements the goal through double dispatch.

File:VisitorClassDiagram.svg



interface CarElementVisitor {
    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) {
        /*
         * accept(CarElementVisitor) in Wheel implements
         * accept(CarElementVisitor) in CarElement, so the call
         * to accept is bound at run time. This can be considered
         * the first dispatch. However, the decision to call
         * visit(Wheel) (as opposed to visit(Engine) etc.) can be
         * made during compile time since 'this' is known at compile
         * time to be a Wheel. Moreover, each implementation of
         * CarElementVisitor implements the visit(Wheel), which is
         * another decision that is made at run time. This can be
         * considered the second dispatch.
         
*/ 
        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 Car() {
        //create new Array of elements
        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 elem : elements) {
            elem.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());
    }
}



明年今日 2012-11-02 14:16 发表评论
]]>
Six: Composite patternhttp://www.aygfsteel.com/czihong/articles/390627.html明年今日明年今日Thu, 01 Nov 2012 09:10:00 GMThttp://www.aygfsteel.com/czihong/articles/390627.htmlhttp://www.aygfsteel.com/czihong/comments/390627.htmlhttp://www.aygfsteel.com/czihong/articles/390627.html#Feedback0http://www.aygfsteel.com/czihong/comments/commentRss/390627.htmlhttp://www.aygfsteel.com/czihong/services/trackbacks/390627.htmlIn software engineering, the composite pattern is a partitioning design pattern. The composite pattern describes that a group of objects are to be treated in the same way as a single instance of an object. The intent of a composite is to "compose" objects into tree structures to represent part-whole hierarchies. Implementing the composite pattern lets clients treat individual objects and compositions uniformly.

Motivation

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 "has-a" relationship between objects.[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.

[edit]When to use

Composite can be used when clients should ignore the difference between compositions of objects and individual objects.[1] If programmers find that they are using multiple objects in the same way, and often have nearly identical code to handle each of them, then composite is a good choice; it is less complex in this situation to treat primitives and composites as homogeneous.

Structure

Composite pattern in UML.
Component
  • is the abstraction for all components, including composite ones
  • declares the interface for objects in the composition
  • (optional) defines an interface for accessing a component's parent in the recursive structure, and implements it if that's appropriate
Leaf
  • represents leaf objects in the composition .
  • implements all Component methods
Composite
  • represents a composite Component (component having children)
  • implements methods to manipulate children
  • implements all Component methods, generally by delegating them to its children

    import java.util.List;
    import java.util.ArrayList;
     
    /** "Component" */
    interface Graphic {
     
        //Prints the graphic.
        public void print();
    }
     
    /** "Composite" */
    class CompositeGraphic implements Graphic {
     
        //Collection of child graphics.
        private List<Graphic> childGraphics = new ArrayList<Graphic>();
     
        //Prints the graphic.
        public void print() {
            for (Graphic graphic : childGraphics) {
                graphic.print();
            }
        }
     
        //Adds the graphic to the composition.
        public void add(Graphic graphic) {
            childGraphics.add(graphic);
        }
     
        //Removes the graphic from the composition.
        public void remove(Graphic graphic) {
            childGraphics.remove(graphic);
        }
    }
     
    /** "Leaf" */
    class Ellipse implements Graphic {
     
        //Prints the graphic.
        public void print() {
            System.out.println("Ellipse");
        }
    }
     
    /** Client */
    public class Program {
     
        public static void main(String[] args) {
            //Initialize four ellipses
            Ellipse ellipse1 = new Ellipse();
            Ellipse ellipse2 = new Ellipse();
            Ellipse ellipse3 = new Ellipse();
            Ellipse ellipse4 = new Ellipse();
     
            //Initialize three composite graphics
            CompositeGraphic graphic = new CompositeGraphic();
            CompositeGraphic graphic1 = new CompositeGraphic();
            CompositeGraphic graphic2 = new CompositeGraphic();
     
            //Composes the graphics
            graphic1.add(ellipse1);
            graphic1.add(ellipse2);
            graphic1.add(ellipse3);
     
            graphic2.add(ellipse4);
     
            graphic.add(graphic1);
            graphic.add(graphic2);
     
            //Prints the complete graphic (four times the string "Ellipse").
            graphic.print();
        }
    }


明年今日 2012-11-01 17:10 发表评论
]]>
Five: Bridge Design Patternhttp://www.aygfsteel.com/czihong/articles/390620.html明年今日明年今日Thu, 01 Nov 2012 08:00:00 GMThttp://www.aygfsteel.com/czihong/articles/390620.htmlhttp://www.aygfsteel.com/czihong/comments/390620.htmlhttp://www.aygfsteel.com/czihong/articles/390620.html#Feedback0http://www.aygfsteel.com/czihong/comments/commentRss/390620.htmlhttp://www.aygfsteel.com/czihong/services/trackbacks/390620.html“Decouple an abstraction from its implementation so that the two can vary independently” is the intent for bridge design pattern as stated by GoF.
Bridge design pattern is a modified version of the notion of “prefer composition over inheritance”.
Problem and Need for Bridge Design Pattern
When there are inheritance hierarchies creating concrete implementation, you loose flexibility because of interdependence. Oops! these kind of sentencies shows that the author(I) didn’t understand and tries to escape! Okay, I will decrypt this sentence in the coming paragraphs.
Decouple implentation from interface and hiding implementation details from client is the essense of bridge design pattern.
Elements of Bridge Design Pattern
Abstraction – core of the bridge design pattern and defines the crux. Contains a reference to the implementer.
Refined Abstraction – Extends the abstraction takes the finer detail one level below. Hides the finer elements from implemetors.
Implementer - This interface is the higer level than abstraction. Just defines the basic operations.
Concrete Implementation – Implements the above implementer by providing concrete implementation.
Example for core elements of Bridge Design Pattern
Vehicle -> Abstraction
manufacture()
Car -> Refined Abstraction 1
manufacture()
Bike -> Refined Abstraction 2
manufacture()
Workshop -> Implementor
work()
Produce -> Concrete Implementation 1
work()
Assemble -> Concrete Implementation 2
work()
Generic UML Diagram for Bridge Design Pattern
Before Bridge Design Pattern
After Bridge Design Pattern
Sample Java Code for Bridge Design Pattern
package com.javapapers.designpattern;
 
/**
 * abstraction in bridge pattern
 * */
abstract class Vehicle {
  protected Workshop workShop1;
  protected Workshop workShop2;
 
  protected Vehicle(Workshop workShop1, Workshop workShop2) {
    this.workShop1 = workShop1;
    this.workShop2 = workShop2;
  }
 
  abstract public void manufacture();
}
 
package com.javapapers.designpattern;
 
/**
 * Refine abstraction 1 in bridge pattern
 */
public class Car extends Vehicle {
 
  public Car(Workshop workShop1, Workshop workShop2) {
    super(workShop1, workShop2);
  }
 
  @Override
  public void manufacture() {
    System.out.print("Car ");
    workShop1.work();
    workShop2.work();
 
  }
 
}
 
package com.javapapers.designpattern;
 
/**
 * Refine abstraction 2 in bridge pattern
 */
public class Bike extends Vehicle {
 
  public Bike(Workshop workShop1, Workshop workShop2) {
    super(workShop1, workShop2);
  }
 
  @Override
  public void manufacture() {
    System.out.print("Bike ");
    workShop1.work();
    workShop2.work();
  }
 
}
 
package com.javapapers.designpattern;
 
/**
 * Implementor for bridge pattern
 * */
public interface Workshop {
  abstract public void work();
}
 
package com.javapapers.designpattern;
 
/**
 * Concrete implementation 1 for bridge pattern
 * */
public class Produce implements Workshop {
 
  @Override
  public void work() {
    System.out.print("Produced");
  }
 
}
 
package com.javapapers.designpattern;
 
/**
 * Concrete implementation 2 for bridge pattern
 * */
public class Assemble implements Workshop {
 
  @Override
  public void work() {
    System.out.println(" Assembled.");
  }
 
}
 
package com.javapapers.designpattern;
 
/*
 * Demonstration of bridge design pattern
 */
public class BridgePattern {
 
  public static void main(String[] args) {
 
    Vehicle vehicle1 = new Car(new Produce(), new Assemble());
    vehicle1.manufacture();
    Vehicle vehicle2 = new Bike(new Produce(), new Assemble());
    vehicle2.manufacture();
 
  }
}
 
Output:
Car Produced Assembled.
Bike Produced Assembled.
Summary of Bridge Design Pattern
Creates two different hierarchies. One for abstraction and another for implementation.
Avoids permanent binding by removing the dependency between abstraction and implementation.
We create a bridge that coordinates between abstraction and implementation.
Abstraction and implementation can be extended separately.
Should be used when we have need to switch implementation at runtime.
Client should not be impacted if there is modification in implementation of abstraction.
Best used when you have multiple implementations.
Bridge Vs Adapter Design Pattern
The adapter design pattern helps it two incompatible classes to work together. But, bridge design pattern decouples the abstraction and implementation by creating two different hierarchies.


明年今日 2012-11-01 16:00 发表评论
]]>Four: Flyweight Patternhttp://www.aygfsteel.com/czihong/articles/390463.html明年今日明年今日Tue, 30 Oct 2012 07:08:00 GMThttp://www.aygfsteel.com/czihong/articles/390463.htmlhttp://www.aygfsteel.com/czihong/comments/390463.htmlhttp://www.aygfsteel.com/czihong/articles/390463.html#Feedback0http://www.aygfsteel.com/czihong/comments/commentRss/390463.htmlhttp://www.aygfsteel.com/czihong/services/trackbacks/390463.htmlq用׃n技术有效地支持大量l粒度的对象Q系l只使用量的对象,而这些对象都相近Q状态变化很,对象使用ơ数增多?/p>

  UMLcd如下Q?/p>

  

  其中cd对象的关p:

  1. Flyweight(抽象轻量U类)Q声明一个接口,通过它可以接受外来的参数(状?QƈҎ状态做出出?作用)?/p>

  2. ConcreteFlyweight(具体轻量U类)Q实现Flyweight的接口,qؓ内部状态增加存储空_ConcreteFlyweight对象必须是可以共享的Q它所有存储的状态必L内部的,它独立存在于自己的环境中?/p>

  3. UnsharedConcreteFlyweight(不共享具体轻量c?Q不是所有的Flyweight子类都需要包儿共享,Flyweight的共享不是强制的。在某些Flyweight的结构层ơ中QUnsharedConcreteFlyweight对象通常ConcreteFlyweight对象作ؓ子节炏V?/p>

  4. FlyweightFactory(轻量U类工厂)Q创建ƈ理flyweight对象Q确保n用flyweight。当用户h一个flyweightӞFlyweightFactory提供一个已创徏的实例或者创Z个实例?/p>

  5. Client(客户应用E序)Q维持一个对flyweight的引用;计算或存储一个或多个flyweight的外部状态?/p>

  典型应用的顺序图如图Q?/p>

  

  客户初次从轻量cd厂取flyweightӞ轻量U类工厂创徏一个新的具体flyweight对象Qƈ且保存v来,下次客户取用Ӟ׃用重新创建,直接在保存池中返回。客戯责处理flyweight的状态?/p>

  • 实例1——文档~辑?/h2>

  潜在的,每个字符都被大量的采用,因此׃nq些字符对象会节省大量的存储空间。文档编辑器的UMLcd如下Q?/p>

  

代码
复制代码
 //Flyweight工厂
class CharacterFactotry
{
private Hashtable characters = new Hashtable();
public Character GetCharacter(char key)
{
//在初始化的Hashtable中取出字W?/span>
Character character = (Character)characters[key];
//如果取出的字WؓnullQ初始化?/span>
if (character == null)
{
switch (key)
{
case 'A':
character
= new CharacterA();
break;
case 'B':
character
= new CharacterB();
break;
case 'Z':
character
= new CharacterZ();
break;
}
characters.Add(key, character);
}
return character;
}
}
//Flyweight
abstract class Character
{
protected char symbol;
protected int width;
protected int height;
protected int ascent;
protected int descent;
protected int pointSize;
public abstract void Draw(int pointSize);
}
class CharacterA : Character
{
public CharacterA()
{
this.symbol = 'A';
this.height = 100;
this.width = 120;
this.ascent = 70;
this.descent = 0;
}
public override void Draw(int pointSize)
{
this.pointSize = pointSize;
Console.WriteLine(
this.symbol);
}
}
class CharacterB : Character
{
public CharacterB()
{
this.symbol = 'B';
this.height = 100;
this.width = 140;
this.ascent = 72;
this.descent = 0;
}
public override void Draw(int pointSize)
{
this.pointSize = pointSize;
Console.WriteLine(
this.symbol);
}
}
class CharacterZ : Character
{
public CharacterZ()
{
this.symbol = 'Z';
this.height = 100;
this.width = 100;
this.ascent = 68;
this.descent = 0;
}
public override void Draw(int pointSize)
{
this.pointSize = pointSize;
Console.WriteLine(
this.symbol);
}
}


//客户应用试
class Client
{
[STAThread]
static void Main(string[] args)
{
//用字W数l创造document
char[] document = { 'A', 'B', 'Z', 'Z', 'A', 'A' };
CharacterFactotry f
= new CharacterFactotry();
//外部状?/span>
int pointSize = 12;
//为每一个字W用一个flyweight对象
foreach (char c in document)
{
Character character
= f.GetCharacter(c);
character.Draw(pointSize);
}
Console.Read();
}
}
复制代码

 

 

  • 优势和缺?/h2>

  Flyweight模式需要你认真考虑如何能细化对象,以减处理的对象数量Q从而减存留对象在内存或其他存储设备中的占用量。然而,此模式需要维护大量对象的外部状态,如果外部状态的数据量大Q传递、查找、计这些恶数据会变得非常复杂。当外部和内部的状态很隑ֈ清时Q不宜采用flyweight模式?/p>

  • 应用情景

  下面的情景很适合应用轻量U模式:

  1. pȝ需要存在大量的对象而共享某些本质的、不变的信息?/p>

  2. 对象可以同时用于多个环境下?/p>

  3. 在每个实例下Qflyweight可以作ؓ一个独立的对象?/p>

明年今日 2012-10-30 15:08 发表评论
]]>
Three: Prototype Designhttp://www.aygfsteel.com/czihong/articles/390269.html明年今日明年今日Fri, 26 Oct 2012 06:30:00 GMThttp://www.aygfsteel.com/czihong/articles/390269.htmlhttp://www.aygfsteel.com/czihong/comments/390269.htmlhttp://www.aygfsteel.com/czihong/articles/390269.html#Feedback0http://www.aygfsteel.com/czihong/comments/commentRss/390269.htmlhttp://www.aygfsteel.com/czihong/services/trackbacks/390269.htmlPrototype Definition

Specify the kinds of objects to create using a prototypical instance, and create new objects by copying this prototype.

Class Diagram

Builder

Participants

  • Prototype
    • declares an interface for cloning itself.
  • ConcretePrototype.
    • implements an operation for cloning itself.
  • Client.
    • creates a new object by asking a prototype to clone itself.

Example: Product Cache

When object instantiation is a lot more expensive than cloning, Prototype pattern may offer a useful optimization technique.

Example assumptions:

  • An e-commerce application gathers product information trough complex queries against a legacy database.
  • The legacy database is updated at predefined intervals which are known.
  • The number of products allows caching with a reasonable memory consumption.

When a user asks for information for a certain product the application could gather that information in two ways:

  1. execute the complex query against legacy database, gather the information, and instantiate the object.
  2. instantiate the objects at predefined intervals and keep them in a cache, when an object is requested, it is retrieved from cache and cloned. When the legacy database is updated, discard the content of the cache and re-load with new objects.

The second approach is based on Prototype pattern and it is illustrated below:

Example: Class Diagram

Prototype Example

Example: Java sample code

    public abstract class Product implements Cloneable {
        
private String SKU;
        
private String description;    
        
        
public Object clone() {
            Object clone 
= null;
            
try {
                clone 
= super.clone();
            } 
catch (CloneNotSupportedException e) {
                e.printStackTrace();
            }
            
return clone;
        }
        
public String getDescription() {
            
return description;
        }
        
public String getSKU() {
            
return SKU;
        }
        
public void setDescription(String string) {
            description 
= string;
        }
        
public void setSKU(String string) {
            SKU 
= string;
        }
    }
    
public class Book extends Product {
        
private int numberOfPages;

        
public int getNumberOfPages() {
            
return numberOfPages;
        }
        
public void setNumberOfPages(int i) {
            numberOfPages 
= i;
        }
    }
    
public class DVD extends Product {
        
private int duration;

        
public int getDuration() {
            
return duration;
        }
        
public void setDuration(int i) {
            duration 
= i;
        }
    }
    
import java.util.*;
    
public class ProductCache {
        
private static Hashtable productMap = new Hashtable();

        
public static Product getProduct(String productCode) {
            Product cachedProduct 
= (Product) productMap.get(productCode);
            
return (Product) cachedProduct.clone();
        }

        
public static void loadCache() {
            
// for each product run expensive query and instantiate product
            
// productMap.put(productKey, product);
            
// for exemplification, we add only two products
            Book b1 = new Book();
            b1.setDescription(
"Oliver Twist");
            b1.setSKU(
"B1");
            b1.setNumberOfPages(
100);
            productMap.put(b1.getSKU(), b1);
            DVD d1 
= new DVD();
            d1.setDescription(
"Superman");
            d1.setSKU(
"D1");
            d1.setDuration(
180);
            productMap.put(d1.getSKU(), d1);
        }
    }
    
public class Application {
        
public static void main(String[] args) {
            ProductCache.loadCache();

            Book clonedBook 
= (Book) ProductCache.getProduct("B1");
            System.out.println(
"SKU = " + clonedBook.getSKU());
            System.out.println(
"SKU = " + clonedBook.getDescription());
            System.out.println(
"SKU = " + clonedBook.getNumberOfPages());

            DVD clonedDVD 
= (DVD) ProductCache.getProduct("D1");
            System.out.println(
"SKU = " + clonedDVD.getSKU());
            System.out.println(
"SKU = " + clonedDVD.getDescription());
            System.out.println(
"SKU = " + clonedDVD.getDuration());
        }
    }

Benefits

  • Adding and removing products at runtime.
  • Specifying new objects by varying values.
  • Specifying new objects by varying structure.
  • Reduced subclassing.
  • Configuring an application with classes dinamincally.

Usage

  • When the classes to instantiate are specified at run time.
  • When you want to avoid building a class hierarchy of factories that parallels the class hierarchy of products.
  • When instances of a class can have one of only a few combinations of state.


明年今日 2012-10-26 14:30 发表评论
]]>
Two: Strategy patternhttp://www.aygfsteel.com/czihong/articles/381473.html明年今日明年今日Mon, 25 Jun 2012 21:31:00 GMThttp://www.aygfsteel.com/czihong/articles/381473.htmlhttp://www.aygfsteel.com/czihong/comments/381473.htmlhttp://www.aygfsteel.com/czihong/articles/381473.html#Feedback0http://www.aygfsteel.com/czihong/comments/commentRss/381473.htmlhttp://www.aygfsteel.com/czihong/services/trackbacks/381473.htmlStrategy pattern

 

In computer programming, the strategy pattern (also known as the policy pattern) is a particular software design pattern, whereby algorithms can be selected at runtime. Formally speaking, the strategy pattern defines a family of algorithms, encapsulates each one, and makes them interchangeable. Strategy lets the algorithm vary independently from clients that use it.[1]

For instance, a class that performs validation on incoming data may use a strategy pattern to select a validation algorithm based on the type of data, the source of the data, user choice, and/or other discriminating factors. These factors are not known for each case until run-time, and may require radically different validation to be performed. The validation strategies, encapsulated separately from the validating object, may be used by other validating objects in different areas of the system (or even different systems) without code duplication.

The essential requirement in the programming language is the ability to store a reference to some code in a data structure and retrieve it. This can be achieved by mechanisms such as the native function pointer, the first-class function, classes or class instances in object-oriented programming languages, or accessing the language implementation's internal storage of code via reflection.


Example

The following example is in Java.

// The classes that implement a concrete strategy should implement this. // The Context class uses this to call the concrete strategy.

interface Strategy {

     int execute(int a, int b);

 }  

// Implements the algorithm using the strategy interface

class ConcreteStrategyAdd implements Strategy {

       public int execute(int a, int b) {

       System.out.println("Called ConcreteStrategyAdd's execute()");

       return a + b; 

// Do an addition with a and b

 }

 }  

 

class ConcreteStrategySubtract implements Strategy {

       public int execute(int a, int b) {

         System.out.println("Called ConcreteStrategySubtract's execute()");

         return a - b;

 // Do a subtraction with a and b

     }

 }

class ConcreteStrategyMultiply implements Strategy {

       public int execute(int a, int b) {

         System.out.println("Called ConcreteStrategyMultiply's execute()");

         return a * b;

     // Do a multiplication with a and b

}

}  

// Configured with a ConcreteStrategy object and maintains a reference to a Strategy object

class Context {

       private Strategy strategy;

       // Constructor

    public Context(Strategy strategy) {

         this.strategy = strategy;

     }

 

     public int executeStrategy(int a, int b) {

         return strategy.execute(a, b);

     }

 }

 // Test application class StrategyExample {

       public static void main(String[] args) {

           Context context;

           // Three contexts following different strategies

         context = new Context(new ConcreteStrategyAdd());

         int resultA = context.executeStrategy(3,4);

         context = new Context(new ConcreteStrategySubtract());

         int resultB = context.executeStrategy(3,4);

         context = new Context(new ConcreteStrategyMultiply());

         int resultC = context.executeStrategy(3,4);

     }

 }

Strategy versus Bridge

The UML class diagram for the strategy pattern is the same[further explanation needed] as the diagram for the Bridge pattern. However, these two design patterns aren't the same in their intent. While the strategy pattern is meant for behavior, the Bridge pattern is meant for structure.

The coupling between the context and the strategies is tighter than the coupling between the abstraction and the implementation in the Bridge pattern.

Strategy and open/closed principle

http://upload.wikimedia.org/wikipedia/commons/thumb/4/4b/StrategyPattern_IBrakeBehavior.svg/220px-StrategyPattern_IBrakeBehavior.svg.png

Accelerate and brake behaviors must be declared in each new car model

According to the strategy pattern, the behaviors of a class should not be inherited, instead they should be encapsulated using interfaces. As an example, consider a car class. Two possible functionalities for car are brake and accelerate.

Since accelerate and brake behaviors change frequently between models, a common approach is to implement these behaviors in subclasses. This approach has significant drawbacks: accelerate and brake behaviors must be declared in each new Car model. The work of managing these behaviors increases greatly as the number of models increases, and requires code to be duplicated across models. Additionally, it is not easy to determine the exact nature of the behavior for each model without investigating the code in each.

The strategy pattern uses aggregation instead of inheritance. In the strategy pattern behaviors are defined as separate interfaces and specific classes that implement these interfaces. Specific classes encapsulate these interfaces. This allows better decoupling between the behavior and the class that uses the behavior. The behavior can be changed without breaking the classes that use it, and the classes can switch between behaviors by changing the specific implementation used without requiring any significant code changes. Behaviors can also be changed at run-time as well as at design-time. For instance, a car object’s brake behavior can be changed from BrakeWithABS() to Brake() by changing the brakeBehavior member to:

brakeBehavior = new Brake();

This gives greater flexibility in design and is in harmony with the Open/closed principle (OCP) that states that classes should be open for extension but closed for modification.

 



明年今日 2012-06-26 05:31 发表评论
]]>
One: Decorator patternhttp://www.aygfsteel.com/czihong/articles/381472.html明年今日明年今日Mon, 25 Jun 2012 21:30:00 GMThttp://www.aygfsteel.com/czihong/articles/381472.htmlhttp://www.aygfsteel.com/czihong/comments/381472.htmlhttp://www.aygfsteel.com/czihong/articles/381472.html#Feedback0http://www.aygfsteel.com/czihong/comments/commentRss/381472.htmlhttp://www.aygfsteel.com/czihong/services/trackbacks/381472.html阅读全文

明年今日 2012-06-26 05:30 发表评论
]]>
վ֩ģ壺 ײ| DZ| | | α| ̩| | ƽ| | | | | ɽ| | Ӳ| | | ̰| żҽ| | | | ɽ| ʯɽ| ɽ| | ̷| | ʵ| | | ԣ| | «| Ϫ| | | | ƽ| | Ͷ|