锘??xml version="1.0" encoding="utf-8" standalone="yes"?>亚洲国产精品VA在线看黑人,色婷婷亚洲一区二区三区,亚洲熟妇av一区二区三区下载http://www.tkk7.com/czihong/category/52037.htmlzh-cnSat, 24 Nov 2012 00:20:51 GMTSat, 24 Nov 2012 00:20:51 GMT60Twelve: Iterator Design Patternhttp://www.tkk7.com/czihong/articles/390859.html鏄庡勾浠婃棩鏄庡勾浠婃棩Tue, 06 Nov 2012 02:49:00 GMThttp://www.tkk7.com/czihong/articles/390859.htmlhttp://www.tkk7.com/czihong/comments/390859.htmlhttp://www.tkk7.com/czihong/articles/390859.html#Feedback0http://www.tkk7.com/czihong/comments/commentRss/390859.htmlhttp://www.tkk7.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



]]>
Eleven: Memento Design Patternhttp://www.tkk7.com/czihong/articles/390848.html鏄庡勾浠婃棩鏄庡勾浠婃棩Tue, 06 Nov 2012 01:45:00 GMThttp://www.tkk7.com/czihong/articles/390848.htmlhttp://www.tkk7.com/czihong/comments/390848.htmlhttp://www.tkk7.com/czihong/articles/390848.html#Feedback0http://www.tkk7.com/czihong/comments/commentRss/390848.htmlhttp://www.tkk7.com/czihong/services/trackbacks/390848.htmlRefer to:http://blog.sina.com.cn/s/blog_4a2100f8010142n1.html
1.1.1.姒傝堪
澶囧繕褰曟槸涓涓潪甯稿鏄撶悊瑙g殑妯″紡錛屽彧闇瑕佺湅涓涓嬪悗闈㈢殑瀹㈡埛绔祴璇曚唬鐮佸氨鑳芥槑鐧藉蹇樺綍妯″紡鐨勭敤鎰忋傚蹇樺綍妯″紡灝辨槸鐢ㄦ潵淇濆瓨瀵硅薄鐨勬煇涓涓姸鎬侊紝榪欐牱鍦ㄤ竴瀹氭椂鍊欙紝鍙互閫氳繃澶囧繕褰曟潵鎭㈠瀵硅薄鐨勭姸鎬併?/div>
閽堝涓婇潰鎵璇寸殑鐢ㄦ剰錛屽疄鐜拌搗鏉ュ氨闇瑕佷竴涓被鏉ヤ繚瀛樿繖涓姸鎬侊紝榪欎釜綾誨氨鏄蹇樺綍綾匯傞壌浜庡蹇樺綍寰堝鏄撶悊瑙o紝灝辯洿鎺ョ湅鍚庨潰鐨勪唬鐮佸疄鐜板惂銆?/div>
1.1.2.浠g爜瀹炵幇
鍦ㄤ唬鐮佸疄鐜頒腑錛屽蹇樺綍妯″紡涓鍏辨湁涓変釜綾伙紝Originator綾繪槸鍘熷鐨勫璞★紝姝f槸榪欎釜瀵硅薄鐨勭姸鎬侀渶瑕佸蹇橈紝榪欐牱鏄負浜嗗湪涓涓椂闂達紝榪欎釜瀵硅薄鍙互鎭㈠鍒板蹇樼殑鐘舵併傝繕鏈変竴涓被鏄疢emento錛岃繖涓槸澶囧繕褰曪紝鐢ㄤ簬淇濆瓨Originator綾葷殑鐘舵併傝繕鏈変竴涓被CareTaker鐢ㄦ潵綆$悊澶囧繕褰曘?/div>
棣栧厛鐪婳riginator鐨勪唬鐮佸疄鐜般?/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;
        }
 
    }
Originator綾誨叿鏈変竴涓姸鎬佸睘鎬э紝榪欎釜灞炴т唬琛ㄤ簡Originator瀵硅薄鐨勫疄鏃剁姸鎬侊紝CreateMemento()鏂規硶鐢ㄦ潵淇濆瓨Originator瀵硅薄鐨勪竴涓姸鎬佷綔涓哄蹇橈紝鍦ㄤ互鍚庨渶瑕佺殑鏃跺欏彲浠ユ樉紺恒備篃灝辨槸璇撮氳繃榪欎釜鏂規硶灝卞彲浠ョ粰Originator瀵硅薄浜х敓涓涓蹇樺綍銆俁estoreMemento()鏂規硶鐢ㄦ潵浠庝繚瀛樼殑澶囧繕褰曚腑鎭㈠Originator鐨勭姸鎬侊紝灝哋riginator鐨勭姸鎬佽緗負涔嬪墠鐨勪竴涓蹇樼姸鎬併?/div>
涓嬮潰鏄蹇樺綍綾籑emento綾葷殑浠g爜瀹炵幇銆?/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;
        }
    }
鍥犱負Memento綾婚渶瑕佷繚瀛極riginator瀵硅薄鐨勭姸鎬侊紝鎵浠emento鍏鋒湁涓涓狾riginator鐘舵佷竴鏍風殑灞炴tate錛岃繖涓猻tate鐢ㄦ潵淇濆瓨Originator鐨勪竴涓姸鎬併?/div>
Memento綾葷殑綆$悊鑰呮槸CareTaker綾伙紝CareTaker綾葷殑浠g爜濡備笅銆?/div>
    /// <summary>
    /// 璐熻矗淇濆瓨澶囧繕褰曠殑綆$悊鍛?/span>
    /// </summary>
    public class CareTaker
    {
        /// <summary>
        /// 澶囧繕褰?/span>
        /// </summary>
        private Memento memento;
 
        /// <summary>
        /// 榪斿洖鎵鎷ユ湁鐨勫蹇樺綍
        /// </summary>
        /// <returns></returns>
        public Memento retrieveMemento()
        {
            return this.memento;
        }
 
        /// <summary>
        /// 淇濆瓨涓涓蹇樺綍
        /// </summary>
        /// <param name="memento"></param>
        public void SaveMemento(Memento memento)
        {
            this.memento = memento;
        }
    }
