JWorld@TW the best professional Java site in Taiwan
      註冊 | 登入 | 全文檢索 | 排行榜  

» JWorld@TW » Software Design » Effective Java  

按列印兼容模式列印這個話題 列印話題    把這個話題寄給朋友 寄給朋友    訂閱主題
reply to topicthreaded modego to previous topicgo to next topic
話題被移動
該話題已被移動 - morchory , 2003-10-03 01:40
如果您尚不清楚該話題被移動的原因,請參考論壇規則以及本版公告或者聯系本版版主。
本主題所含的標籤
無標籤
作者 [Effective Java] 條款1 : 考慮以 "static factory methods" 取代建構式 [精華]
metavige

麥塔.米奇

版主

發文: 2133
積分: 10
於 2003-10-01 14:51 user profilesend a private message to usersend email to metavigereply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
既然是我貼的
那我就先 POST 一些啦

在這個條款裡面
主要是在比較 建構式static factory methods 的優缺點

基本上
static factory methods 方面

因為具有可命名性, 所以可以使 classes 較容易被使用, 而且也可以使得程式碼較易閱讀
因為建構式的主要區別, 只是在參數型別、參數個數、以及參數排列的方式不同
來區分各個不同的建構式
對後來的使用者而言, 較不容易做維護的動作, 也容易發生錯誤的呼叫

而另外也可以在 static factory methods 裡面採取 cache 的機制
或者是能夠確保實體物件的產生控制, 比如說像是 singleton

另外書裡面有提到所謂的可以選擇傳回一個「隸屬於函式回返值型別之任何子型別」
可以在「選擇回返物件之型別」這件事情上面有比較大的彈性
這部分我就比較不太清楚, 可能要請各位替我解釋一下
他舉的例子就是 java.util.Collections 的部分
我想是在說可以在 static factory methods 裡面去選擇要傳回的型別

當然
缺點也是有的啦
因為 public or protected 建構式被取代了, 所以就大概不會有 subclasses 啦

還有就是有關於 static factory methods 的命名習慣
因為在 API 文件裡面是跟一般的 methods 在一起
所以可能就不容易像建構式一樣容易區分

然後最後
其實書裡面是提到說
如果這兩者之間, 並沒有那一方是有比較明顯的優勢時
那建議還是採用建構式, 因為這是語言的規範嘛

其實這部分我大概比較不容易理解的大概就是「隸屬於函式回返值型別之任何子型別」這部分了
這部分在書裡面還有提到 service provider framework
還有 Java Cryptography Extension (JCE)
呼∼ 有點深度

-------------------------------------------------------------------------
第一次貼 Tip, 請各位多多指教


metavige edited on 2004-04-23 14:52
reply to postreply to post
請各位新手參考 論壇規範Java 新手 FAQ
作者 Re:[Effective Java] 條款1 : 考慮以 "static factory methods" 取代建構式 [Re:metavige]
ymshin





發文: 277
積分: 4
於 2003-10-01 15:46 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
會不會是指 parent & child 的繼承關係呢? 先 create 一個 parent class reference, 到 runtime 時再視情況 initiate object instance.

reply to postreply to post
作者 Re:[Effective Java] 條款1 : 考慮以 "static factory methods" 取代建構式 [Re:ymshin]
metavige

麥塔.米奇

版主

發文: 2133
積分: 10
於 2003-10-01 16:03 user profilesend a private message to usersend email to metavigereply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public class testFactoryMethod {
  
  public static testFactoryMethod getInstance() {
    return new testFactoryMethodSubClass();
  }
  
  public String toString() {
    return "testFactoryMethod";
  }  
 
  public static void main(String[] args) {
    testFactoryMethod obj = testFactoryMethod.getInstance();
    System.out.println(obj);
  }
}
 
class testFactoryMethodSubClass extends testFactoryMethod {
  public String toString() {
    return "testFactoryMethodSubClass";
  }  
}


