我最近向我的一位同事提出建议,指出我们当前的项目(C#)“服务应该是无状态的,因此是静态的”。
我的同事同意并表示,在我们的项目中,服务(并且应该)确实是无国籍的。然而,我的同事不同意静态意味着没有状态,无状态应该意味着静态。
我的问题是“标记为静态的方法是否意味着它不需要任何状态,并且在大多数情况下,无状态方法应该是静态的”。
答案 0 :(得分:7)
静态几乎意味着全球化。还有一个实例,在该实例中仍然存在状态,但它是静态实例,这意味着只有一个,所有调用者总是引用那个。
答案 1 :(得分:5)
标记为静态暗示的方法 它不需要任何州
1)否。你不能说静态方法暗示它不需要状态,因为静态方法可以访问静态/单例资源。
大多数案件应无国籍 方法是静态的
2)是的。不需要状态的方法,因此不需要实例,通常应该是静态的。
答案 2 :(得分:3)
C#中的静态方法可以访问其包含类的静态变量,如果是,则不是无状态的。我已经看到一些令人痛苦的非重入“无状态”静态方法,引发了有趣的竞争条件。
真正无状态的方法确实可以是静态的,通常应该是。
答案 3 :(得分:3)
我觉得无状态与 static 相同,因为这是两个不同的世界,这是相当可怕的。无状态意味着没有状态保持,即一个完美的例子是HTTP连接(一旦数据被发送,连接被关闭,并且没有保留内存),我们实际上正在努力尽力保持状态(登录一个国家)。
静态另一方面是用于描述调用方法的方式的术语。在C#中,这意味着可以在没有类实例的情况下调用方法,但类的实例与state不同。还有静态实例,它完全能够维护状态:任何静态成员变量,字段或属性都可以维持状态。静态方法或类也完全能够通过使用内存映射文件,数据库或其他任何东西来维护状态。静态是一种调用约定,仅此而且与无状态无关。
答案 4 :(得分:3)
我认为他的陈述与“民主国家应该使用黄纸选票”一样有意义。
他正在将高级设计概念“无状态服务”与低级技术实现细节“使用静态类”相结合。
无状态服务可以(并且已经)以仅支持静态变量(例如COBOL,RPG)的语言和甚至不支持静态变量的语言(Erlang等)实现。
我很容易想象一个使用静态类实现无状态服务的情况,因为他们在那里并且已经实现了正确的业务逻辑,尽管它通常被认为是优秀的Java编程实践,除非你真的需要,否则不要使用静态类。
他还严重误解了“静态”的含义 - 静态变量是一种在调用之间存储状态的方式 - 因此似乎与“有状态”服务更好地匹配。
答案 5 :(得分:2)
static 是一种语言关键字, state 是一种设计概念。这两件事之间有明显的关系,但它是具体与形而上学的关系,而不是因果关系。静态方法可以引用某些类型的状态信息。
关于无状态方法,这里我们讨论的是不引用类实例的方法,即this指针。将这些方法标记为静态可以提高代码的清晰度,并与最佳实践保持一致。请注意,在这种情况下,我们正在讨论一种特定的“无国籍”,而不是对有状态上下文的使用做出一般性评论。
答案 6 :(得分:1)
静态可以是有状态的。你只需要为所述状态定义静态容器。并且容器在对静态方法的所有调用中共享。
答案 7 :(得分:1)
每个类都有一个类定义结构,其中表示和存储静态字段。该类的每个“实例”都可以访问存储在类定义中的静态字段(数据结构caleld CORINFO_CLASS_STRUCT
)。即使已经创建了NO实例,程序集中任何位置的代码都可以使用语法classname.StaticFieldName
访问这些静态类级别字段,而根本不需要任何实例。
由于存储在这些静态类级别字段中的值是持久的,因此它们肯定是状态。实际上,它们不仅是可能存在的类的任何实例共享的状态,它们在整个程序集中共享,无论是否已创建任何实例。
更重要的是,因为一旦加载了CORINFO_CLASS_STRUCT
类定义,与类的真实实例不同,它就是 从未卸载 直到程序集(或AppDomain)被卸载,因此可以说 更有状态 比在类中定义的任何实例字段更强,因为当实例被垃圾收集时,实例字段会消失。 / p>
有关详细信息,请查看Don Boxes精彩图书CORINFO_CLASS_STRUCT
答案 8 :(得分:1)
对你的问题的简短回答是“不”,static
并不意味着“没有国家”。
在参考您的其他评论时,static
可用于帮助您实施无状态服务,但仅static
是不够的。另一种帮助使无状态的工具/技术是使用不可变数据结构。这(当前)不是C#的强项之一,特别是与F#相比时。
答案 9 :(得分:1)
除了重复所有可以运行的“静态”定义之外,答案是“是”。静态方法可以愉快地修改类本身的状态(通过静态变量表示),并且甚至修改类的实例状态(特别是,当它们传递一个实例或一组实例时)。 但是,大多数情况下,在没有状态更改的情况下,您将使用静态方法。最重要的例子是查找或创建实例(工厂方法)。
那就是说,真正的答案是“不”。在现实生活中(例如,通过HTTP进行Web服务,或与任何类型的Orb交互),服务从不使用实际的静态方法公开其服务方法。您通常调用静态方法来获取服务的实例(或服务工厂的实例,从中获取实例!),然后使用它。 这是因为您的服务代理在内部需要跟踪它的位置。因此,虽然你的方法对你来说似乎没有状态,但实际上并非如此。
希望这不会太混乱:)。
答案 10 :(得分:1)
静态类不是无状态的。它仍然可以有变量,虽然是静态的,但却具有状态。
没有任何类级变量的静态类是无状态的。它没有数据。
答案 11 :(得分:0)
这通常是正确的。但是,您可以使用静态变量,这允许静态方法具有状态。例如,拿这个FooBarFactory类:
class FooBarFactory
{
private static _id = 0;
public FooBar MakeAFooBar()
{
FooBar foo = new FooBar();
foo.ID = _id;
_id++;
}
}
class FooBar
{
public int ID {get;set;}
}
在这种情况下,你的静态方法具有最小的状态,但它(可能)是必要的。
答案 12 :(得分:-1)
如果您想要一个具有状态的单个实例,请使用单例模式;它使意图明确表明你正在使用单一事件。
然后,我会将所有静态类和方法视为无状态。它只是有助于保持理智。