CareTaker綾葷敤鏉ョ鐞哅emento瀵硅薄錛屾墍浠ヨ嚜韜嫢鏈変竴涓狹emento瀵硅薄銆傚茍涓旀湁涓涓緗甅emento瀵硅薄鏂規硶錛圫aveMemento錛夊拰涓涓彇寰桵emento鐨勬柟娉曪紙retrieveMemento錛夈?/div>
澶囧繕褰曟ā寮忕殑鏍稿績浠g爜宸茬粡瀹氫箟濂戒簡錛屼笅闈㈤氳繃瀹㈡埛绔唬鐮佹潵嫻嬭瘯涓涓嬪蹇樺綍妯″紡銆?/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("絎竴嬈′負" + o.GetState());
            o.SetState("Off");
            Console.WriteLine("絎簩嬈′負" + o.GetState());
            o.RestoreMemento(c.retrieveMemento());
            Console.WriteLine("鎭㈠鍒頒笂涓嬈′負" + o.GetState());
        }
鍦ㄥ鎴風浠g爜涓紝瀹氫箟浜嗕竴涓狾riginator鐨勫璞鍜孋areTaker 鐨勫璞錛岄鍏堝o璁劇疆浜嗕竴涓姸鎬侊紝騫朵笖閫氳繃c錛坈鏄鐞嗗蹇樺綍鐨勶級鏉ユ妸o鐩墠鐨勭姸鎬佸蹇橈紙淇濆瓨涓哄蹇樺綍錛夈傜劧鍚庣戶緇緗簡涓涓媜鐨勭姸鎬侊紝鍦ㄦ鏃訛紝o鎯蟲仮澶嶈嚜宸辯殑鐘舵佸埌涔嬪墠錛屽洜涓烘兂鎭㈠鐨勭姸鎬佷繚瀛樺湪浜嗗蹇樺綍涓紝鎵浠ラ氳繃o鐨凴estoreMemento鍙互灝嗙姸鎬佹仮澶嶄負澶囧繕褰曟墍璁拌澆鐨勭姸鎬併?/div>
瀹㈡埛绔殑嫻嬭瘯浠g爜婕旂ず鐨勬槸澶囧繕褰曟ā寮忕殑鎰忓浘錛岃屼箣鍓嶇殑浠g爜婕旂ず鐨勬槸澶囧繕褰曟ā寮忕殑緇撴瀯銆?/div>
 
1.1.3.妯″瀷琛ㄧず
澶囧繕褰曟ā寮忕殑UML綾誨浘濡備笅鎵紺恒?/div>
鍦ㄥ蹇樺綍妯″紡鐨勭被妯″瀷鍥句腑鍙互鐪嬪嚭鏉ワ紝Originator錛孧emento鍜孋areTaker涓夎呬箣闂寸殑鍏崇郴錛孧emento鐢ㄦ潵淇濆瓨Originator鐨勪竴涓姸鎬侊紝Caretaker鐢ㄦ潵綆$悊Memento銆傚湪Originator闇瑕丮emento鐨勬椂鍊欙紝閫氳繃Caretaker鍗沖彲寰楀埌銆傚湪Originator闇瑕佸蹇樹竴涓姸鎬佺殑鏃跺欙紝閫氳繃Caretaker鍗沖彲澶囧繕銆?/div>
1.1.4.妯″紡鍒嗘瀽
澶囧繕褰曟ā寮忓氨鏄敤鏉ュ湪瀵硅薄鐨勫閮ㄥ彲浠ヤ繚瀛樺璞$殑涓涓唴閮ㄧ姸鎬併傜敤鏉ュ瓨鍌ㄥ彟澶栦竴涓璞″唴閮ㄧ姸鎬佺殑蹇収銆傚蹇樺綍鍗沖璞$殑涓涓鏌ョ偣錛屼篃鏄竴涓繕鍘熺偣銆?/div>
媯鏌ョ偣錛氭煇涓涓揩鐓ф墍澶勭殑浣嶇疆錛堝嵆涓涓姸鎬侊級銆?/div>
澶囧繕褰曟ā寮忕殑鎰忓浘鏄湪涓嶇牬鍧忓皝瑁呮х殑鍓嶆彁涓嬶紝鎹曡幏涓涓璞$殑鍐呴儴鐘舵侊紝騫跺湪璇ュ璞′箣澶栦繚瀛樿繖涓姸鎬侊紝榪欐牱浠ュ悗灝卞彲浠ュ皢璇ュ璞℃仮澶嶅埌鍘熷厛淇濆瓨鐨勭姸鎬併?/div>
閫氳繃浠g爜瀹炵幇涓殑瀹㈡埛绔祴璇曚唬鐮佸嵆鍙湅鍒板蹇樺綍妯″紡鐨勪嬌鐢ㄥ満鏅細
1銆佸繀欏諱繚瀛樹竴涓璞″湪鏌愪竴涓椂鍒葷殑鐘舵侊紝榪欐牱浠ュ悗闇瑕佺殑鏃跺欏氨鑳芥仮澶嶅埌涔嬪墠鐨勭姸鎬併?/div>
2銆佸鏋滅敤鎺ュ彛鏉ヨ鍏朵粬瀵硅薄鐩存帴寰楀埌榪欎簺鐘舵侊紝灝嗕細鏆撮湶瀵硅薄鐨勫疄鐜扮粏鑺傚茍鐮村潖瀵硅薄鐨勫皝瑁呮с?/div>
 