結果:
1
testFactoryMethodSubClass


我想大概是這個意思吧


reply to postreply to post
請各位新手參考 論壇規範Java 新手 FAQ
作者 Re:[Effective Java] 條款1 : 考慮以 "static factory methods" 取代建構式 [Re:metavige]
ymshin





發文: 277
積分: 4
於 2003-10-01 16:26 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
好像不太對, 舉例的這種結果是 overriding, 我想 getInstance() 才是癥結, 可是這裡看不太出來~~~ @@

有其他想法嗎?


reply to postreply to post
作者 Re:[Effective Java] 條款1 : 考慮以 "static factory methods" 取代建構式 [Re:metavige]
ingramchen

Web monkey



發文: 479
積分: 12
於 2003-10-01 18:48 user profilesend a private message to usersend email to ingramchenreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
原文是:

A third advantage of static factory methods is that, unlike constructors,
they can return an object of any subtype of their return type.

這樣比較好懂吧?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
public abstract Shape class {
      
      public static int SQUARE = 1 ;
      public static int CIRCLE = 2 ;
      public static int TRIANGLE = 3 ;
 
      public static Shape ShapeFactory(int shapeType) {
            switch(shapeType) {
                 case SQUARE:
                       return new Square() ;
                 case CIRCLE:
                       return new Circle();
                 case TRIANGLE:
                       return new Triangle();
                 default:
                       throw new ShapeCreateException("wrong shape definition") ; 
            }
      }
      public abstract void draw() ;
}
 
class Square extends Shape{
    public void draw() {
       // implement square
   }
}
 
class Circle extends Shape {
    public void draw() {
       // implement circle
    }
}
 
class Triangle extends Shape {
    public void draw() {
    // implement triangle
    }
}
 

<This line is eaten...........>

you client program:

1
2
3
4
5
6
7
public class Client {
     public void doSomething() {
        // client 的程式界面一致,新增 shape 不用 new 新的 class
        Shape s = Shape.ShapeFactory(Shape.SQUARE) ;
        s.draw() ; 
     }
}


使用上 ShapeFactory() 雖然是在父類別 Shape,但回傳的可以是他的子
類別,這樣是可以簡化使用者的介面,只要去學會操作 ShapeFactory 就
行了。若再配合多型 ( 上例的 draw() ),那未來程式增加新的子類別,
程式幾乎不用修改。


ingramchen edited on 2003-10-01 19:04
reply to postreply to post
作者 Re:[Effective Java] 條款1 : 考慮以 "static factory methods" 取代建構式 [Re:metavige]
Duncan

還隱隱作痛

版主

發文: 7816
積分: 39
於 2003-10-01 22:10 user profilesend a private message to usersend email to Duncanreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
metavige wrote:
當然
缺點也是有的啦
因為 public or protected 建構式被取代了, 所以就大概不會有 subclasses 啦


被取代了?使用了 static factory method 就可以不要有 public constructor,但是還是一定有 constructor(maybe private/protected/package)不然怎麼建構物件來傳回?只要留有一個 non-private constructor 還是可以擴充的,這應該不是缺陷吧。

看看 core classes API,使用 static factory method 的多是 abstract class,一定有 subclass(不然 factory method 傳回的物件哪裡來),如果沒有 subclass 反而讓 static factory method 的使用又失去了一項優勢。


reply to postreply to post

給我
辣味豆腐 其餘免談
作者 Re:[Effective Java] 條款1 : 考慮以 "static factory methods" 取代建構式 [Re:ingramchen]
metavige

麥塔.米奇

版主

發文: 2133
積分: 10
於 2003-10-01 22:34 user profilesend a private message to usersend email to metavigereply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
ingramchen wrote:
原文是:

A third advantage of static factory methods is that, unlike constructors,
they can return an object of any subtype of their return type.

這樣比較好懂吧?




