HelloWorld 善戰(zhàn)者,求之于勢,不責于人;故能擇人而任勢。

          知止而后有定,定而后能靜,靜而后能安,安而后能慮,慮而后能得。物有本末,事有終始。知所先后,則近道矣。

            BlogJava :: 首頁 ::  :: 聯(lián)系 ::  :: 管理 ::
            167 隨筆 :: 1 文章 :: 40 評論 :: 0 Trackbacks

          以下為java抽象工廠模式的一個例子,都是個人的一點想法,有什么不足的地方,懇求大家予以指出,歡迎討論

          我們使用的界面上有

          文本 {Linux文本,Windows文本}

          標簽 {Linux標簽,Windows標簽}

          等等.

          第一部分 抽象工廠的實現(xiàn)

          interface 文本 {}

          interface 標簽 {}

          class Linux文本 implements 文本{

               public String toString() {

                   return "Linux文本";

               }

          }

          class Linux標簽 implements 標簽{

               public String toString() {

                   return "Linux標簽";

               }

          }

          class Windows文本 implements 文本{

               public String toString() {

                   return "Windows文本";

               }

          }

          class Windows標簽 implements 標簽{

               public String toString() {

                   return "Windows標簽";

               }

          }

          interface 組件工廠 {

               public 文本 生產(chǎn)文本組件();

               public 標簽 生產(chǎn)標簽組件();

          }

          class Linux組件工廠 implements 組件工廠 {    

               public 文本 生產(chǎn)文本組件() {

                   return new Linux文本();

               }

               public 標簽 生產(chǎn)標簽組件() {

                   return new Linux標簽();

               }

             

          }

          class Windows標簽組件工廠 implements 組件工廠 {    

               public 文本 生產(chǎn)文本組件() {

                   return new Windows文本();

               }

               public 標簽 生產(chǎn)標簽組件() {

                   return new Windows標簽();

               }

             

          }

          class 客戶系統(tǒng)顯示 {

               private 文本 text;

               private 標簽 label;

               public static void main(String args[]) {

                   客戶系統(tǒng)顯示 clientOS = new 客戶系統(tǒng)顯示();

                   組件工廠 factory = new Linux組件工廠();

                   clientOS.label = factory.生產(chǎn)標簽組件();

                   clientOS.text = factory.生產(chǎn)文本組件();    

                   System.out.println(clientOS.label);

                   System.out.println(clientOS.text);

               }

          }

          如果按照上面的標準,我們要添加一個新的組件 下拉框

          A.需要修改的地方有

          1.組件工廠

          2.Linux組件工廠

          3.Windows標簽組件工廠

          B.需要增加的有

          1.interface 下拉框 {}

          2.class Linux下拉框 implements 下拉框

          3.class Windows下拉框 implements 下拉框

          C.調(diào)用的地方也會多出一個factory.生產(chǎn)下拉框組件();    

          第二部分 改革抽象工廠

          有沒有覺得要改動的地方有點多呢,下面我們來改革一下

          1.把 組件工廠中的

          生產(chǎn)文本組件();

          生產(chǎn)標簽組件();

          ...

          都改為

          生產(chǎn)組件(組件標識);

          這樣帶來的好處就是前面提到的,以下的修改就免去了

          /**************************/

          ......

          A.需要修改的地方有

          1.組件工廠

          2.Linux組件工廠

          3.Windows標簽組件工廠

          ......

          /**************************/

          要做到上面的,需要做以下幾件事情

          1.增加一個Annotation來說明后面增加的 組件注冊表

          @interface 組件描述 {

               Class 組件類();

             

          }

          2.增加一個Enum

          enum 組件注冊表 {

               /**

                * Linux_文本 的對應(yīng)實體類為 Linux文本

                */

               @組件描述(組件類 = Linux文本.class)

               Linux_文本,

             

               @組件描述(組件類 = Linux標簽.class)

               Linux_標簽,

             

               @組件描述(組件類 = Windows文本.class)

               Windows_文本,

             

               @組件描述(組件類 = Windows標簽.class)

               Windows_標簽,

          }

          3.我們不再需要

          interface 組件工廠,class Windows標簽組件工廠,class Linux組件工廠

          我們把 接口 組件工廠改為實體類

          為了保持可以擴展和維護

          我們定義了一個 接口 工廠

          interface 工廠 {

          }

          class 組件工廠 implements 工廠 {

               public 組件 生產(chǎn)組件(組件注冊表 ID) throws Exception {

                   try {

                       Field f = 組件注冊表.class.getField(ID.toString());

                       組件描述 描述 = f.getAnnotation(組件描述.class);

                       Class 組件類 = 描述.組件類();

                       return (組件) 組件類.newInstance();

                       // 注意,組件類.newInstance();的調(diào)用的時候要確保這個組件類有個不帶參數(shù)的構(gòu)造函數(shù)

                       // 如果要使用帶參數(shù)的構(gòu)造函數(shù),可以在@interface 組件描述 中增加一個成員

                       // 構(gòu)造函數(shù)[] 構(gòu)造函數(shù)參數(shù)() default{};

                       // @interface 構(gòu)造函數(shù) {Class[] 構(gòu)造函數(shù)的參數(shù)();}

                       // 通過 組件類.getConstructors(); 來得到這個類的不同構(gòu)造方法

                       // 這樣就可以根據(jù)用戶提供的信息用不同的構(gòu)造函數(shù)實例話對象

                       // 帶不同的構(gòu)造函數(shù),這里先不討論,后面我會給出代碼

                   } catch (Exception e) {

                       throw new Exception ("沒有找到對應(yīng)的組件");

                   }

               }

          }

          經(jīng)過上面的修改,代碼如下

          import java.lang.annotation.Retention;

          import java.lang.annotation.RetentionPolicy;

          import java.lang.reflect.Field;

          @Retention(RetentionPolicy.RUNTIME)

          @interface 組件描述 {

               Class 組件類();

             

          }

          enum 組件注冊表 {

               @組件描述(組件類 = Linux文本.class)

               Linux_文本,

             

               @組件描述(組件類 = Linux標簽.class)

               Linux_標簽,

             

               @組件描述(組件類 = Windows文本.class)

               Windows_文本,

             

               @組件描述(組件類 = Windows標簽.class)

               Windows_標簽,

          }

          interface 組件 {}

          interface 文本 extends 組件 {}

          interface 標簽 extends 組件 {}

          class Linux文本 implements 文本{

               public String toString() {

                   return "Linux文本";

               }

          }

          class Linux標簽 implements 標簽{

               public String toString() {

                   return "Linux標簽";

               }

          }

          class Windows文本 implements 文本{

               public String toString() {

                   return "Windows文本";

               }

          }

          class Windows標簽 implements 標簽{

               public String toString() {

                   return "Windows標簽";

               }

          }

          interface 工廠 {}

          class 組件工廠 implements 工廠{

               public 組件 生產(chǎn)組件(組件注冊表 ID) throws Exception {

                   try {

                       Field f = 組件注冊表.class.getField(ID.toString());

                       組件描述 描述 = f.getAnnotation(組件描述.class);

                       Class 組件類 = 描述.組件類();

                       return (組件) 組件類.newInstance();

                   } catch (Exception e) {

                       throw new Exception ("沒有找到對應(yīng)的組件");

                   }

               }

          }

          class 客戶系統(tǒng)顯示 {

               private 文本 text;

               private 標簽 label;

               public static void main(String args[]) {

                   客戶系統(tǒng)顯示 clientOS = new 客戶系統(tǒng)顯示();

                   組件工廠 factory = new 組件工廠();

                   try {

                       clientOS.text = (文本) factory.生產(chǎn)組件(組件注冊表.Linux_文本);

                       clientOS.label = (標簽) factory.生產(chǎn)組件(組件注冊表.Linux_標簽);

                   } catch (Exception e) {

                       e.printStackTrace();

                   }

                   System.out.println(clientOS.label);

                   System.out.println(clientOS.text);

               }

          }

          這個時候我們增加一個 下拉框

          需要改動的地方

          1.增加一個 interface 下拉框 extends 組件 {}

          2.增加2個實現(xiàn)類

          class Windows下拉框 implements 下拉框{}

          class Linux下拉框implements 下拉框{}

          3.組件注冊表 增加2個成員

          @組件描述(組件類 = Linux下拉框.class)

          Linux_下拉框,    

          @組件描述(組件類 = Windows下拉框.class)

          Windows_下拉框,

          和上面的比起來我們只需要在 組件注冊表中增加2個成員,而不需要去修改

          1.組件工廠

          2.Linux組件工廠

          3.Windows標簽組件工廠

          因為這里要修改3個地方,是不是覺得麻煩,反正我覺得麻煩了點

          還有一點就是用戶調(diào)用的時候不需要再使用factory.生產(chǎn)標簽組件();等方法,只要一個factory.生產(chǎn)組件就可以了,這樣符合簡單工廠的模式

          第三部分 帶參數(shù)的構(gòu)造函數(shù)代碼

          import java.lang.annotation.Annotation;

          import java.lang.annotation.Retention;

          import java.lang.annotation.RetentionPolicy;

          import java.lang.reflect.Constructor;

          import java.lang.reflect.Field;

          import java.util.ArrayList;

          import java.util.List;

          @Retention(RetentionPolicy.RUNTIME)

          @interface 構(gòu)造函數(shù) {

               /**

                * 構(gòu)造函數(shù)的參數(shù)類型

                * @return

                */

               Class[] 構(gòu)造函數(shù)的參數(shù)();

          }

          @Retention(RetentionPolicy.RUNTIME)

          @interface 組件描述 {

               Class 組件類();

             

               /**

                * 返回組件的構(gòu)造函數(shù) <br>

                * 如果長度為0,則調(diào)用沒有參數(shù)的構(gòu)造函數(shù) <br>

                * @return 構(gòu)造函數(shù)[]

                */

               構(gòu)造函數(shù)[] 構(gòu)造函數(shù)參數(shù)() default{};

             

          }

          enum 組件注冊表 {

               /**

                * Linux_文本 的對應(yīng)實體類為 Linux文本 <br>

                * Linux的構(gòu)造函數(shù)有 <br>

                * 1. Linux文本(String 顯示的文字) ; <br>

                * 2. Linux文本(String 顯示的文字, Integer 文本字體大小);

                */

               @組件描述(組件類 = Linux文本.class,

                       構(gòu)造函數(shù)參數(shù) = {@構(gòu)造函數(shù)(構(gòu)造函數(shù)的參數(shù)={String.class}) ,

                   @構(gòu)造函數(shù)(構(gòu)造函數(shù)的參數(shù)={String.class, Integer.class}) } )

               Linux_文本,

             

               @組件描述(組件類 = Linux標簽.class)

               Linux_標簽,

             

               @組件描述(組件類 = Windows文本.class)

               Windows_文本,

             

               @組件描述(組件類 = Windows標簽.class)

               Windows_標簽,

          }

          interface 組件 {}

          interface 文本 extends 組件 {}

          interface 標簽 extends 組件 {}

          class Linux文本 implements 文本{

               private String text;

               private Integer size;

               public Linux文本(String text) {

                   this.text = text;

               }

               public Linux文本(String text, Integer size) {

                   this.text = text;

                   this.size = size;

               }

               public String toString() {

                   return "Linux文本" + (text == null ? "":",文本內(nèi)容為:"+text) + (size == null ? "":",文本字體大小為:"+size);

               }

          }

          class Linux標簽 implements 標簽{

               public String toString() {

                   return "Linux標簽";

               }

          }

          class Windows文本 implements 文本{

               public String toString() {

                   return "Windows文本";

               }

          }

          class Windows標簽 implements 標簽{

               public String toString() {

                   return "Windows標簽";

               }

          }

          interface 工廠 {}

          class 組件工廠 implements 工廠{

               public 組件 生產(chǎn)組件(組件注冊表 ID, Object[] 參數(shù)) throws Exception {

                   try {

                       Field f = 組件注冊表.class.getField(ID.toString());

                       組件描述 描述 = f.getAnnotation(組件描述.class);

                       Class 組件類 = 描述.組件類();

                       構(gòu)造函數(shù)[] ano = 描述.構(gòu)造函數(shù)參數(shù)();

                       if (參數(shù) != null) {

                           for (int i = 0; i < ano.length; i++) {

                               構(gòu)造函數(shù) temp = ano;

                               Class[] 構(gòu)造函數(shù)S = temp.構(gòu)造函數(shù)的參數(shù)();                    

                               if (參數(shù).length == 構(gòu)造函數(shù)S.length) {

                                   for (int j = 0; j < 參數(shù).length; j++) {

                                       if (參數(shù)[j].getClass().toString().equals(構(gòu)造函數(shù)S[j].toString())) {

                                           if ( j == 參數(shù).length - 1) {

                                               Constructor cons = 組件類.getConstructor(構(gòu)造函數(shù)S);

                                               return (組件) cons.newInstance(參數(shù));

                                           }

                                       } else break;

                                   }

                               }

                               continue;

                           }

                           throw new Exception ("沒有找到對應(yīng)的組件");

                       } else

                           return (組件) 組件類.newInstance();

                   } catch (Exception e) {

                       e.printStackTrace();

                       throw new Exception ("沒有找到對應(yīng)的組件");

                   }

               }

          }

          class 客戶系統(tǒng)顯示 {

               private 文本 text;

               private 標簽 label;

               public static void main(String args[]) {

                   客戶系統(tǒng)顯示 clientOS = new 客戶系統(tǒng)顯示();

                   組件工廠 factory = new 組件工廠();

                   try {

                       Object [] params = {"初始化文本", new Integer(20)};

                       clientOS.text = (文本) factory.生產(chǎn)組件(組件注冊表.Linux_文本,params);

                       clientOS.label = (標簽) factory.生產(chǎn)組件(組件注冊表.Linux_標簽,null);

                       System.out.println(clientOS.label);

                       System.out.println(clientOS.text);

                       Object [] params2 = {"初始化"};

                       clientOS.text = (文本) factory.生產(chǎn)組件(組件注冊表.Linux_文本,params2);

                       System.out.println(clientOS.text);

                   } catch (Exception e) {

                       e.printStackTrace();

                   }

               }

          }



          </script>

          posted on 2007-08-13 18:57 helloworld2008 閱讀(713) 評論(0)  編輯  收藏 所屬分類: java - 模式
          主站蜘蛛池模板: 广昌县| 信阳市| 上思县| 余姚市| 秭归县| 晋城| 乌审旗| 商都县| 安西县| 六盘水市| 浏阳市| 南京市| 汝阳县| 五河县| 和田县| 新蔡县| 克东县| 长寿区| 石楼县| 安丘市| 乌恰县| 卫辉市| 炉霍县| 平定县| 杭州市| 琼海市| 北京市| 苏尼特右旗| 宁夏| 抚顺市| 谷城县| 博兴县| 漯河市| 宁陵县| 赣州市| 扶沟县| 普陀区| 饶阳县| 那曲县| 万载县| 元氏县|