閫氳繃浣跨敤澶囧繕褰曟ā寮忥紝鍙互杈懼埌涓浜涙晥鏋滐細
1銆佷繚鎸佸皝瑁呰竟鐣屻傚簲鐢ㄤ嬌鐢ㄥ蹇樺綍妯″紡錛屽皢Originator瀵硅薄涓殑涓浜涚粏鑺傞殧紱誨埌浜咰aretaker鍜孧emento涓備繚鎸佷簡Originator綾誨唴閮ㄤ俊鎭鍏朵粬瀵硅薄鐨勯殣钘忥紝浠庤屼繚鎸佷簡灝佽杈圭晫銆?/div>
2銆佺畝鍖栦簡Originator綾伙紝灝哋riginator綾諱腑鐨勪竴浜涙搷浣滀氦緇欎簡Caretaker鍜孧emento銆?/div>
3銆佸鍔犱簡棰濆鐨勪唬浠鳳紝浣跨敤浜嗗蹇樺綍妯″紡錛屽氨瀵艱嚧浜哋riginator綾諱腑鐨勭姸鎬佸湪浜х敓澶囧繕褰曠殑鏃跺欏鍒朵簡淇℃伅錛岃繖鏍峰鏋滈渶瑕佸蹇樼殑淇℃伅閲忓緢澶э紝閭d箞澶囧繕褰曟ā寮忎細瀵艱嚧棰濆澶ч噺鐨勫紑閿銆?/div>
4銆佸畾涔夌獎鎺ュ彛鍜屽鎺ュ彛銆備竴浜涜璦涓彲鑳介毦浠ヤ繚璇佸彧鏈塐riginator鍙闂蹇樺綍鐨勭姸鎬併備篃灝辨槸璇碠riginator涔嬪鐨勫璞″彲鑳戒細璁塊棶Memento鐨勭姸鎬侊紝瀵艱嚧涓嶅畨鍏ㄣ?/div>
5銆佺淮鎶ゅ蹇樺綍瀛樺湪娼滃湪鐨勪唬浠楓侰aretaker鍦ㄧ淮鎶emento鐨勬椂鍊欙紝鍥犱負Caretaker涓嶇煡閬撳蹇樺綍Memento鎵淇濆瓨鐨勭姸鎬佹暟閲忥紝鎵浠ュ湪閫氳繃Caretaker鏉ヤ繚瀛楳emento鐨勬椂鍊欙紝鍙兘浼氬鑷村ぇ閲忕殑瀛樺偍寮閿銆?/div>
 
鍥犱負鏁堟灉4鎵璇寸殑娼滃湪鐨勫畨鍏ㄩ棶棰橈紝澶囧繕褰曡繕鏈夊彟澶栦竴縐嶅畨鍏ㄧ殑瀹炵幇鏂瑰紡錛屼篃灝辨槸灝哅emento瀹氫箟涓篛riginator鐨勫唴閮ㄧ被錛岃繖鏍風殑璇滿emento涔熷氨鏄彧鏈塐riginator鎵嶈兘璁塊棶浜嗐?/div>
瀹夊叏妯″紡鐨勪竴縐嶅蹇樺綍妯″紡浠g爜瀹炵幇錛屽涓嬶細
    public interface IMementoSafeMode
    {
    }
瀹氫箟涓涓蹇樺綍鐨勬帴鍙o紝榪欐牱灝卞皝瑁呬簡澶囧繕褰曠殑璁塊棶錛屽閮ㄧ殑綾婚兘閫氳繃璁塊棶鎺ュ彛鏉ヨ闂蹇樺綍銆傚蹇樺綍妯″紡鐨勪竴涓鐐瑰氨鏄笉鐮村潖灝佽鎬с?/div>
涓嬮潰鏄竴縐嶅畨鍏ㄥ疄鐜扮殑澶囧繕褰曠鐞嗗憳綾葷殑瀹炵幇銆?/div>
    public class CareTakerSafeMode
    {
        private IMementoSafeMode memento;
        public IMementoSafeMode RetriveMemento()
        {
            return this.memento;
        }
        public void SaveMemento(IMementoSafeMode memento)
        {
            this.memento = memento;
        }
    }
閫氳繃鎺ュ彛鐨勫疄鐜幫紝綆$悊鍛樺畬鍏ㄤ笉浼氳闂蹇樺綍綾葷殑錛岃繖鏍峰氨浣垮緱澶囧繕褰曠被鍙細鏆撮湶緇欏拰浠栨湁鍏崇郴鐨勭被錛岃繖涔熸槸鍗曚竴鍘熷垯鐨勪綋鐜幫紝鍗寵開綾崇壒娉曞垯錛圠OD錛夛細鍙笌浣犵殑鏈嬪弸閫氫俊錛屼笉鍜岄檶鐢熶漢璇磋瘽銆?/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; }
            }
        }
    }
