HelloWorld 善戰者,求之于勢,不責于人;故能擇人而任勢。

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

            BlogJava :: 首頁 ::  :: 聯系 ::  :: 管理 ::
            167 隨筆 :: 1 文章 :: 40 評論 :: 0 Trackbacks

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

          我們使用的界面上有

          文本 {Linux文本,Windows文本}

          標簽 {Linux標簽,Windows標簽}

          等等.

          第一部分 抽象工廠的實現

          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 文本 生產文本組件();

               public 標簽 生產標簽組件();

          }

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

               public 文本 生產文本組件() {

                   return new Linux文本();

               }

               public 標簽 生產標簽組件() {

                   return new Linux標簽();

               }

             

          }

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

               public 文本 生產文本組件() {

                   return new Windows文本();

               }

               public 標簽 生產標簽組件() {

                   return new Windows標簽();

               }

             

          }

          class 客戶系統顯示 {

               private 文本 text;

               private 標簽 label;

               public static void main(String args[]) {

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

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

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

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

                   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.調用的地方也會多出一個factory.生產下拉框組件();    

          第二部分 改革抽象工廠

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

          1.把 組件工廠中的

          生產文本組件();

          生產標簽組件();

          ...

          都改為

          生產組件(組件標識);

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

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

          ......

          A.需要修改的地方有

          1.組件工廠

          2.Linux組件工廠

          3.Windows標簽組件工廠

          ......

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

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

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

          @interface 組件描述 {

               Class 組件類();

             

          }

          2.增加一個Enum

          enum 組件注冊表 {

               /**

                * Linux_文本 的對應實體類為 Linux文本

                */

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

               Linux_文本,

             

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

               Linux_標簽,

             

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

               Windows_文本,

             

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

               Windows_標簽,

          }

          3.我們不再需要

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

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

          為了保持可以擴展和維護

          我們定義了一個 接口 工廠

          interface 工廠 {

          }

          class 組件工廠 implements 工廠 {

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

                   try {

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

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

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

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

                       // 注意,組件類.newInstance();的調用的時候要確保這個組件類有個不帶參數的構造函數

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

                       // 構造函數[] 構造函數參數() default{};

                       // @interface 構造函數 {Class[] 構造函數的參數();}

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

                       // 這樣就可以根據用戶提供的信息用不同的構造函數實例話對象

                       // 帶不同的構造函數,這里先不討論,后面我會給出代碼

                   } catch (Exception e) {

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

                   }

               }

          }

          經過上面的修改,代碼如下

          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 組件 生產組件(組件注冊表 ID) throws Exception {

                   try {

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

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

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

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

                   } catch (Exception e) {

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

                   }

               }

          }

          class 客戶系統顯示 {

               private 文本 text;

               private 標簽 label;

               public static void main(String args[]) {

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

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

                   try {

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

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

                   } catch (Exception e) {

                       e.printStackTrace();

                   }

                   System.out.println(clientOS.label);

                   System.out.println(clientOS.text);

               }

          }

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

          需要改動的地方

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

          2.增加2個實現類

          class Windows下拉框 implements 下拉框{}

          class Linux下拉框implements 下拉框{}

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

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

          Linux_下拉框,    

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

          Windows_下拉框,

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

          1.組件工廠

          2.Linux組件工廠

          3.Windows標簽組件工廠

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

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

          第三部分 帶參數的構造函數代碼

          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 構造函數 {

               /**

                * 構造函數的參數類型

                * @return

                */

               Class[] 構造函數的參數();

          }

          @Retention(RetentionPolicy.RUNTIME)

          @interface 組件描述 {

               Class 組件類();

             

               /**

                * 返回組件的構造函數 <br>

                * 如果長度為0,則調用沒有參數的構造函數 <br>

                * @return 構造函數[]

                */

               構造函數[] 構造函數參數() default{};

             

          }

          enum 組件注冊表 {

               /**

                * Linux_文本 的對應實體類為 Linux文本 <br>

                * Linux的構造函數有 <br>

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

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

                */

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

                       構造函數參數 = {@構造函數(構造函數的參數={String.class}) ,

                   @構造函數(構造函數的參數={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 ? "":",文本內容為:"+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 組件 生產組件(組件注冊表 ID, Object[] 參數) throws Exception {

                   try {

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

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

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

                       構造函數[] ano = 描述.構造函數參數();

                       if (參數 != null) {

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

                               構造函數 temp = ano;

                               Class[] 構造函數S = temp.構造函數的參數();                    

                               if (參數.length == 構造函數S.length) {

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

                                       if (參數[j].getClass().toString().equals(構造函數S[j].toString())) {

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

                                               Constructor cons = 組件類.getConstructor(構造函數S);

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

                                           }

                                       } else break;

                                   }

                               }

                               continue;

                           }

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

                       } else

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

                   } catch (Exception e) {

                       e.printStackTrace();

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

                   }

               }

          }

          class 客戶系統顯示 {

               private 文本 text;

               private 標簽 label;

               public static void main(String args[]) {

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

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

                   try {

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

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

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

                       System.out.println(clientOS.label);

                       System.out.println(clientOS.text);

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

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

                       System.out.println(clientOS.text);

                   } catch (Exception e) {

                       e.printStackTrace();

                   }

               }

          }



          </script>

          posted on 2007-08-13 18:57 helloworld2008 閱讀(713) 評論(0)  編輯  收藏 所屬分類: java - 模式
          主站蜘蛛池模板: 四子王旗| 浪卡子县| 临高县| 石林| 黄冈市| 平安县| 乌拉特前旗| 内江市| 德令哈市| 育儿| 三穗县| 惠来县| 利辛县| 迁安市| 永靖县| 余干县| 赞皇县| 南召县| 莱西市| 蒙自县| 法库县| 简阳市| 阜阳市| 贵阳市| 曲周县| 泸定县| 洛南县| 郧西县| 南木林县| 铁岭市| 安达市| 庆云县| 巴东县| 渝中区| 昌宁县| 贵阳市| 枣阳市| 四平市| 赤峰市| 同心县| 孝昌县|