我是節錄啦
因為這部分有一大段在說明
我也不好意思都放上來
不過
您放的這部分的確是比較好懂
尤其是有程式碼
謝啦


reply to postreply to post
請各位新手參考 論壇規範Java 新手 FAQ
作者 Re:[Effective Java] 條款1 : 考慮以 "static factory methods" 取代建構式 [Re:metavige]
ymshin





發文: 277
積分: 4
於 2003-10-01 22:47 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
嗯, 他放的 code 是清楚多了, 和我說的一樣嘛~ 先前倒沒仔細看缺點敘述部分, 幸好 Duncan 幫 metavige 抓出問題來, 不然誤會大了. ^^

reply to postreply to post
作者 Re:[Effective Java] 條款1 : 考慮以 "static factory methods" 取代建構式 [Re:metavige]
wctang





發文: 7
積分: 0
於 2003-10-02 13:38 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
如果用 reflection 來做的話,就可以更增動態性了…
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
abstract class TestInterface {
    public static TestInterface getRealObject(String subclass) {
        try {
            Class sub = Class.forName(subclass);
            return (TestInterface)sub.newInstance();
        } catch ( Exception e) {
            return null;
        }
    }
    public abstract void show();
}
 
class TestSub1 extends TestInterface {
    public void show() {
        System.out.println("TestSub1");
    }
}
 
class TestSub2 extends TestInterface {
    public void show() {
        System.out.println("TestSub2");
    }
}
 
public class TestMain {
    public static void main( String[] args) {
        TestInterface.getRealObject("TestSub2").show();
        TestInterface.getRealObject("TestSub1").show();
    }
}


reply to postreply to post
作者 Re:[Effective Java] 條款1 : 考慮以 "static factory methods" 取代建構式 [Re:wctang]
iampoya

Speculator

版主

發文: 169
積分: 8
於 2003-10-02 14:57 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
wctang wrote:
如果用 reflection 來做的話,就可以更增動態性了…

不過用了reflection就少了一次compile time的驗證機會
也會造成日後程式碼不易閱讀及除錯上的困難


reply to postreply to post
Japan Adult Video Album
作者 Re:[Effective Java] 條款1 : 考慮以 "static factory methods" 取代建構式 [Re:iampoya]
wctang





發文: 7
積分: 0
於 2003-10-02 16:08 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
iampoya wrote:
不過用了reflection就少了一次compile time的驗證機會
也會造成日後程式碼不易閱讀及除錯上的困難

嗯…
以現在所討論的情況下, compile time 的驗證應該沒有幫助的。
要能動態選擇 subclass 的 instance,應是 runtime 才能知道型別的。就算用 int 來選擇,也沒辦法 compile time check 的。當然,用 String 當參數是比較方便,也比較能用在設定的情況。應該也可以直接傳 class 型別進去的(吧?)。
這個 pattern 最強的情況是可以做到 plugin 的用途,就是主程式不用修改,而立刻可以用其他的 model 來加強或切換功能。而 Java 不需用 DLL 之類的東西就可以達成,又方便自然,是應該強調的能力。
而程式碼不易閱讀,多是源自於命名的問題(我覺得啦…)。當然, reflection 比較少人用也是原因。
以上我的看法 Smile 剛上站不久,請多指教。


reply to postreply to post
作者 Re:[Effective Java] 條款1 : 考慮以 "static factory methods" 取代建構式 [Re:wctang]
iampoya

Speculator

版主

發文: 169
積分: 8
於 2003-10-02 16:49 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
No No
就算是傳int也是可以check的
以上面ingramchen兄提供的程式為例n
基本上正常在撰碼時是不會真的傳一個int進去
而是會透過類別常數來產生所需的實體物件
像醬子:Shape.ShapeFactory(Shape.SQUARE);

所以其實很明確的可以在compile time就抓出問題
總不可能傳一個沒有的類別常數進去吧 :P

