欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

基于不要返回null之EmptyFactory的应用详解

程序员文章站 2023-12-19 20:38:34
有很多书上都提出过一个建议:不要返回null对象。比如下面的getusers方法:public class user{    public s...
有很多书上都提出过一个建议:不要返回null对象。
比如下面的getusers方法:
public class user
{
    public string id { get; set; }
    public string name { get; set; }
}

public list<user> getusers()
{
    list<user> result = new list<user>();

    // search db for user
    return result;
}
如果其他方法由getusersofxxx,getusersbyxxx之类的方法,那么就有大量
list<user> result = new list<user>();

考虑到这一点,可以将new list<user>()  封装到方法中,这就是”工厂”模式了.
因为可能不是list<user> ,也许是stack<user> 更或者是observablecollection<user>

所以配合泛型,代码如下:
public static class emptyfactory
{
    public static t empty<t>() where t : ienumerable, new()
    {
        return new t();
    }
}

使用如下:
list<string> emptylist = new list<string>();
stack<string> emptystack = new stack<string>();
observablecollection<string> emptyobserable = new observablecollection<string>();

emptylist = emptyfactory.empty<list<string>>();
emptystack = emptyfactory.empty<stack<string>>();
emptyobserable = emptyfactory.empty<observablecollection<string>>();
虽然这样写可以满足要求,但是可以发现基本没什么好处,写emptyfactory还不如new 来得快。
不过如果能够缓存对象的话,也许emptyfactory有作用。
考虑到这一点,为emptyfactory增加缓存机制的代码如下,使用dictionary<type,object> 来实现
复制代码 代码如下:

public static class emptyfactory
{
    private static dictionary<type, object> cacheemptyobjects =
                     new dictionary<type, object>();
    public static t empty<t>() where t : ienumerable, new()
    {
        type generictype = typeof(t);
        if (cacheemptyobjects.containskey(generictype))
        {
            return (t)cacheemptyobjects[generictype];
        }
        else
        {
            t tempemptyobject = new t();
            cacheemptyobjects.add(generictype, tempemptyobject);
            return tempemptyobject;
        }
    }
}

测试代码如下:

 基于不要返回null之EmptyFactory的应用详解

不过这种方法有一个缺陷,对于值类型而言,需要装箱

其根本原因是因为emptyfactory不知道t是什么,如果emptyfactory知道t的话,那么就可以使用dictionary<t,t> 的缓存了。

解决这个问题的思路是将emptyfactory变成泛型类:

代码如下:

复制代码 代码如下:

public static class emptyfactory<t> where t : ienumerable, new()
{
    private static dictionary<type, t> cacheemptyobjects = new dictionary<type, t>();
    public static t empty()
    {
        type generictype = typeof(t);
        if (cacheemptyobjects.containskey(generictype))
        {
            return cacheemptyobjects[generictype];
        }
        else
        {
            t tempemptyobject = new t();
            cacheemptyobjects.add(generictype, tempemptyobject);
            return tempemptyobject;
        }
    }
}

使用的时候,只需要

基于不要返回null之EmptyFactory的应用详解

当然也可以emptyfactory<list<user>>.empty();

为什么不用enumersble.empty<t>方法呢?

因为enumerable.empty<t> 返回的是ienumerable<t>对象。

上一篇:

下一篇: