偽命題:Java傳遞的值還是引用?

banq發表於2013-04-17
Java引數傳值還是傳引用?
Java按值傳遞與引用傳遞?
JAVA值傳遞還是引用傳遞?

初學者經常被這個問題搞得頭暈腦脹,甚至它還成為程式設計師面試的經典試題,但是在我個人看來,這個問題本身存在誤導,如同媽和老婆落水你先救哪個一樣,這個問題能夠成立的條件並不是在Java語言這個邊界內。

實際上這個問題是:
Java(或其他語言)能否提供值傳遞或引用傳遞?
語言平臺除了這兩種傳遞方式之外,是否需要其他傳遞方式?

要回答這兩個問題,我們需要從OO松耦合和DDD分析設計這個高度來回答。

之前我寫了兩篇文章:
1. 松耦合角度:依賴注入和事件程式設計,提出瞭如果因為兩個類因為方法呼叫,而必須將這兩個類實現引用關聯,這是一種因為區域性利益造成整體依賴緊耦合的短視做法。

2.聚合根與Bounded Context角度:使用依賴注入實現聚合根之間呼叫的邏輯悖論,DDD提供了一套統一語言和方法,讓我們對需求領域切分成一個個Bounded context,這些上下文場景孕育了聚合根,有名乃萬物之母,不能有超越有界上下文邊界的聚合存在,而如果將兩個聚合根(聚合群的頭)使用引用聚合在一起,這本身實則是混淆了上下文邊界,Evans認為在上下文之間重用程式碼是一件非常冒險的,更何況我們透過引用表達這種緊耦合關係。

既然引用是把雙刃劍,如此簡單卻又是造成緊耦合的元兇,那麼是不是應該慎重使用呢?每次用Java程式設計時,該使用引用+依賴注入,還是考慮使用別的方式替代呢?

值+ 事件訊息 可以替代引用+依賴注入。

比如原來引用+依賴注入的程式碼:

public class BacklogItem{
     Product product;

}
<p class="indent">


如果BacklogItem和Product兩個類之間只是一種方法依賴,也就是說,BacklogItem需要呼叫Product方法,那麼我們就沒有必要使用設計模式這種結構模式(組合模式),而應該考慮行為模式(觀察者模式等),因為這種引用實現的組合模式導致兩個類結構上的依賴,正好誤用了結構型模式。


透過值+ 事件訊息(觀察者模式)可以替代如下:

public class ProductVO {
         private long productId;
         private long name;
         private String description;
}

public class BacklogItem{
      private ProductVO productVO;
      void dosth(){
         //向Product聚合根發事件訊息實現呼叫
       domainevents.send(new 
                      ProductUpdatedEvent(productVO.getProductId));
      }
}
<p class="indent">


既然我們的設計意圖是使用事件訊息,那麼我們就要拷問作為設計工具的Java,你能實現這樣的事件訊息嗎?

Java只能說:不能直接實現。

Scala或Erlang說:I can, 用Actor即可

如果下次再有人問你:Java傳遞的是值還是引用。
你可以反問:傳你個妹啊,你怎麼不問Java能夠傳遞訊息嗎?

[該貼被banq於2013-04-17 10:30修改過]

[該貼被admin於2013-04-17 12:32修改過]

相關文章