但是透過reflection哩
我傳坨屎進去,不到run time,搞不好也沒人發覺
以您提供的程式為例n像醬子:TestInterface.getRealObject("***").show();

至於除錯不易跟命名好壞與否我也覺得沒多大關係
原因很簡單,若是習慣用IDE工具來trace程式
碰到reflection就沒輒了
又得慢慢手工去尋找,到底是真有其屎,還是海市蜃屎

Welcome to the whole *** world !! Smile
--
JUTE有潔癖
屎打不出來…會被轉成*** Evil


iampoya edited on 2003-10-02 16:56
reply to postreply to post
Japan Adult Video Album
作者 Re:[Effective Java] 條款1 : 考慮以 "static factory methods" 取代建構式 [Re:wctang]
Duncan

還隱隱作痛

版主

發文: 7816
積分: 39
於 2003-10-02 17:43 user profilesend a private message to usersend email to Duncanreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
wctang wrote:
如果用 reflection 來做的話,就可以更增動態性了…
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
abstract class TestInterface {
    public static TestInterface getRealObject(String subclass) {
        try {
            Class sub = Class.forName(subclass);
            return (TestInterface)sub.newInstance();
        } catch ( Exception e) {
            return null;
        }
    }
    public abstract void show();
}
 
class TestSub1 extends TestInterface {
    public void show() {
        System.out.println("TestSub1");
    }
}
 
class TestSub2 extends TestInterface {
    public void show() {
        System.out.println("TestSub2");
    }
}
 
public class TestMain {
    public static void main( String[] args) {
        TestInterface.getRealObject("TestSub2").show();
        TestInterface.getRealObject("TestSub1").show();
    }
}



我覺得這樣子寫並沒有帶來太多好處,以某個角度看反而比 factory method 更是不好的作法。

因為這樣子的作法還是得指名道姓,這跟直接以 public constructor 一樣都是把類別名稱寫出來,你的作法彈性更小只能應付有 default constructor 的型別。而兩者同樣的缺點是,你會自然而然地讓建構物件的程式片段分散在各處,假如目前偕同作用的物件是一組的,當遇到需要替換成另一組時,你得翻遍所有的程式碼找出建構物件的部分,這就是為什麼要用 Abstract Factory,至少 Abstract Factory 可以縮小物件生產的範圍(集中在 factory 身上)抽換 factory 就可以整個換掉。

當然你也可以試著讓 TestInterface- getReadObject(static factory method)使用的地方侷限在某個範圍,但這樣子你的作法顯得沒有很必要,但的確是可以讓他的生產種類提到最大,不過就像 iampoya 提到的,有少了 compile-time type checking 的弊病。

我想 static factory method 本身就有一個缺點是不能避免的,那就是不容易擴充。一個 static factory method 會產出的物件決定了,似乎沒辦法在不修改程式碼的情況下得到另外不同 subclass 的 instance(如果不搭配其他的 pattern),你沒有辦法透過繼承機制來改變或擴充 static factory method 的產品(種類)。


reply to postreply to post

給我
辣味豆腐 其餘免談
作者 Re:[Effective Java] 條款1 : 考慮以 "static factory methods" 取代建構式 [Re:metavige]
wctang





發文: 7
積分: 0
於 2003-10-02 17:53 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
那下面的做法會不會比較好呢Smile 在 compiler time 擋住一些小 typo,我覺得和用類別常數沒什麼差別。重點是,可以使用未知型別。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
class NoTestException extends Exception {}
 
interface TestInterface {
    public void show();
}
 
class TestSub1 implements TestInterface {
    public void show() {
        System.out.println("TestSub1");
    }
}
 
class TestSub2 implements TestInterface {
    public void show() {
        System.out.println("TestSub2");
    }
}
 
class TestFactory {
    public static TestInterface getInstance(Class subclass) 
        throws NoTestException 
    {
        try {
            return (TestInterface)subclass.newInstance();
        } catch ( Exception e) {
            throw new NoTestException();
        }
    }
}
 
