锁定老帖子 主题:基础知识: 需求!
该帖已经被评为精华帖
|
|
---|---|
作者 | 正文 |
发表时间:2004-08-21
好. 问题前提逐渐有点轮廓了.
potian的意思: ejb等外部环境是希望组件必须提供语言约定俗成的构造函数. 所以组件就必须提供这个约定俗成的构造函数. 首先, 我在我的利弊分析里确实没有列出这一条. Bloch的文章里倒是列了: 构造函数是约定好的. 有它的直接性. 工厂函数没有约定, 是要根据文档的. 这是工厂的一个缺点. 我无意否认. 那么, 接下来, 问题就是: 1. 是否多数的可重用的类都要喝这些容器打交道? 我的理解是只有少数的要放到容器中的类才需要. 很多类都可以不用关心外部环境的存在, 埋头做好自己的事情, 最后即使要放到容器中也可以通过adapter罩一个壳子. 这样才达到了容器无关性和最大的重用. 不知道你怎么看这个问题. 2. 这些外部环境不支持. 到底是它们侵入性强, 还是组件不应该自己封装自己? 我理解这是一个不是很现实的问题. 这些外部环境已经存在了, 你的质疑不能改变它们对你的设计的约束这个事实. 我只是从一个更理论的角度, 来说这样的外部环境是否是最合理的? 或者, 换句话说, 是否一个支持静态工厂等组件自定义构造方式的容器比一个不支持这个灵活性的容器要好呢? 总而言之, 两个需要辨析清楚的问题: 1. 是否应该每个类都是先天适应各种流行的容器的. 还是放弃这个限制, 给各个类自由. 如果要放到某个特定的容器, 用adapter来解决不匹配? 2. 是否容器们有权利要求组件提供一个固定的接口? (比如语言约定的公有构造函数). 是容器服务于组件, 还是组件服务于容器? 从一个整体的角度看, 两者谁更符合依赖倒转原则? |
|
返回顶楼 | |
发表时间:2004-08-21
引用 任何一种框架和技术都可以自由选择自己的方式来创建对象
其实,你这句话不严谨. 从你的看法来说, 所有的框架都必须只能要求公有构造函数, 没有所谓的"自由选择自己的方式". 否则, 如果我做了一个要求instance()函数的框架, 而你的组件只提供了构造函数, 不是一样不成? 换句话说,你主张的,只是大家都应该只用语言约定好的方式来创建对象. 框架只能要调用构造函数, 组件只能提供构造函数. 大家都没有什么自由. |
|
返回顶楼 | |
发表时间:2004-08-21
引用 1. 是否多数的可重用的类都要喝这些容器打交道? 我的理解是只有少数的要放到容器中的类才需要 我认为可以不放到任何容器里面,对象不应该假设别人把自己放到容器里面或不放到容器里面 引用 很多类都可以不用关心外部环境的存在, 埋头做好自己的事情, 是的 引用 最后即使要放到容器中也可以通过adapter罩一个壳子. 这样才达到了容器无关性和最大的重用. 最好连这个adapter也不需要。另外一种情况就是因为你的构造方法已经做了一定的假设,例如你的构造静态方法里面已经依赖了JDBC,这个时候adapter也解决不了问题 引用 2. 这些外部环境不支持. 到底是它们侵入性强, 还是组件不应该自己封装自己?
侵入性的意思是这些框架要求对象必须遵守某种特殊的要求和限制,例如必须实现框架的某些接口。但这里我们只要求对象遵守Java最基本的设定。我不认为这是环境对对象的约束 |
|
返回顶楼 | |
发表时间:2004-08-21
引用 引用 很多类都可以不用关心外部环境的存在, 埋头做好自己的事情, 是的 既然如此. 为什么我要关心外界环境的要求而不敢用静态工厂呢? 你的不能用静态工厂的原因不是因为容器不支持吗? 这不是对容器的一种依赖? 引用 最好连这个adapter也不需要。另外一种情况就是因为你的构造方法已经做了一定的假设,例如你的构造静态方法里面已经依赖了JDBC,这个时候adapter也解决不了问题 当然最好不需要. 但是, 如果能用adapter来解决, 为什么把要和容器兼容作为每个类的设计目标? 这不等于自绑手脚? 依赖jdbc? 如果你构造函数依赖了jdbc呢? 不是一样? 这是设计的问题, 不是静态厂的问题. 引用 侵入性的意思是这些框架要求对象必须遵守某种特殊的要求和限制,例如必须实现框架的某些接口。但这里我们只要求对象遵守Java最基本的设定。我不认为这是环境对对象的约束
呵呵. 你容器都对我的组件设计指手画脚了: 不许用静态工厂! 我支持不了! 还不是约束? 你的约束的定义是什么呀? 就因为这是语言的约定俗称? 可是语言的约定俗成只是一个约定, 从来没有成为一个必须尊行的硬标准啊. 是谁把它变成了硬标准呢? 这个从可选约定变成变成硬标准不是约束? |
|
返回顶楼 | |
发表时间:2004-08-21
引用 引用 引用 很多类都可以不用关心外部环境的存在, 埋头做好自己的事情, 是的 既然如此. 为什么我要关心外界环境的要求而不敢用静态工厂呢? 你的不能用静态工厂的原因不是因为容器不支持吗? 这不是对容器的一种依赖? 可重用的对象是要被人家用的,所以最好是即不假设人家要把他放到容器里面也不假设人家要把它放到容器里面 对象不应该增加不必要的间接性来阻碍别人可能对他的使用 引用 引用 最好连这个adapter也不需要。另外一种情况就是因为你的构造方法已经做了一定的假设,例如你的构造静态方法里面已经依赖了JDBC,这个时候adapter也解决不了问题 当然最好不需要. 但是, 如果能用adapter来解决, 为什么把要和容器兼容作为每个类的设计目标? 这不等于自绑手脚? 依赖jdbc? 如果你构造函数依赖了jdbc呢? 不是一样? 这是设计的问题, 不是静态厂的问题. JDBC的例子是因为你做这个静态方法的原因就是在内部控制自己的构造形式,这是你已经作出的决定,不是JDBC也可能是每次都new,不管怎么样,你增加静态方法的原因就是因为这里需要作出一些控制,作出一些限制,不然的话就和构造函数完全一样了 这本来是一个设计问题,但是你在静态厂里面必然把某一种做法确定下来了,而这种做法必然是由于你当时应用的需要。下次另外一个应用程序有另外一种控制需要或者没有控制需要的时候,不管你如何重构,你都无法用同一段代码同时满足两个不同应用程序的需要 |
|
返回顶楼 | |
发表时间:2004-08-21
如果一个容器要求你的组件必须实现接口ABC, 你会让你的每个类都实现ABC还是告诉你的程序员:
别理它. 你们做你们的就好. 就当没这个傻容器. 然后, 最终当要把某个类放入容器的时候, 做一个adapter? 两种方案哪个好? 对比一下, 如果容器要求组件必须支持构造函数, 你是要求所有的类, 不论将来会不会被放入容器, 都要公开构造函数. 还是不对具体的类做要求, 在要放入容器时, 如果碰巧这个类不支持构造函数, 就adapt一下? 是否第二个方案就必然是个不可重用的错误方案呢? |
|
返回顶楼 | |
发表时间:2004-08-21
引用 对象不应该增加不必要的间接性来阻碍别人可能对他的使用
从你这个说法我闻到了被调用者依赖调用者这个味道. 首先, 这是一个可能, 你是否为了一个10%概率发生得事情来预先付出代价? 其次, 既然调用者可以用adapter来解决不匹配(这正是oo得迷人所在), 你这个说法还有多大意义呢? 最后, 什么叫做"不必要"? 我在前面给出了这样作得好处. 是否必要, 时由容器说了算还是由具体类的设计者说了算? 如果类的设计者发现这样作很有必要呢? 还是你要接下来证明: "即使不管容器, 静态工场也永远不是必要的." 这个判断? 那样你就要直接面对前面我提出的几个静态工厂的好处了. (或者Bloch的, 如果我的表达总让人误会的话) 其实,是否要说: 对象不应该增加任何间接性来造成别人可能需要用adapter来使用它 我可不大信服这样一个说法. |
|
返回顶楼 | |
发表时间:2004-08-21
引用 JDBC的例子是因为你做这个静态方法的原因就是在内部控制自己的构造形式,这是你已经作出的决定,不是JDBC也可能是每次都new,不管怎么样,你增加静态方法的原因就是因为这里需要作出一些控制,作出一些限制,不然的话就和构造函数完全一样了
这本来是一个设计问题,但是你在静态厂里面必然把某一种做法确定下来了,而这种做法必然是由于你当时应用的需要。下次另外一个应用程序有另外一种控制需要或者没有控制需要的时候,不管你如何重构,你都无法用同一段代码同时满足两个不同应用程序的需要 我注意到你曾经提过这个观点. 只是当时枝节太多, 我们都不知道该对着哪个问题开火了. 当然, 如果你能给出几个具体例子来, 就好了. 现在, 我还是先复述一下你的观点, 看看理解上是否有偏差. 省得到时候又让你生气. 你是否说: 用了静态工厂, (假设这个instance()函数每次都new吧), 那么, 外界就无法做类似singleton之类的创建控制了. 而如果直接就是构造函数, 外界想singleton就singleton, 想cache就cache,想怎样就怎样. 是这个意思吗? |
|
返回顶楼 | |
发表时间:2004-08-21
ajoo 写道 引用 JDBC的例子是因为你做这个静态方法的原因就是在内部控制自己的构造形式,这是你已经作出的决定,不是JDBC也可能是每次都new,不管怎么样,你增加静态方法的原因就是因为这里需要作出一些控制,作出一些限制,不然的话就和构造函数完全一样了
这本来是一个设计问题,但是你在静态厂里面必然把某一种做法确定下来了,而这种做法必然是由于你当时应用的需要。下次另外一个应用程序有另外一种控制需要或者没有控制需要的时候,不管你如何重构,你都无法用同一段代码同时满足两个不同应用程序的需要 我注意到你曾经提过这个观点. 只是当时枝节太多, 我们都不知道该对着哪个问题开火了. 当然, 如果你能给出几个具体例子来, 就好了. 现在, 我还是先复述一下你的观点, 看看理解上是否有偏差. 省得到时候又让你生气. 你是否说: 用了静态工厂, (假设这个instance()函数每次都new吧), 那么, 外界就无法做类似singleton之类的创建控制了. 而如果直接就是构造函数, 外界想singleton就singleton, 想cache就cache,想怎样就怎样. 是这个意思吗? 基本上是这个意思 |
|
返回顶楼 | |
发表时间:2004-08-21
那么, 让我来写一个基于静态工厂的singleton让大家批评一下.
前提, 我知道类X的instance()方法返回一个接口I的实例. 但是我不知道它是否每次一定返回一个新的实例还是旧的. 我只知道它对我来说可以当新的用. (除了不要试图去用==比较) 下面我试图从类X外面做一个singleton. class XSingleton{ public static I getSingleton();{return singleton;} private static final I singleton = X.instance();; } 是否可行呢? |
|
返回顶楼 | |