鍦ㄤ箣鍓嶇殑澶囧繕褰曟ā寮忎腑錛屽蹇樺綍妯″紡Memento鍜孫riginator綾繪槸鍒嗗紑鐨勶紝榪欓噷灝哅emento浣滀負Originator鐨勫唴閮ㄧ被錛岃繖鏍烽檺鍒朵簡Memento鐨勮闂寖鍥達紝鍗沖彧鏈塐riginator綾葷殑鍐呴儴鎵嶈兘璁塊棶銆?/div>
娉ㄦ剰C#鍜孞AVA鍦ㄥ鐞嗗唴閮ㄧ被鐨勬椂鍊欐湁涓嶄竴鑷寸殑鍦版柟銆侰#涓唴閮ㄧ被鐨凱ublic灞炴у彧鑳芥槸澶栭儴綾昏寖鍥村唴璁塊棶錛屽鏋滄槸private鍒欏閮ㄧ被涔熸棤娉曡闂紝鍙湁鍦ㄥ唴閮ㄧ被涔嬪唴鎵嶈兘璁塊棶銆備絾鏄湪java涓瀹炵幇榪欐牱鐨勬晥鏋滐紝鍐呴儴綾葷殑鎵鏈夊睘鎬ч兘蹇呴』鏄疨rivate錛岃繖鏍鋒墠闄愬埗浜嗗彧鏈夊閮ㄧ被璁塊棶銆傚湪java涓紝澶栭儴綾葷被浼間簬涓涓懡鍚嶇┖闂達紝閫氳繃澶栭儴綾誨彲浠ョ湅鍒板唴閮ㄧ被錛圤riginatorSafeMode.MementoSafeMode榪欐牱鐨勫啓娉曞氨瀵艱嚧浜嗗唴閮ㄧ被鐨勬毚闇詫紝鍙笉榪囨棤娉曞疄渚嬪寲鑰屽凡錛夈傚嵆浣夸笉鑳藉疄渚嬪寲錛屼絾鏄篃瀵瑰鏆撮湶浜嗗唴閮ㄧ被銆傚湪C#涓繖涓鐐規湁鎵鏀硅繘錛屽唴閮ㄧ被鍦ㄥ闈㈡牴鏈棤娉曠湅鍒般?/div>
瀹炵幇浜嗗唴閮ㄧ被鐨刄ML綾誨浘鐪佺暐錛屽唴閮ㄧ被鍦║ML涓嬌鐢ㄥ湀閲岄潰鍖呭惈鐨勪竴涓弶鏉ユ樉紺猴紝鍙︿竴绔槸綆ご錛岀澶存寚鍚戠殑鏄唴閮ㄧ被銆俈isual Studio 2010涓嚜甯︾殑UML綾誨浘鍜孷isio涓殑UML綾誨浘閮戒笉鏀寔鍐呴儴綾葷殑琛ㄧず錛屼嬌鐢╮ose鍙互鐢匯?/div>
1.1.5.鎬濇兂
鐩殑錛氬湪涓嶇牬鍧忓皝瑁呮х殑鍓嶆彁涓嬶紝鎹曡幏涓涓璞$殑鍐呴儴鐘舵侊紝騫跺湪璇ュ璞′箣澶栦繚瀛樿繖涓姸鎬併傝繖鏍蜂互鍚庡氨鍙互灝嗚瀵硅薄鎭㈠鍒板師鍏堜繚瀛樼殑鐘舵併?/div>
瀹炵幇鎬濇兂錛氱敤涓涓狹emento鐨勭被鏉ヤ繚瀛橀渶瑕佹仮澶嶇殑鐘舵侊紝鍙互鏄竴涓垨鑰呭涓傚茍涓旂敱鍙︿竴涓被CareTaker鏉ヨ礋璐f仮澶嶃?/div>
1.1.6.搴旂敤
搴旂敤涓鏋滄湁綾諱技鍘嗗彶璁板綍鏈哄埗鐨勫姛鑳斤紝閭d箞榪欎釜鍔熻兘鏈夊彲鑳藉氨鑳戒嬌鐢ㄥ蹇樺綍妯″紡錛屽洜涓哄巻鍙茶褰曞氨鏄竴涓繃鍘葷殑鐘舵侊紝閭d箞濡傛灉瑕佽闂巻鍙茶褰曞氨琛ㄧず瑕佹仮澶嶇姸鎬併備繚瀛樺巻鍙茶褰曠殑綾誨氨鏄竴涓蹇樺綍綾匯?/div>
褰撶劧浜嗭紝濡傛灉鐞嗚В浜嗕箣鍓嶇殑澶囧繕褰曟ā寮忕殑瀹炵幇錛岄偅涔堟牴鎹叾瑕佺偣“鎭㈠鍒板師鍏堜繚瀛樼殑鐘舵?#8221;錛岄偅涔堝鏋滈渶瑕佹仮澶嶄竴涓被鐨勭姸鎬佸埌浠ュ墠鐨勬煇涓姸鎬侊紝鍒欏蹇樺綍鍩烘湰涓婂氨鍙互鎼炲畾錛屼絾鏄紝鍒囧繉鏉楦$敤鐗涘垁鐨勬偛鍓с?/div>


]]>Ten: Mediator Design Patternhttp://www.tkk7.com/czihong/articles/390799.html鏄庡勾浠婃棩鏄庡勾浠婃棩Mon, 05 Nov 2012 03:45:00 GMThttp://www.tkk7.com/czihong/articles/390799.htmlhttp://www.tkk7.com/czihong/comments/390799.htmlhttp://www.tkk7.com/czihong/articles/390799.html#Feedback0http://www.tkk7.com/czihong/comments/commentRss/390799.htmlhttp://www.tkk7.com/czihong/services/trackbacks/390799.htmlRefer to: http://blog.sina.com.cn/s/blog_3fe961ae0100qbz6.html
鎰忓浘
閫氳繃寮曞叆涓粙鑰呮ā寮忔潵鍦ㄥ璞′箣闂翠紶閫掓秷鎭紙鎵挎媴涓粙鑰咃級錛屼互綆鍖栧璞′箣闂寸殑閫氫俊銆?/div>
浠涔堟槸涓粙鑰呮ā寮?/div>
涓粙鑰呮ā寮忓寘瑁呬簡涓緋誨垪瀵硅薄鐩鎬簰浣滅敤鐨勬柟寮忥紝浣垮緱榪欎簺瀵硅薄涓嶅繀浜掔浉鏄庢樉寮曠敤銆備粠鑰屼嬌瀹冧滑鍙互杈冩澗鏁e湴鑰﹀悎銆傚綋榪欎簺瀵硅薄涓殑鏌愪簺瀵硅薄涔嬮棿鐨勭浉浜掍綔鐢ㄥ彂鐢熸敼鍙樻椂錛屼笉浼氱珛鍗沖獎鍝嶅埌鍏朵粬鐨勪竴浜涘璞′箣闂寸殑鐩鎬簰浣滅敤銆備粠鑰屼繚璇佽繖浜涚浉浜掍綔鐢ㄥ彲浠ュ郊姝ょ嫭绔嬪湴鍙樺寲銆?/div>
鍦ㄤ腑浠嬭呮ā寮忎腑錛屾墍鏈夌殑鎴愬憳瀵硅薄鑰呭彲浠ュ崗璋冨伐浣滐紝浣嗘槸鍙堜笉鐩存帴鐩鎬簰綆$悊銆傝繖浜涘璞¢兘涓庝竴涓浜庝腑蹇冨湴浣嶇殑涓粙鑰呭璞″彂鐢熺揣瀵嗙殑鍏崇郴錛岀敱榪欎釜涓粙鑰呭璞¤繘琛屽崗璋冨伐浣溿傝繖涓崗璋冭呭璞″彨鍋氫腑浠嬭咃紙Mediator錛夛紝鑰屼腑浠嬭呮墍鍗忚皟鐨勬垚鍛樺璞$О鍋氬悓浜嬶紙Colleague錛夊璞°?/div>
綾誨浘
瑙掕壊
錛?錛夋娊璞′腑浠嬭咃紙Mediator錛夎鑹詫細瀹氫箟鍑哄悓浜嬪璞″埌涓粙鑰呭璞$殑鎺ュ彛錛屽叾涓富瑕佺殑鏂規硶鏄竴涓紙鎴栬呭涓級浜嬩歡鏂規硶銆傚湪鏈変簺鎯呭喌涓嬶紝榪欎釜鎶借薄瀵硅薄鍙互鐪佺暐銆?/div>
錛?錛夊叿浣撲腑浠嬭咃紙ConcreteMediator錛夎鑹詫細浠庢娊璞′腑浠嬭呯戶鎵胯屾潵錛屽疄鐜頒簡鎶借薄瓚呯被鎵澹版槑鐨勪簨浠舵柟娉曘傚叿浣撲腑浠嬭呯煡鏅撴墍鏈夌殑鍏蜂綋鍚屼簨綾伙紝瀹冧粠鍏蜂綋鍚屼簨瀵硅薄鎺ユ敹娑堟伅銆佸悜鍏蜂綋鍚屼簨瀵硅薄鍙戝嚭鍛戒護銆?/div>
錛?錛夋娊璞″悓浜嬬被錛圕olleague錛夎鑹詫細瀹氫箟鍑轟腑浠嬭呭埌鍚屼簨瀵硅薄鐨勬帴鍙c傚悓浜嬪璞″彧鐭ラ亾涓粙鑰呰屼笉鐭ラ亾鍏朵綑鐨勫悓浜嬪璞°?/div>
錛?錛夊叿浣撳悓浜嬬被錛圕oncreteColleague錛夎鑹詫細鎵鏈夌殑鍏蜂綋鍚屼簨綾誨潎浠庢娊璞″悓浜嬬被緇ф壙鑰屾潵銆傛瘡涓涓叿浣撳悓浜嬬被閮藉緢娓呮瀹冭嚜宸卞湪灝忚寖鍥村唴鐨勮涓猴紝鑰屼笉鐭ラ亾瀹冨湪澶ц寖鍥村唴鐨勭洰鐨勩傚湪紺烘剰鎬х殑綾誨浘涓紝鍏蜂綋鍚屼簨綾繪槸Colleague1鍜孋olleague2銆?/div>
 