public class TestMain {
    public static void main( String[] args) {
        String subclassname = "TestSub2";
 
        Class sub = null;
        try {
            sub = Class.forName(subclassname);
        } catch (Exception e) {
            System.out.println("Not a valid Class");
            return;
        }
        
        try {
            TestFactory.getInstance(TestSub1.class).show();
            TestFactory.getInstance(sub).show();
        } catch (NoTestException e) {
            System.out.println("No Such Subclass");
        }
    }
}

必需是型別名稱才能傳入 TestFactory.getInstance,所以也不能隨便寫個東西就傳了,就算真的傳個其他的 type 進去,也可以用 exception 來擋住,而且如果用個有意義的 subclass name ,也可以讓程式容易理解。重點在於就算我沒有source,只要我知道 TestInterface ,就可以自已寫個 TestSub3 傳進去,就可以和原本的程式配合了。當然,這裡的 TestFactory 並不算是個 Factory class,好名稱不好找。
maybe 我們的著眼點不同,不過我想強調的是 Java 的 reflection 是一大強項,可以多多利用。


reply to postreply to post
作者 Re:[Effective Java] 條款1 : 考慮以 "static factory methods" 取代建構式 [Re:wctang]
Duncan

還隱隱作痛

版主

發文: 7816
積分: 39
於 2003-10-02 18:08 user profilesend a private message to usersend email to Duncanreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
wctang wrote:
必需是型別名稱才能傳入 TestFactory.getInstance,所以也不能隨便寫個東西就傳了,就算真的傳個其他的 type 進去,也可以用 exception 來擋住,而且如果用個有意義的 subclass name ,也可以讓程式容易理解。重點在於就算我沒有source,只要我知道 TestInterface ,就可以自已寫個 TestSub3 傳進去,就可以和原本的程式配合了。當然,這裡的 TestFactory 並不算是個 Factory class,好名稱不好找。
maybe 我們的著眼點不同,不過我想強調的是 Java 的 reflection 是一大強項,可以多多利用。


所謂 exception 就是 run-time 才會出現的,還是少了 compile-time 檢查這一關。即使你不自己攔截 exception,一旦 run-time 時依照傳入的字串/Class 所產生的 instance 不是傳回型態相容,也會產生 ClassCastException。

我一直覺得 reflection 只有在作物件檢視器(IDE tool 不可或缺的功能)或 bean container 之類的不然就是 stub generator 之類的應用上才會顯得重要,一般寫寫小型的應用程式用到 reflection 的機會還不多吧。


reply to postreply to post

給我
辣味豆腐 其餘免談
作者 Re:[Effective Java] 條款1 : 考慮以 "static factory methods" 取代建構式 [Re:Duncan]
wctang





發文: 7
積分: 0
於 2003-10-02 18:12 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
Duncan wrote:
我覺得這樣子寫並沒有帶來太多好處,以某個角度看反而比 factory method 更是不好的作法。

因為這樣子的作法還是得指名道姓,這跟直接以 public constructor 一樣都是把類別名稱寫出來,你的作法彈性更小只能應付有 default constructor 的型別。

沒錯,這就是一大缺點。但不是沒有解決的方法,可以利用 subclass 的 factory class 來達成非 default constructor 的物件生成能力。不過這就又要多一層了,但實際上或許真的有其必要。

而兩者同樣的缺點是,你會自然而然地讓建構物件的程式片段分散在各處,假如目前偕同作用的物件是一組的,當遇到需要替換成另一組時,你得翻遍所有的程式碼找出建構物件的部分,這就是為什麼要用 Abstract Factory,至少 Abstract Factory 可以縮小物件生產的範圍(集中在 factory 身上)抽換 factory 就可以整個換掉。

這個反而容易解決,可以將不同組的物件用 package 來分類,而不同的 Abstract Factory 就用不同的 package 中的 class 來建立就行了,不過我覺得功能的擴充比較常見,切換至另一組到是比較少看到的需求。


