I recently made a recommendation to on开发者_开发问答e of my colleagues stating that on our current project (C#) "services should be stateless and therefore static".
My colleague agreed and indicated that in our project the services are (and should be) indeed stateless. However my colleague disagreed that static implies no state and that stateless should mean static.
My questions is “does a method marked as static imply that it requires no state and that in a majority of cases should stateless methods be made static”.
Static nearly means global. There is still an instance, and there is still state in that instance, but it is the static instance, which means there is only one and all callers always refer to that one.
does a method marked as static imply that it requires no state
1) No. You cannot say static methods imply that it requires no state because static methods can access static/singleton resources.
a majority of cases should stateless methods be made static
2) Yes. Methods that require no state, therefore require no instance, should be generally made static.
A static method, in C#, can access the static variables of its containing class, and if it does, it's not stateless. I've seen some painful instances of non-reentrant "stateless" static methods triggering fun race conditions.
A truly stateless method can indeed be made static, and generally should.
I find it rather scary to say that stateless is the same as static as these are two different worlds. Stateless means that there is no state kept, i.e., a perfect example is an HTTP connection (once data is send, the connection is closed and there's no memory kept), where we are actually trying to do our best to maintain state regardless (login state for one).
Static on the other hand is a term used to describe a way that a method is invoked. In C# that means that a method can be invoked without a class instance, but an instance of a class is not the same as state. There's still the static instance and that's perfectly capable of maintaining state: any static member variable, field or property can maintain state. A static method or class is also perfectly capable of maintaining state by using memory mapped files, a database or whatever. Static is a calling convention, nothing more and is not related to being stateless or not.
I think his statement makes about as much sense as "Democracies should use yellow paper ballots".
He is mixing a high level design concepts "stateless services" with a low level technical implementation detail "using static classes".
Stateless services can (and have been) implemented in languages which supports only static variables (e.g. COBOL, RPG) and languages which dont even allow static variables (Erlang etc.).
I could easily imagine a case where stateless service was implemented largly using static classes, becuase they were there and already implemented the correct business logic, although its generally considered good Java programing practice not to use static classes unless you really need to.
He also serioulsy misunderstands what "static" is all about -- a static variable is a way of storing state between invocations -- and would therefore seem a better match with a "stateful" service.
static is a language keyword and state is a design concept. There's an obvious relationship between these two things, but it is a relationship of the concrete to the metaphysical, not a relationship of cause and effect. It is possible for static methods to refernce some kinds of state information.
Regarding stateless methods, here we are talking about method that don't reference a class instance, i.e. a this pointer. Marking these methods as static improves the clarity of the code and is consistent with best practices. Note that in this case we are talking a specific kind of "statelessness" and not making a general commentary about the use of stateful contexts.
static can be stateful. you just have to define static containers for said state. and the containers are shared among all calls to your static methods.
The short answer to your question is "no", static
does not imply "no state".
In reference to your other comments, static
can be used to help you implement a stateless service, but static
alone is not sufficient. Another tool/technique to help make something stateless is to use immutable data structures. This (currently) isn't one of C#'s fortes, especially when compared to F#.
Beyond rehashing all the definitions of "static" that one can run through, the answer is "yes." Static methods may happily modify the state of the Class itself (represented through static variables), and even modify the state of instances of the class (notably, when they get passed an instance or set of instances). However, most of the time, you will use static methods in cases where no state is changed. The most important example is to find or create an instance (factory methods).
That said, the real answer is "no." In real life (Web Services over HTTP, for instance, or interaction with any kind of Orb), services never expose their service methods using actual static methods. You usually call static methods to get an instance of the service (or an instance of the service factory, from which you get an instance!), and then work with that. This is because your service proxy, internally, needs to keep track of where it's at. So while your methods seem stateless to you, they are really not.
Hope this wasn't too confusing :)
A Static class is not stateless. It can still have variables which, although static, have a state.
A Static class without any class-level variables is stateless. It holds no data.
Every class has a class definition structure, where static fields are represented and stored. Every "instance" of the class has access to the static fields stored in the class definition (a data structure caleld CORINFO_CLASS_STRUCT
). Even when NO instances have been created, code anywhere in your assembly can access these static class-level fields by using the syntax classname.StaticFieldName
, without any instance at all.
Since the values stored in these static class-level fields are persisted, they are definitely state. In fact, they are state shared by not only any instances of the class that might exist, they are shared throughout the assembly, whether any instances have been created or not.
Even more significant, since once a CORINFO_CLASS_STRUCT
class definition has been loaded, unlike a true instance of the class, it is never unloaded until the assembly (or the AppDomain) is unloaded, so it is arguably more stateful than any instance field defined in a class, because an instance field dissapears when the instance gets garbage collected.
For more information check out CORINFO_CLASS_STRUCT
link to Don Boxes' great book, Essential .Net
That is generally correct. However you can have static variables, which allow your static methods to have state. For instance, take this FooBarFactory class:
class FooBarFactory
{
private static _id = 0;
public FooBar MakeAFooBar()
{
FooBar foo = new FooBar();
foo.ID = _id;
_id++;
}
}
class FooBar
{
public int ID {get;set;}
}
In that case your static method has a minimum of state, but it's (probably) neccessary.
If you want a single instance with state, use a singleton pattern; it makes the intent clear that you're working with a single-occurrence object.
From that, I would then treat all static classes and methods as stateless. It just helps keep sanity.
精彩评论