婧愪唬鐮?/div>
package 涓粙鑰呮ā寮?
//鎶借薄涓粙鑰?/span>
public abstract class Mediator {
 
//浜嬩歡鏂規硶錛岀敱瀛愮被瀹炵幇
public abstract void colleagueChanged(Colleague c);
}
 
 
package 涓粙鑰呮ā寮?
//鎶借薄鍚屼簨綾?/span>
public abstract class Colleague {
  private Mediator mediator;
 
//鏋勯犲嚱鏁幫紝涓粙鑰呬綔涓哄弬鏁?/span>
public Colleague(Mediator m){
  this.mediator=m;
}
 
public Mediator getMediator(){
  return this.mediator;
}
 
//琛屽姩鏂規硶錛岀敱瀛愮被瀹炵幇
public abstract void action();
 
//褰撳悓浜嬪璞″彂鐢熷彉鍖栨椂錛屽憡鐭ヤ腑浠嬭?/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) {
//涓粙鑰呴氱煡鍏跺畠鍚屼簨瀵硅薄浣滃嚭鍝嶅簲錛屽疄闄呯殑浠g爜瑕佸鏉傚緱澶?/span>
  if(c==colleague1){
    System.out.println("colleague1鍙戠敓鏀瑰彉錛屽叾浠栧悓浜嬪璞′綔鍑哄搷搴?);
    this.colleague2.action();
  }else if(c==colleague2){
    System.out.println("colleague2鍙戠敓鏀瑰彉錛屽叾浠栧悓浜嬪璞′綔鍑哄搷搴?);
    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();
 }
}
 
杈撳嚭錛?/div>
colleague1鍙戠敓鏀瑰彉錛屽叾浠栧悓浜嬪璞′綔鍑哄搷搴?/div>
Colleague2 action
colleague2鍙戠敓鏀瑰彉錛屽叾浠栧悓浜嬪璞′綔鍑哄搷搴?/div>
Colleague1 action


]]>Nine: Interpreter Design Patternhttp://www.tkk7.com/czihong/articles/390784.html鏄庡勾浠婃棩鏄庡勾浠婃棩Mon, 05 Nov 2012 02:34:00 GMThttp://www.tkk7.com/czihong/articles/390784.htmlhttp://www.tkk7.com/czihong/comments/390784.htmlhttp://www.tkk7.com/czihong/articles/390784.html#Feedback0http://www.tkk7.com/czihong/comments/commentRss/390784.htmlhttp://www.tkk7.com/czihong/services/trackbacks/390784.htmlInterpreter瑙i噴鍣ㄨ璁℃ā寮忕殑瀹氫箟錛氱粰瀹氫竴涓璦錛屽畾涔夊叾鏂囨硶鐨勪竴縐嶈〃紺猴紝騫跺畾涔変竴涓В閲婂櫒錛岃繖涓В閲婂櫒浣跨敤璇ヨ〃紺烘潵瑙i噴璇█涓殑鍙ュ瓙銆?/p>

