既然是工厂造出来返回对象,没造出来当然是NULL了。
这样符合逻辑,也不用再捕捉异常了。

解决方案 »

  1.   

    具体问题具体分析:
      为什么  对象没有能成功生成?
    如果是对象本来就不应该生成。那就返回null
    如果对象应该可以生成,但是因为出错了,没能生成,那就是异常。因为异常通常表示程序出错了。
    而null表示没有出错。只是没有值而已。
      

  2.   

    不管怎么样,我都不同意返回null,有两种情况,其一,这个事件处于用例图中的异常流分支,例如:
    public class UserFactory{
      public User getUser(String name,String password)throws AuthException{
         ....
      }
    }
    在登录时,用户名和口令不符,这是一个明显的异常流,应该用一个定制的异常来描述,这很合理。异常也是对象,可以帮助我们写出更OO的设计。
    其二,当这种情况不足以承担一个异常流时,有比返回null更好的方式,比如NullObject模式,你可以在网上查一下,举个简单例子:public User[] getUserList();上述方法将返回一个用户列表,当没有用户时,你返回一个零长度数组无疑比你返回一个null要友好得多,因为调用它的其它类不必非得这样子作:
     if (getUserList!=null) ....
    他可能简单地迭代一下就可以了,这是良性设计,不强迫调用者多去考虑。
    想想那烦人的空指针错误吧。
      

  3.   

    小蚊子所说的:异常代表程序出错了,这是不对的。异常中有checkException和未检查异常,你可以查一下相关文档,异常可以帮助我们写出更健壮的程序,这句话大家都比较熟悉了,作为初学者很容易就忽略异常,你建立起OO的思维习惯后,看异常的观点可能就不一样了。
      

  4.   

    返回null,在用这个对象的地方判断是否为null
      

  5.   


    mOm 253 青之六号一个(没有任何贬义)----------------------------------------------------------------
    首先,你说的是正确的。
    异常中有checkException和未检查异常,AuthException
    可以做成一个checkException的例子。
    public User getUser(String name,String password)throws AuthException
    的例子也是不错的。----------------------------------------------------------------
    但是,我感觉这不是一个“用例图中的异常流分支”。你说的这个异常,只是程序员眼中的异常,而不是用例中的异常。
    对于用户来说,一不小心用户名或者密码输入错了,完全是很正常的一件事情,
    必须检查,乃是情理中的事情。
    只是程序员写了一个异常来完成这个检查罢了。
    从上层用例来看,这是一个正常出口。那么,我们为什么一定要写成
    public User getUser(String name,String password)throws AuthException
    这个样子呢?从设计角度看来,这里要做得事情其实是:
    public boolean isAuthCorrect(String name,String password)然而,实际上,如果我们有一些属性保存在 User 这个类里边
    而后边要通过他来实现某些功能,比如权限验证等。那么我们
    还需要一个函数如下:
    public User getUser(String name,String password)一个简单的做法就是把它们写到一起去,于是
    public User getUser(String name,String password)throws AuthException
    就产生了。假如不需要 User 这个类,那么直接用isAuthCorrect就好了。所以说这未必是一个异常流。
    不知大家是否同意。----------------------------------------------------------------
    其次,你这个例子呢,是工厂模式吗?不是吗?是吗?
    我觉得,不是所有用来创建一个对象的代码都是工厂模式。
    工厂模式确实是一个比较有意思的模式,值得去好好研究研究。
    (public User[] getUserList();应该和工厂模式没有关系的。)----------------------------------------------------------------
    NullObject模式
    是不是就使你所说的,“返回一个零长度数组”
    我倒是没有找到相关资料。
    不过,“返回一个零长度数组”是一个比较好的办法。
    然而缺点就是必须靠程序员自律。
    很难做到。除非是"Design by Contract"。
    因为,别人返回一个null,或者返回一个零长度数组,
    都得处理,是挺烦的。
    但是如果实现没有约定好的话,你不能说人家
    返回一个null,或者返回一个零长度数组,
    就错了。
    而且,为了增加你程序的鲁棒性。这两种情况都处理
    是应该的。----------------------------------------------------------------
    最后,关于例外,有一篇文章不错。
    http://blog.csdn.net/kiss0931/archive/2005/02/21/296170.aspx摘录:
    Error类体系描述了Java运行系统中的内部错误以及资源耗尽的情形。应用程序不应该抛出这种类型的对象(一般是由虚拟机抛出)。如果出现这种错误,除了尽力使程序安全退出外,在其他方面是无能为力的。所以,在进行程序设计时,应该更关注Exception体系。
    RuntimeException体系包括错误的类型转换、数组越界访问和试图访问空指针等等。处理RuntimeException的原则是:如果出现RuntimeException,那么一定是程序员的错误。例如,可以通过检查数组下标和数组边界来避免数组越界访问异常。
    这类异常一般是外部错误,例如试图从文件尾后读取数据等,这并不是程序本身的错误,而是在应用环境中出现的外部错误。4 关于异常的其他问题
    4.1 过度使用异常
    首先,使用异常很方便,所以程序员一般不再愿意编写处理错误的代码,而仅仅是简简单单的抛出一个异常。这样做是不对的,对于完全已知的错误,应该编写处理这种错误的代码,增加程序的鲁棒性。另外,异常机制的效率很差。
    4.2 将异常与普通错误区分开
    对于普通的完全一致的错误,应该编写处理这种错误的代码,增加程序的鲁棒性。只有外部的不能确定和预知的运行时错误才需要使用异常。
      

  6.   

    to 小蚊子:(没有任何贬义 too :)
    1.有很多设计思路都没有绝对唯一正确的,作为用户登录,当输入不存在的
    用户名或口令不符时,使用use case的异常流来描述我认为是恰当的。
    “程序员眼中的异常”?王侯将相,宁有种乎,我认为这个异常只是一个业务
    逻辑层异常,不管是程序员或系统设计(use case view)无二义性。2.public User[] getUserList();
    是为了说明返回null不好的例子,它的确不是一个工厂方法。返回空数组这个idea出自<<effective java>>,
    此书中也有几个原则是关于异常的,很不错。3. 异常的创建的确比较耗性能,不过良好的设计现在要重于性能,在这个级别上
    考虑优化,不如你去持久层,数据库连接上多考虑,性能瓶颈需要压力测试和数据说话,不能臆测。4 归根结底,咱们还是围绕楼主的主题来进行,我的观点仍是:当选择工厂方法
      返回null或抛出异常时,我坚定地支持后者。
      

  7.   

    补充一点,小蚊子提到了避免过度使用异常,我是同意的,比如说提前检查参数类型,
    预防异常的抛出。
    to jacky:
    这种思路不可取,不OO,相当于一个大的switch,这种设计味道不好。
      

  8.   

    TO: 青之六号不是,我总觉得你的用例中缺少用户的观点。
    所以才定义为异常。
    我觉得用户才是上帝。
    另外正如你所言:“有很多设计思路都没有绝对唯一正确的”
    我觉得,把它看作正常系和异常系是没有关系的。
    用例外来实现正常系是可以的。
    不用例外来实现异常系也是可以的。
    这是实现角度的事。其实我觉得
    public User getUser(String name,String password)throws AuthException
    也不见得是一个工厂模式。我认为,例外不是银弹。
    具体问题具体分析才索硬道理。
      

  9.   

    蚊子,有点喧宾夺主了哟。银弹是没有的,地球人都知道,用例图中的异常流相当于旁支事件,是很
    重要的,正因为要让用户觉得这不是“程序异常”,才把它定义为异常流的。
    public User getUser(String name,String password)throws AuthException;
    明明就是工厂模式,让我们重温一下工厂模式最经常使用的两种情形:
    1. 在编码时不能预见需要创建哪一子类的实例,会根据参数来创建不同子类,以支持多态。 
    2. 开发人员不希望将如何创建实例的信息暴露给外部程序。
    很明显该例属于第二种。