0
interface IDependency
{
    string Baz { get; set; }
}

class Foo
{
    IDependency dependency;

    public Foo(IDependency dependency)
    {
        this.dependency = dependency;
    }

    public void FubarBaz()
    {
        dependency.Baz = "fubar";
    }
}

我也可以将其实现为:

class FooStatic
{
    public static void FubarBaz(IDependency dependency)
    {
        dependency.Baz = "fubar";
    }
}

我什么时候应该选择不可变对象而不是静态方法?在任何情况下,情况可能相反吗?

另外,在我看来,不可变对象不应该有 void 方法。你怎么看?

4

2 回答 2

3

不可变对象当然可以有 void 方法——除了改变对象的状态之外,还有其他种类的副作用。考虑:

public void WriteTo(Stream stream)

举个例子。

至于您的“不可变对象与静态方法”问题 - 如果您的方法实际上需要状态的几个方面Foo怎么办?仅仅因为状态没有改变并不意味着将状态封装在一起是没有意义的。假设它有 5 个依赖项而不是 1 个 - 你想编写大量采用 5 个参数的静态方法吗?当您获得第六个依赖项(甚至只是另一个状态)时,您真的希望必须将第六个参数添加到所有方法,还是只添加到构造函数?

于 2009-09-29T23:56:02.493 回答
0

FubarBaz() 改变成员Foo.dependency因此Foo不是不可变的。不变性是一种设计约束,可以而且应该通过标记 fields 在 C# 中更好地表达readonly。您的依赖项的连接可以而且应该在构造函数中完成(如果您正在执行 IoC,大多数框架都需要这样做)。一个不可变的设计最终可能是这样的:

class Foo
{
    private readonly IDependency dependency;

    public Foo(IDependency dependency)
    {
        this.dependency = dependency;
        dependency.Baz = "fubar";
    }
}

可变和不可变类设计都有时间和地点。也许一个值经常改变并且类不共享,那么一个可变类就起作用了。不变性具有不变性的优点。您可以传递对对象的引用,并确保它指向的值永远不会改变。这是一个强大的概念,尤其是在处理多线程应用程序时。

使用静态类的决定应该基于您希望调用的外观,或者您是否绝对需要使用静态类,例如创建扩展方法时的情况。IME,在实现调用之前编写调用是在连接实现之前决定设计的好方法。静态与非静态基本相同,只是静态不能“新建”(由您构建)。静态不是一成不变的,特别是因为你不构造它们。您只需处理一个实例。

我认为没有理由避免在不可变类设计中的方法上使用 void 返回类型。

于 2015-02-18T01:49:49.837 回答