开发者

what is a stateless class?

开发者 https://www.devze.com 2023-04-10 14:35 出处:网络
I would like to know what are drawbacks of a stateless class (if any)? Has anyone seen a real-world application where some use case mandated the creation of a statele开发者_运维问答ss class (No hello

I would like to know what are drawbacks of a stateless class (if any)? Has anyone seen a real-world application where some use case mandated the creation of a statele开发者_运维问答ss class (No hello world please )? I think a stateless class means a class without any fields.


Here's a real world example: Writing plugins for Microsoft Dynamics CRM.

In that doc you'll see a note that says: "The plug-in's Execute method should be written to be stateless". And basically what it means to be a stateless class is that there should be no global variables (except for a few special cases, which I won't get into unless asked).

The reason why this is mandated by CRM upon plugin developers is because CRM tries to improve performance by caching and re-using instances of plugin classes. The way CRM executes its plugins is something roughly like this:

Main thread:

YourCustomPlugin yourCustomPluginCached = new YourCustomPlugin();

then later: Thread1:

yourCustomPluginCached.Execute(context1);

and Thread2:

yourCustomPluginCached.Execute(context2);

What some developers do wrong is they will create a global variable to store the Context, which they set as the first line in the Execute() method. That way they don't have to pass it between all their methods. But this is actually a huge mistake. Because if they do that, and in the scenario above, if the execution in thread2 begins before the execution from thread1 finishes. That would mean that context1 in thread1 would be overwritten with context2. And now that plugin will have some unexpected result. In 99% of cases, even when developed incorrectly this way, there are no problems, or no noticeable problems. But in 1% of cases, it will cause something to go wrong, and that something will be incredibly difficult for the dev to figure out what went wrong, and will probably never occur when they are testing/debugging. So it will probably go unfixed for a long time.


I never heard "stateless class", but I think you mean immutable objects (very useful notion!). Or maybe a class which doesn't have any fields, so usually it looks like just bunch of pure functions.


If by stateless class you mean a class of immutable objects, then the drawback is that mutating operations need to copy an object instead of changing it in-place. That might be expensive.

I use these things quite often, pretty much whenever an object's behavior is determined by some input that can be processed all at once. A recent example is a statistical language model that I implemented: the model parameters were determined entirely in the constructor based on training input, and then the model could be queried for probability estimates on unseen text, but not modified. Immutability wasn't strictly mandated, but modifying the object didn't make sense, since there was no need to add data later on (in which case much of the computation had to be redone anyway).


I too am not sure what you mean by that term, but I assume it to mean a class with no fields, as the state of an object is actually the content of its fields.

Now, usually you'd use this kind of class as a collection of related functions - say, a certain Utils class. The common way to use this kind of class is by making its method static, so you don't actually have to create an instance of the class.

The only reason I can think of to actually create such a stateless object is if you'd like the actual functionality to be determined at run-time. So, if you have a UtilsBase class which offers a bunch of virtual methods and a UtilsDerived which overrides some of the methods, you can pass whoever needs to use the utils a reference to UtilsBase, and create the actual utils object at run-time, according to the specific needs.


A bit late, but here is my share. I am sure the poster meant a stateless object. Please, people don't make it so dramatic.

Let's get to business. Some commenters asked about static. When static is used in a class, which should be used sparingly, all those members holding the static keyword now belong to the class and not anymore to the object. They are part of the class. For example:

Declaring a Person class with a static property called Name does not make sense

public class Person
{
    public **static** string Name { get; set; }
}
  • by the way another word for static is "Shared" which is used in VB.NET.

If we once set the name on the Person, then that name is shared everywhere because it does not belong to the object, but to the class itself. In real world you would not call all people "Jhon", or all your customers "Customer1". Each one will have a different name, surname, phone, address, etc. The moment we set these properties, this object becomes stateful, instead of stateless. It has a name, an address, etc. The properties of an object defined in a class make it stateful.

Here Name property belongs to the class, not part of the object:

Person.Name="Fili" //You would not call every person Fili in your application.

Let's redeclare the Person class by removing the static keyword:

public class Person 
{
    public string Name { get; set; }
}

In the example below, the object is stateful. It has a state, it has been given a name, "Jhon", which can be changed later. A person can change his name to Jimmy, for example. Once that is done, then the state of that object has changed from Jhon to Jimmy.

//From
Person person1 = new Person {
    Name = "Jhon";
}

//to
person1.Name = "Jimmy"

The object 'person1' still is the same object, but its state has changed. It is not the same anymore. It has a different name. So, person1 had a state until a cetain point in time, but then its state was changed. Now, it is in a different state.

Now, creating a new person is something new which has nothing to do with the person1. Person2 has its own state.

Person person2 = new Person {
    Name = "Imir";
}

Using the static class: Person.Name="Fili" it has a state, but it belongs to the class and it is shared everywhere. So, a stateless object will be one that has nothing to be changed, doesn't hold a value. Will you create a person without a Name? Would you create a customer object which does not exist? No, of course not. The moment you name a person or a customer, they have a state. They exists and can change their state.

Take the example of a Airplane. When you delcare it you add a Status property for example.

public class Airplane {
  public string Status {get;set;}
}

var plane1 = new Airplane{ Status="Flying"};

So, the question arises: what is the state (status) of the plane at this moment? One would reply: it is "flying". If you change the state to "taxing", then its state is "taxing", or it is "stationary", etc.


In stateless class, all field members should be readonly type. Although c# don't have any such features which will check statelessness at compile time like:

public readonly class MyReadonlyClass
{
    public readonly double X {get;set;}
    public readonly double Y {get;set;}
    public readonly double Z {get;set;}

    public MyReadonlyClass(double x_,double y_,double z_)
    {
        X=x_;Y=y_;Z=z_;
    }
}

public readonly static class MyStaticReadonlyClass
{
    public readonly static double X {get;set;}
    public readonly static double Y {get;set;}
    public readonly static double Z {get;set;}

    static MyStaticReadonlyClass(double x_,double y_,double z_)
    {
        X=x_;Y=y_;Z=z_;
    }

}


Stateless is something which should not preserve its state or in other words we can say that every time we use the any functionality or member of that class then previously used/set variables should not affect the next use of that class/functionality.

Consider the following code snippet (Ignore the standards)-

class Maths {
int radius;

public void setRadius(int r) {
    this.radius = r;
}

public float getCircleArea() {
    return (float) (3.14 * radius * radius);
}
}

public class Geometry {
public static void main(String[] args) {
    Maths m = new Maths();
    m.setRadius(14);
    System.out.println(m.getCircleArea());
}
}

if some other running thread changes the value of radius in class Maths then getCircleArea() would give us different results because the state of the variable 'radius' can be change as it is a global variable. This problem occurs mainly in web application where we use bean containers. Most of the beans are Singleton and only has one copy. If we use global variables then there is a possibility that value of a global variable will change.

To make a stateless class try to use local variable so that the scope of the variable will be limited. Example of the above getCircleArea() will be.

public float getCircleArea(int radius) {
    return (float) (3.14 * radius * radius);
}
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号