设计模式之_Strategy_04
生活随笔
收集整理的這篇文章主要介紹了
设计模式之_Strategy_04
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
package com.learn.stratege;/*** 現在你可以發現我這類更爽了,對于int類型排序,還可以對Cat類型排序* 你自己有點飄飄然,瞧我組織的多么的好,但是我現在要求你你能不能對Dog類型進行排序* 加入我又有一個類叫Dog,能不能對Dog類型進行排序,當然你會說你要告訴我Dog類型怎么判大怎么判小* 我就 會給你添加新的方法進去,拜托你累不累啊,如果我未來需要你對Car類型進行排序,加入我要求一個更過分的,* 我要求你DataSorter這類的算法能夠重用,能夠對任何對象的數組進行排序,這個時候你該怎么辦* 你該怎么去封裝他,當然有人可能會想到,這個還不簡單* * 你會發現DataSorter這個類竟然具備這種能力,* * * @author Leon.Sun**/
public class DataSorter {/*** 我這里面不能夠簡簡單單的要求他就是一個Cat,就是一個Dog,我就要求它是一個Object類型的數組就可以了* 然后任何類型的數組就可以往里裝了,起碼我確定了排序的接口了,當然有一點可能沒有想到,* 但是當我們把算法復制過來之后,算法就要重復使用了,我到底怎么去判斷a數組里面那些個對象到底誰大誰小* 這時候就麻煩了,有的人說了既然這是Object類型,我就查查Object這個類里面有沒有方法直接調用的* 你可以去查,他沒有,所以現在問題就歸結到這里了,我們去判斷Object類型的數組里面的對象到底誰大誰小,* * 能對狗的數組進行排序,還能對貓的數組進行排序,但是我們要知道怎么樣才算大怎么樣才算小* 有的人說我就根據height,根據weight來比較,這不好,你說我規定好了之后人家定義貓定義狗* 的時候就必須這么寫了,假如以后我想根據貓的尾巴的長度你的算法還是要接著改,所以這么寫還是不行,* 既然比較大小的方式,現在不是能確定的,干脆就交給他的子類去確定,將來去擴展好了,* 一定有多態存在,咱們說Cat和Dog是能夠去比較大小的,通過這句話你能夠想到一個接口* * 我們在這里寫算法的時候可以做一個假設,假設這個數組里的這些個對象,都應該去實現了Comparable的接口* * 當我把貓的數組作為Object傳進來的時候,我們假設他都是實現了Comparable接口的,* 所以比較大小的時候就可以這樣來做,首先把a[j]強制轉為Comparable接口,* 既然他是實現Comparable接口的,不管他是貓還是狗,他實現了Comparable接口就可以,* * 在Sort方法里面可以會認為你所有的數組對象都會去實現Comparable接口,* 所以我可以把數組里面的任何一個對象轉換為Comparable接口類型的對象* 既然你實現了Comparable接口,當然可以去調用你CompareTo方法* 同時由于多態,你這里具體是什么對象,他就會去調用具體對象的compareTo的方法* 你這里都是貓的類型的對象,所以我們調用的都是貓的compareTo的方法* 因此o1和o2一比較,首先把貓 給轉換過來,判斷他們兩個的高度是不是相等,誰大誰小,然后來確定返回值* 最后都確定了兩只貓誰大誰小,既然確定了兩只貓誰大誰小了,我們整個算法就實現重用了* 這個算法和原來int類型的算法是一樣,直接拿來作用就行了,* 如果說你想對狗進行排序,我相信你能想到了* * 它的算法寫了一次之后,他這一輩子都不需要再變了,而且他可以對于任意的一個類型進行排序* 這個可擴展性是不是好多了,不過他要求一點,能夠實現排序的這些個類,必須去實現Comparable接口* 講到這里應知道Comparable接口是干嘛的了,第一是定義這個類是不是能夠比較大小,* 第二是為了我們寫的一些算法能夠得到重復使用,不用說有一種新的類型我就要寫一個新的sort方法,* * 我們來看API文檔,在java.lang里面,他有一個Comparable接口,* 在這個Comparable接口里面,他又一個compareTo方法,返回值就是一個int類型* 實際上和我們寫的一模一樣,當然這里的Comparable<T>接口使用了泛型,* 如果你看不懂,你就把T當做Object來看待就行了,所以我們就模擬了一下JDK提供的Comparable接口* 他背后的原理是一樣的* * @param a*/public static void sort(Object[] a) {for(int i=a.length;i>0;i--) {for(int j=0;j<i-1;j++) {Comparable o1 = (Comparable)a[j];Comparable o2 = (Comparable)a[j+1];/*** 這個時候我們比較他們兩個的大小,既然這兩個對象都實現了Comaparable接口* 如果等于1或者大于0,這個時候我就任務o1比o2大,*/if((o1.compareTo(o2))==1) {swap(a,j,j+1);}}}}private static void swap(Object[] a, int x, int y) {/*** 我就把它寫成Obect類型而不是Cat類型*/Object temp = a[x];a[x] = a[y];a[y] = temp;}public static void sort(int[] a) {for(int i=0;i<a.length;i--) {for(int j=0;j<i-1;j++) {if(a[j]>a[j+1]) {swap(a,j,j+1);}}}}private static void swap(int[] a, int x, int y) {int temp = a[x];a[x] = a[y];a[y] = temp;}public static void p(int[] a) {for(int i=0;i<a.length;i++) {System.out.print(a[i] + " ");}System.out.println();}/*** 把輸出貓的改成可以輸出任何類型* @param a*/public void p(Object[] a) {for(int i=0;i<a.length;i++) {System.out.print(a[i] + " ");}System.out.println();}}
package com.learn.stratege;/*** 讓他去實現Comparable接口,** 只要你寫了一個狗的類,去實現了Comparable接口,* 你就可以用原來已經寫好了的類對狗進行排序了,這個算法就可以對任何的對象進行排序了* @author Leon.Sun**/
public class Dog implements Comparable {public Dog() {super();}public Dog(int food) {super();this.food = food;}/*** 根據飯量來,吃的越多,他就越大*/private int food;public int getFood() {return food;}public void setFood(int food) {this.food = food;}/*** 同時為了輸出這只狗比較方便,我們重寫toString方法*/@Overridepublic String toString() {return "Dog [food=" + food + "]";}/*** 實現這個方法,*/@Overridepublic int compareTo(Object o) {/*** 我們把o強制轉換為Dog*/Dog d = (Dog)o;/*** 然后來判斷*/if(this.food>d.getFood()) {return 1;}else if(this.food<d.getFood()) {return -1;}else {return 0;}}}
package com.learn.stratege;/*** 這里并不是JDK的Comparable* 可比較大小的一個接口,里面可以定義什么樣的方法,* * @author Leon.Sun**/
public interface Comparable {/*** 我這個接口不能直接寫Cat,Dog,我只能寫和另一個Object比較大小* 下面我要確定返回值是什么,如果是void你是得不到是什么結果的* 所以這個返回值要給我反饋一下對象比較的結果,所以我定義一個int類型* 如果實現了這個類的對象,去和另一個對象做比較的時候,返回值如果大于0的,* 表示和別人做比較的對象大,否則是被比較的對象大,如果等于0就表示兩個對象相等的邏輯* */public int compareTo(Object o);}
package com.learn.stratege;/*** Cat類型是可以去比較大小的,既然你實現了Comparable接口* 他就應該去實現compareTo這個方法* * 現在是這樣一種關系,Cat實現了Comparable接口,* 這樣的話它就可以和Cat比較大小了,既然他能夠比較大小了,* * @author Leon.Sun**/
public class Cat implements Comparable {private int height;private int weight;public Cat() {super();}public Cat(int height, int weight) {super();this.height = height;this.weight = weight;}public int getHeight() {return height;}public void setHeight(int height) {this.height = height;}public int getWeight() {return weight;}public void setWeight(int weight) {this.weight = weight;}/*** 表示我這個方法是重寫的,如果你不理解,就簡單這么理解,當我需要打印一只貓的時候,* 會調用貓的toString方法,*/@Overridepublic String toString() {return "Cat [height=" + height + ", weight=" + weight + "]";}/*** 現在我寫一個典型的實現,雖然現在定義的是和Object比較大小* 但是作為一只貓來講,我和其他類型比較大小沒有意義,所以假設實際類型是一只貓* */@Overridepublic int compareTo(Object o) {/*** 如果o是一只貓*/if(o instanceof Cat) {/*** 強制轉換*/Cat c = (Cat)o;/*** 如果我的高度大于你傳給我的高度* 也就是this我比你大,*/if(this.getHeight()>c.getHeight()) {return 1;}else if(this.getHeight()<c.getHeight()) {/*** 如果當前這只貓比你傳給我的這只貓小*/return -1;}else {/*** 其他情況表示我們兩一樣大*/return 0;}}else {/*** 如果o本身就不是一只貓,實際情況你要去拋異常,咱們不是一回事* 嚴格來講你是要來拋異常的,不過我們在這里為了簡單起見,* 我就不這么寫了,我就return -100,表示出錯了* 這是我簡單的寫法,實際中是要拋異常的,到時我們看一下JDK接口的寫法就明白了*/return -100;}}}
package com.learn.stratege;/*** 你可以發現他已經排好順序了* @author Leon.Sun**/
public class Test {public static void main(String[] args) {DataSorter dataSorter = new DataSorter(); /*** 順序是怎么排的,當你new出三只貓出來的時候,我們把貓交給Sort方法,*/Cat[] a = {new Cat(8,8),new Cat(2,2),new Cat(1,1)};dataSorter.sort(a);dataSorter.p(a);Dog[] d = {new Dog(6),new Dog(4),new Dog(2)};dataSorter.sort(d);dataSorter.p(d);}
}
?
總結
以上是生活随笔為你收集整理的设计模式之_Strategy_04的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 设计模式之_Strategy_03
- 下一篇: 设计模式之_Strategy_05