伪命题:Java传递的值还是引用?

13-04-17 banq
Java参数传值还是传引用?

Java按值传递与引用传递?

JAVA值传递还是引用传递?

初学者经常被这个问题搞得头晕脑胀,甚至它还成为程序员面试的经典试题,但是在我个人看来,这个问题本身存在误导,如同妈和老婆落水你先救哪个一样,这个问题能够成立的条件并不是在Java语言这个边界内。

实际上这个问题是:

Java(或其他语言)能否提供值传递或引用传递?

语言平台除了这两种传递方式之外,是否需要其他传递方式?

要回答这两个问题,我们需要从OO松耦合和DDD分析设计这个高度来回答。

之前我写了两篇文章:

1. 松耦合角度:依赖注入和事件编程,提出了如果因为两个类因为方法调用,而必须将这两个类实现引用关联,这是一种因为局部利益造成整体依赖紧耦合的短视做法。

2.聚合根与Bounded Context角度:使用依赖注入实现聚合根之间调用的逻辑悖论,DDD提供了一套统一语言和方法,让我们对需求领域切分成一个个Bounded context,这些上下文场景孕育了聚合根,有名乃万物之母,不能有超越有界上下文边界的聚合存在,而如果将两个聚合根(聚合群的头)使用引用聚合在一起,这本身实则是混淆了上下文边界,Evans认为在上下文之间重用代码是一件非常冒险的,更何况我们通过引用表达这种紧耦合关系。

既然引用是把双刃剑,如此简单却又是造成紧耦合的元凶,那么是不是应该慎重使用呢?每次用Java编程时,该使用引用+依赖注入,还是考虑使用别的方式替代呢?

值+ 事件消息 可以替代引用+依赖注入。

比如原来引用+依赖注入的代码:

public class BacklogItem{
     Product product;

}
<p>

如果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>

既然我们的设计意图是使用事件消息,那么我们就要拷问作为设计工具的Java,你能实现这样的事件消息吗?

Java只能说:不能直接实现。

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

如果下次再有人问你:Java传递的是值还是引用。

你可以反问:传你个妹啊,你怎么不问Java能够传递消息吗?

[该贴被banq于2013-04-17 10:30修改过]

[该贴被admin于2013-04-17 12:32修改过]

                   

7
banq
2013-04-17 11:56
之所以认为这是个伪问题,是因为弄清楚这个问题对于是否能使用好Java没有任何帮助。

正如弄清楚“母亲和老婆掉入水里先救哪个”对你生活有帮助吗?

如果一个问题没有任何利处,反而可能浪费时间精力,干脆就否定问题本身。被应试教育驯化的我们要敢于说“不”。

2012
2013-04-18 01:21
没法回复?

[该贴被2102于2013-04-18 01:22修改过]

hxzqlh
2013-04-19 14:11
有个疑问:

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));

}

}

板桥的这种设计方式不也同样耦合了BacklogItem和ProductVO两个类吗?我觉得,只要是面向对象,一个类关联了另一个类的话,除了组合、实现某个接口,没有其他方式了吧?

hxzqlh
2013-04-19 14:15
其实这个问题对于java初学者是有帮助的,在java里传递的参数一律都是实参的副本,引用也是一个值(某个对象的地址的值),传递引用被有些人误以为传递的是对象的地址(其实是对象地址的一个副本)

猜你喜欢
2Go 1 2 下一页