Interpreter瑙i噴鍣ㄨ璁℃ā寮忚鑹插涓嬶細

(1).鎶借薄琛ㄨ揪寮?AbstractExpression)瑙掕壊錛氬0鏄庝竴涓墍鏈夌殑鍏蜂綋琛ㄨ揪寮忚鑹查兘闇瑕佸疄鐜扮殑鎶借薄鎺ュ彛銆傝繖涓帴鍙d富瑕佸畾涔変竴涓猧nterpret()鏂規硶錛岀О鍋氳В閲婃搷浣溿?nbsp;
(2).緇堢粨絎﹁〃杈懼紡(TerminalExpression)瑙掕壊錛氭病鏈夊瓙鑺傜偣鐨勮〃杈懼紡銆?nbsp;
(3).闈炵粓緇撶琛ㄨ揪寮?NonterminalExpression)瑙掕壊錛氭湁瀛愯妭鐐圭殑琛ㄨ揪寮忥紝瑙i噴鎿嶄綔浠ラ掑綊鏂瑰紡璋冪敤鍏跺瓙鑺傜偣琛ㄨ揪寮忋?nbsp;

(4).涓婁笅鏂?Context)瑙掕壊錛氫笂涓嬫枃鎻愪緵瑙i噴鍣ㄤ箣澶栫殑涓浜涘叏灞淇℃伅錛屾瘮濡傚彉閲忕殑鐪熷疄閲忓肩瓑銆?nbsp;

Interpreter瑙i噴鍣ㄨ璁℃ā寮忕粨鏋勫涓嬶細


閫氳繃緙栧啓涓涓ā鎷焜ava涓棩鏈熸牸寮忓寲涓烘寚瀹氬瓧絎︿覆鐨勪緥瀛愭潵婕旂ずInterpreter瑙i噴鍣ㄨ璁℃ā寮忥紝浠g爜濡備笅錛?/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瑙i噴鍣ㄨ璁℃ā寮忕殑搴旂敤鍦烘櫙錛?/p>

鍦ㄨ蔣浠舵瀯寤鴻繃紼嬩腑錛岃嫢鏋滄煇涓鐗瑰畾棰嗗煙鐨勯棶棰樻瘮杈冨鏉傦紝綾諱技鐨勬ā寮忎笉鏂噸澶嶅嚭鐜幫紝濡傛灉浣跨敤鏅氱殑緙栫▼鏂瑰紡鏉ュ疄鐜板皢闈復闈炲父棰戠箒鐨勫彉鍖栥傚湪榪欑鎯呭喌涓嬶紝灝嗙壒瀹氶鍩熺殑闂琛ㄨ揪涓烘煇縐嶈娉曡鍒欎笅鐨勫彞瀛愶紝鍐嶆瀯寤轟竴涓В閲婂櫒鏉ヨВ閲婅繖鏍風殑鍙ュ瓙錛屼粠鑰岃揪鍒拌В鍐抽棶棰樼殑鐩殑銆?/p>

JDK涓璉nterpreter瑙i噴鍣ㄨ璁℃ā寮忓吀鍨嬪簲鐢ㄥ氨鏄鍒欒〃杈懼紡銆?/p>

]]>
Eight: State Design Patternhttp://www.tkk7.com/czihong/articles/390681.html鏄庡勾浠婃棩鏄庡勾浠婃棩Fri, 02 Nov 2012 06:56:00 GMThttp://www.tkk7.com/czihong/articles/390681.htmlhttp://www.tkk7.com/czihong/comments/390681.htmlhttp://www.tkk7.com/czihong/articles/390681.html#Feedback0http://www.tkk7.com/czihong/comments/commentRss/390681.htmlhttp://www.tkk7.com/czihong/services/trackbacks/390681.html闃呰鍏ㄦ枃

]]>
Seven: Visitor Design Patternhttp://www.tkk7.com/czihong/articles/390677.html鏄庡勾浠婃棩鏄庡勾浠婃棩Fri, 02 Nov 2012 06:16:00 GMThttp://www.tkk7.com/czihong/articles/390677.htmlhttp://www.tkk7.com/czihong/comments/390677.htmlhttp://www.tkk7.com/czihong/articles/390677.html#Feedback0http://www.tkk7.com/czihong/comments/commentRss/390677.htmlhttp://www.tkk7.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());
    }
}



]]>
Six: Composite patternhttp://www.tkk7.com/czihong/articles/390627.html鏄庡勾浠婃棩鏄庡勾浠婃棩Thu, 01 Nov 2012 09:10:00 GMThttp://www.tkk7.com/czihong/articles/390627.htmlhttp://www.tkk7.com/czihong/comments/390627.htmlhttp://www.tkk7.com/czihong/articles/390627.html#Feedback0http://www.tkk7.com/czihong/comments/commentRss/390627.htmlhttp://www.tkk7.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();
        }
    }


]]>
Five: Bridge Design Patternhttp://www.tkk7.com/czihong/articles/390620.html鏄庡勾浠婃棩鏄庡勾浠婃棩Thu, 01 Nov 2012 08:00:00 GMThttp://www.tkk7.com/czihong/articles/390620.htmlhttp://www.tkk7.com/czihong/comments/390620.htmlhttp://www.tkk7.com/czihong/articles/390620.html#Feedback0http://www.tkk7.com/czihong/comments/commentRss/390620.htmlhttp://www.tkk7.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.


]]>Four: Flyweight Patternhttp://www.tkk7.com/czihong/articles/390463.html鏄庡勾浠婃棩鏄庡勾浠婃棩Tue, 30 Oct 2012 07:08:00 GMThttp://www.tkk7.com/czihong/articles/390463.htmlhttp://www.tkk7.com/czihong/comments/390463.htmlhttp://www.tkk7.com/czihong/articles/390463.html#Feedback0http://www.tkk7.com/czihong/comments/commentRss/390463.htmlhttp://www.tkk7.com/czihong/services/trackbacks/390463.html榪愮敤鍏變韓鎶鏈湁鏁堝湴鏀寔澶ч噺緇嗙矑搴︾殑瀵硅薄錛岀郴緇熷彧浣跨敤灝戦噺鐨勫璞★紝鑰岃繖浜涘璞¢兘鐩歌繎錛岀姸鎬佸彉鍖栧緢灝忥紝瀵硅薄浣跨敤嬈℃暟澧炲銆?/p>