當然你也可以試著讓 TestInterface- getReadObject(static factory method)使用的地方侷限在某個範圍,但這樣子你的作法顯得沒有很必要,但的確是可以讓他的生產種類提到最大,不過就像 iampoya 提到的,有少了 compile-time type checking 的弊病。

我想 static factory method 本身就有一個缺點是不能避免的,那就是不容易擴充。一個 static factory method 會產出的物件決定了,似乎沒辦法在不修改程式碼的情況下得到另外不同 subclass 的 instance(如果不搭配其他的 pattern),你沒有辦法透過繼承機制來改變或擴充 static factory method 的產品(種類)。

其實我是不太了解 static factory method 的真正內涵,不過我覺得比較像是在 C++ 的系統中會有需要,像 Java 這種 bytecode 固定的系統,可以有更漂亮的解法。這種功能在 C++ 要實現就會是 os depend.


reply to postreply to post
作者 Re:[Effective Java] 條款1 : 考慮以 "static factory methods" 取代建構式 [Re:Duncan]
wctang





發文: 7
積分: 0
於 2003-10-02 18:21 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
Duncan wrote:
所謂 exception 就是 run-time 才會出現的,還是少了 compile-time 檢查這一關。即使你不自己攔截 exception,一旦 run-time 時依照傳入的字串/Class 所產生的 instance 不是傳回型態相容,也會產生 ClassCastException。

我一直覺得 reflection 只有在作物件檢視器(IDE tool 不可或缺的功能)或 bean container 之類的不然就是 stub generator 之類的應用上才會顯得重要,一般寫寫小型的應用程式用到 reflection 的機會還不多吧。

或許吧 Smile
不過我覺 Java 不久(Java 剛出來時學過一陣子,變了好多),突然發現 Java 有 reflection 的功能,覺得令人驚豔 Smile 比 C++ 的 rtti 更方便而且標準。
不過,我看到用 reflection 的地方比上面說的多得多了,只要是用 JavaBean 的地方大概都可以用 reflection 來更加強其應用。

不過好像開始離題了… Smile


reply to postreply to post
作者 Re:[Effective Java] 條款1 : 考慮以 "static factory methods" 取代建構式 [Re:wctang]
metavige

麥塔.米奇

版主

發文: 2133
積分: 10
於 2003-10-02 20:42 user profilesend a private message to usersend email to metavigereply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
我似乎發現我把優點三講得太簡單了
針對可以傳回 隸屬於函式回返值型別之任何子型別 這件事

在書裡面是談到可以有幾項應用

1. API 可以傳回 non-public classes 的一個物件, 可以隱藏 implementation classes
我想是 inner classes, private/package-private classes 吧

2. 也可以是一個 subtype
就有如 ingramchen, wctang, Duncan 各位所貼的那些程式碼所說的

3. 並不需要在 「擁有 static factory methods 的那個 class」被撰寫時就存在
可以用 Properties 裡面將 key 跟 class 名稱作映對
再用 Class.forName & Class.newInstance() 將物件產生實體

這樣我想就清楚多了∼ Big Smile


reply to postreply to post
請各位新手參考 論壇規範Java 新手 FAQ
作者 Re:[Effective Java] 條款1 : 考慮以 "static factory methods" 取代建構式 [Re:Duncan]
tempo



版主

發文: 645
積分: 7
於 2003-10-03 09:35 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
Duncan wrote:
所謂 exception 就是 run-time 才會出現的,還是少了 compile-time 檢查這一關。即使你不自己攔截 exception,一旦 run-time 時依照傳入的字串/Class 所產生的 instance 不是傳回型態相容,也會產生 ClassCastException。

我一直覺得 reflection 只有在作物件檢視器(IDE tool 不可或缺的功能)或 bean container 之類的不然就是 stub generator 之類的應用上才會顯得重要,一般寫寫小型的應用程式用到 reflection 的機會還不多吧。


還有, ap server 跟很多物件管理的 frameworks (或許就是 Duncan 說的 bean container?) 也都大量使用 reflection ...Smile
如 spring, avalon ...
這裡有詳細的介紹: http://www.springframework.org/docs/lightweight_container.html


reply to postreply to post
作者 Re:[Effective Java] 條款1 : 考慮以 "static factory methods" 取代建構式 [Re:metavige]
etman





發文: 15
積分: 0
於 2003-10-29 10:33 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
Factory method在應用面上討論,應是與Proxy pattern結合最有利,我們可以先用Abstract factory來定義我們的類別(內部),再實作某個介面(外部),而利用Proxy pattern與Factory method的結合,來達到一個類別合作的目的,而關於Reflection我想,很多人都知道他不是一個好的產生物件的方式,他會拉低效能,不易維護,但又不失為一種好方法,我們可以利用Proxy pattern的原理,在裡面使用Reflection和Pooling,但必須確保每個類別都是Invoke by reference而沒有狀態的類別成員,像Value Object就不適合(當然,我們也可以定義一個Clear方法,在拿取前呼叫),當我們第一次產生instance時,將這份instance keep在Pool中,後續只需從Pool拿取物件即可,這在效能上又增進許多,Struts就是利用這個原理來產生Action,ActionForm...etc,可以配合Jakarta Commons-pool

reply to postreply to post
作者 Re:[Effective Java] 條款1 : 考慮以 "static factory methods" 取代建構式 [Re:metavige]
LarryBank





發文: 1
積分: 0
於 2004-04-19 17:08 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
可是我們真的要做這麽高品質的code嗎?

reply to postreply to post
作者 Re:[Effective Java] 條款1 : 考慮以 "static factory methods" 取代建構式 [Re:metavige]
davidlovesmoly





發文: 7
積分: 0
於 2004-04-23 12:03 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
各位朋友好!

首先我想說: 問的好, Larry! 不過要清楚描述我會這麼說的原因 只怕要寫上
好多好多. 所以我只就原本的問題提出看法.

static factory method這個題目能引起這麼多討論, 其實蠻令我訝異.

我想 metavige 應該是打錯字或可能誤解了"第三個好處"中作者提出的
"第一個"實例:
應該是java.util.Collections 而不是 Collection.

對照一下Collections的文件, 再看一下原書的敘述, 我想應該就ok了吧...

此外原來提到的缺點, 首先我覺得前面的朋友們舉的例子似乎不太恰當...

作者在此處所指的"classes without public or protected constructors
can not be subclassed" 應該是呼應 "上一段" 所提的諸多好處
(static factory method 可傳回符合某特定 interface 的物件, 而此物件
的實際的產生或實作細節不需被公開. 使用者不知道此物件實際上屬於
哪個特定的Class 亦無所謂. java.utl.Calendar不就是個挺好的例子)
硬要使用這裡提出的Shape的例子, 那就變成了Rectangle, Cirle,...
其他Shape的徒子徒孫 的constructor 不被公開(意即僅有private
的constructors). 這樣programmer 當然不好以繼承的方式擴充Rectangle,
Circle,...

正如作者的原意, 缺點未必是缺點...
"Arguably this can be a blessing in disguise"
"it encourages programmers to use composition
instead of inheritance(Item 14)"

我剛才進來時瞄了一下列表似乎已經有人在討論(item 14)了

另外我對 etman 的想法頗為好奇, 以我的認知, Design Pattern
內的 Factory Method 和effective Java 所提的 static factory method
出發點並不一樣 是否真如 etman 提到的
"Factory method在應用面上討論,應是與Proxy pattern結合最有利"
我還從來沒往這方向想過 或許 etman 的想法本身就值得為他在
開個主題討論了

有空再聊!