銆銆UML綾誨浘濡備笅錛?/p>

銆銆

銆銆鍏朵腑綾誨拰瀵硅薄鐨勫叧緋伙細

銆銆1. Flyweight(鎶借薄杞婚噺綰х被)錛氬0鏄庝竴涓帴鍙o紝閫氳繃瀹冨彲浠ユ帴鍙楀鏉ョ殑鍙傛暟(鐘舵?錛屽茍瀵規柊鐘舵佸仛鍑哄嚭鏉?浣滅敤)銆?/p>

銆銆2. ConcreteFlyweight(鍏蜂綋杞婚噺綰х被)錛氬疄鐜癋lyweight鐨勬帴鍙o紝騫朵負鍐呴儴鐘舵佸鍔犲瓨鍌ㄧ┖闂達紝ConcreteFlyweight瀵硅薄蹇呴』鏄彲浠ュ叡浜殑錛屽畠鎵鏈夊瓨鍌ㄧ殑鐘舵佸繀欏繪槸鍐呴儴鐨勶紝瀹冪嫭绔嬪瓨鍦ㄤ簬鑷繁鐨勭幆澧冧腑銆?/p>

銆銆3. UnsharedConcreteFlyweight(涓嶅叡浜叿浣撹交閲忕駭綾?錛氫笉鏄墍鏈夌殑Flyweight瀛愮被閮介渶瑕佸寘鍎垮叡浜紝Flyweight鐨勫叡浜笉鏄己鍒剁殑銆傚湪鏌愪簺Flyweight鐨勭粨鏋勫眰嬈′腑錛孶nsharedConcreteFlyweight瀵硅薄閫氬父灝咰oncreteFlyweight瀵硅薄浣滀負瀛愯妭鐐廣?/p>

銆銆4. FlyweightFactory(杞婚噺綰х被宸ュ巶)錛氬垱寤哄茍綆$悊flyweight瀵硅薄錛涚‘淇濅韓鐢╢lyweight銆傚綋鐢ㄦ埛璇鋒眰涓涓猣lyweight鏃訛紝FlyweightFactory鎻愪緵涓涓凡鍒涘緩鐨勫疄渚嬫垨鑰呭垱寤轟竴涓疄渚嬨?/p>

銆銆5. Client(瀹㈡埛搴旂敤紼嬪簭)錛氱淮鎸佷竴涓flyweight鐨勫紩鐢紱璁$畻鎴栧瓨鍌ㄤ竴涓垨澶氫釜flyweight鐨勫閮ㄧ姸鎬併?/p>

銆銆鍏稿瀷搴旂敤鐨勯『搴忓浘濡傚浘錛?/p>

銆銆

銆銆瀹㈡埛鍒濇浠庤交閲忕駭綾誨伐鍘傚彇flyweight鏃訛紝杞婚噺綰х被宸ュ巶鍒涘緩涓涓柊鐨勫叿浣揻lyweight瀵硅薄錛屽茍涓斾繚瀛樿搗鏉ワ紝涓嬫瀹㈡埛鍙栫敤鏃訛紝灝變笉鐢ㄩ噸鏂板垱寤猴紝鐩存帴鍦ㄤ繚瀛樻睜涓繑鍥炪傚鎴瘋礋璐e鐞唂lyweight鐨勭姸鎬併?/p>

  • 瀹炰緥1——鏂囨。緙栬緫鍣?/h2>

銆銆娼滃湪鐨勶紝姣忎釜瀛楃閮借澶ч噺鐨勯噰鐢紝鍥犳鍏變韓榪欎簺瀛楃瀵硅薄灝嗕細鑺傜渷澶ч噺鐨勫瓨鍌ㄧ┖闂淬傛枃妗g紪杈戝櫒鐨刄ML綾誨浘濡備笅錛?/p>

銆銆

浠g爜
澶嶅埗浠g爜
 //Flyweight宸ュ巶
class CharacterFactotry
{
private Hashtable characters = new Hashtable();
public Character GetCharacter(char key)
{
//鍦ㄥ垵濮嬪寲鐨凥ashtable涓彇鍑哄瓧絎?/span>
Character character = (Character)characters[key];
//濡傛灉鍙栧嚭鐨勫瓧絎︿負null錛屽垵濮嬪寲瀹?/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)
{
//鐢ㄥ瓧絎︽暟緇勫垱閫燿ocument
char[] document = { 'A', 'B', 'Z', 'Z', 'A', 'A' };
CharacterFactotry f
= new CharacterFactotry();
//澶栭儴鐘舵?/span>
int pointSize = 12;
//涓烘瘡涓涓瓧絎︿嬌鐢ㄤ竴涓猣lyweight瀵硅薄
foreach (char c in document)
{
Character character
= f.GetCharacter(c);
character.Draw(pointSize);
}
Console.Read();
}
}
澶嶅埗浠g爜

 

 

  • 浼樺娍鍜岀己闄?/h2>

銆銆Flyweight妯″紡闇瑕佷綘璁ょ湡鑰冭檻濡備綍鑳界粏鍖栧璞★紝浠ュ噺灝戝鐞嗙殑瀵硅薄鏁伴噺錛屼粠鑰屽噺灝戝瓨鐣欏璞″湪鍐呭瓨鎴栧叾浠栧瓨鍌ㄨ澶囦腑鐨勫崰鐢ㄩ噺銆傜劧鑰岋紝姝ゆā寮忛渶瑕佺淮鎶ゅぇ閲忓璞$殑澶栭儴鐘舵侊紝濡傛灉澶栭儴鐘舵佺殑鏁版嵁閲忓ぇ錛屼紶閫掋佹煡鎵俱佽綆楄繖浜涙伓鏁版嵁浼氬彉寰楅潪甯稿鏉傘傚綋澶栭儴鍜屽唴閮ㄧ殑鐘舵佸緢闅懼垎娓呮椂錛屼笉瀹滈噰鐢╢lyweight妯″紡銆?/p>

  • 搴旂敤鎯呮櫙

銆銆涓嬮潰鐨勬儏鏅緢閫傚悎搴旂敤杞婚噺綰фā寮忥細

銆銆1. 緋葷粺闇瑕佸瓨鍦ㄥぇ閲忕殑瀵硅薄鑰屽叡浜煇浜涙湰璐ㄧ殑銆佷笉鍙樼殑淇℃伅銆?/p>

銆銆2. 瀵硅薄鍙互鍚屾椂鐢ㄤ簬澶氫釜鐜涓嬨?/p>

銆銆3. 鍦ㄦ瘡涓疄渚嬩笅錛宖lyweight鍙互浣滀負涓涓嫭绔嬬殑瀵硅薄銆?/p>

]]>
Three: Prototype Designhttp://www.tkk7.com/czihong/articles/390269.html鏄庡勾浠婃棩鏄庡勾浠婃棩Fri, 26 Oct 2012 06:30:00 GMThttp://www.tkk7.com/czihong/articles/390269.htmlhttp://www.tkk7.com/czihong/comments/390269.htmlhttp://www.tkk7.com/czihong/articles/390269.html#Feedback0http://www.tkk7.com/czihong/comments/commentRss/390269.htmlhttp://www.tkk7.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.


]]>
Two: Strategy patternhttp://www.tkk7.com/czihong/articles/381473.html鏄庡勾浠婃棩鏄庡勾浠婃棩Mon, 25 Jun 2012 21:31:00 GMThttp://www.tkk7.com/czihong/articles/381473.htmlhttp://www.tkk7.com/czihong/comments/381473.htmlhttp://www.tkk7.com/czihong/articles/381473.html#Feedback0http://www.tkk7.com/czihong/comments/commentRss/381473.htmlhttp://www.tkk7.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.

 



]]>
One: Decorator patternhttp://www.tkk7.com/czihong/articles/381472.html鏄庡勾浠婃棩鏄庡勾浠婃棩Mon, 25 Jun 2012 21:30:00 GMThttp://www.tkk7.com/czihong/articles/381472.htmlhttp://www.tkk7.com/czihong/comments/381472.htmlhttp://www.tkk7.com/czihong/articles/381472.html#Feedback0http://www.tkk7.com/czihong/comments/commentRss/381472.htmlhttp://www.tkk7.com/czihong/services/trackbacks/381472.html闃呰鍏ㄦ枃

]]>
主站蜘蛛池模板: 亚洲国产天堂在线观看| 你懂得的在线观看免费视频| 亚洲乱码无码永久不卡在线| 成人黄动漫画免费网站视频 | 一级毛片aaaaaa视频免费看| 亚洲av无码一区二区三区天堂古代| 伊人久久大香线蕉亚洲| 色吊丝最新永久免费观看网站 | 亚洲av午夜福利精品一区人妖| 免费人成年轻人电影| 在线视频观看免费视频18| 国产麻豆一精品一AV一免费| 一区二区三区视频免费| 亚洲aⅴ无码专区在线观看春色| 亚洲一区二区三区在线网站| 亚洲色偷偷偷网站色偷一区| 亚洲AV福利天堂一区二区三 | 你好老叔电影观看免费| 视频免费1区二区三区| 久久精品国产亚洲av品善| 亚洲熟妇无码八V在线播放| 亚洲人成综合在线播放| 亚洲资源在线视频| 久久精品国产亚洲av麻豆小说| 亚洲国产一成人久久精品| 4338×亚洲全国最大色成网站| 国产成人免费手机在线观看视频 | 国产成人精品日本亚洲11| 亚洲人成在线中文字幕| 亚洲嫩草影院在线观看| 亚洲精品在线不卡| 亚洲国产成人在线视频| 亚洲一级黄色大片| 亚洲H在线播放在线观看H| ww亚洲ww在线观看国产| 一本色道久久88亚洲精品综合 | 免费看国产精品麻豆| 亚洲 国产 图片| 国产国拍亚洲精品福利| 亚洲韩国精品无码一区二区三区 | 中文字幕的电影免费网站|