reply to postreply to post
作者 Re:[Effective Java] 條款1 : 考慮以 "static factory methods" 取代建構式 [Re:LarryBank]
metavige

麥塔.米奇

版主

發文: 2133
積分: 10
於 2004-04-23 14:24 user profilesend a private message to usersend email to metavigereply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
LarryBank wrote:
可是我們真的要做這麽高品質的code嗎?


高品質與易維護我想是成正比的∼

所以為了以後專案的易維護性,當然是建議用一些比較好的 Patterns
況且用了 Patterns,也增加了可讀性


reply to postreply to post
請各位新手參考 論壇規範Java 新手 FAQ
作者 Re:[Effective Java] 條款1 : 考慮以 "static factory methods" 取代建構式 [Re:davidlovesmoly]
metavige

麥塔.米奇

版主

發文: 2133
積分: 10
於 2004-04-23 14:37 user profilesend a private message to usersend email to metavigereply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
davidlovesmoly wrote:
各位朋友好!

略....

我想 metavige 應該是打錯字或可能誤解了"第三個好處"中作者提出的
"第一個"實例:
應該是java.util.Collections 而不是 Collection.

對照一下Collections的文件, 再看一下原書的敘述, 我想應該就ok了吧...

沒錯∼我看了 API 文件,應該是 java.util.Collections
回家再參考原文的部分...... Blush


此外原來提到的缺點, 首先我覺得前面的朋友們舉的例子似乎不太恰當...

作者在此處所指的"classes without public or protected constructors
can not be subclassed" 應該是呼應 "上一段" 所提的諸多好處
(static factory method 可傳回符合某特定 interface 的物件, 而此物件
的實際的產生或實作細節不需被公開. 使用者不知道此物件實際上屬於
哪個特定的Class 亦無所謂. java.utl.Calendar不就是個挺好的例子)
硬要使用這裡提出的Shape的例子, 那就變成了Rectangle, Cirle,...
其他Shape的徒子徒孫 的constructor 不被公開(意即僅有private
的constructors). 這樣programmer 當然不好以繼承的方式擴充Rectangle,
Circle,...

不過這裡 ingramchen 所提出的範例,並沒有撰寫 Rectangle, Circle 等的 Constructor
但並不代表這幾個 Class 不能被繼承
當然,在這邊討論的並不是針對被實體化的 Classes
應該是針對該物件若有建構式,考慮使用 static factory method 來取代
但若有 subclasses,處理的方法只是有稍微不一樣而已
就如您所提出的 Calendar 就是一個以 static factory method 來取代建構式的範例n但這與 ingramchen 所提出的範例卻又有不相同的部分
所以要將這兩個例子拿來作比較似乎有點不好


略.....

我剛才進來時瞄了一下列表似乎已經有人在討論(item 14)了

略.....


每個主題其實都有其關連性存在,分開來討論或許會有其偏差性
或許條款14與條款1合併起來討論,就會有不同的想法也說不定
因為複合與繼承建構式是有一點關係的∼


reply to postreply to post
請各位新手參考 論壇規範Java 新手 FAQ
作者 Re:[Effective Java] 條款1 : 考慮以 "static factory methods" 取代建構式 [Re:metavige]
davidlovesmoly





發文: 7
積分: 0
於 2004-04-23 17:59 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
Nice to meet you, Metavige. It's great to share idea with you.
In fact, I feel happy in these days for I can spend working hours on
this sites for I'm using this sites as the testing target of our company's
product, as to the testing result, so far so good.


davidlovesmoly edited on 2004-04-23 18:02
reply to postreply to post
go to first page go to previous page  1   2  go to next page go to last page
» JWorld@TW »  Software Design » Effective Java

reply to topicthreaded modego to previous topicgo to next topic
  已讀文章
  新的文章
  被刪除的文章
Jump to the top of page

JWorld@TW 本站商標資訊

Powered by Powerful JuteForum® Version Jute 1.5.8