Stateful or stateless class class?

Transfer: http://developer.51cto.com/art/201603/507198.htm

I believe we all know what object-oriented programming. But sometimes we also need to take the time to decide what kind of property is given to a particular class. Obviously, if the class attribute assignment is wrong, then we are likely to encounter serious follow-up questions. Here we will discuss what classes should have a state, and which classes should be stateless.

What is the status of objects means

Before we have a state with no state class category, first of all you should have in-depth understanding of the state of the object. As stated in the dictionary, the state is referred to as "the particular condition of someone or something is located at a specific point in time."

When we look at the program and consider the state of the object at a particular point in time, it narrowed the scope related to the property or member variable to the value of objects in a given time. Then the properties of the object Who decides? The answer is class. Who determines the class attribute with the members? The answer is that programmers write the class. Who is the programmer? That you are reading this article friends. So we really need their expertise in how decisions each class of property?

The answer is probably no. At least I've seen a lot of Indian programmers just to pay to join the program industry, they obviously lack the ability to make the right choice of property. First, such knowledge can not learn directly from the school. Specifically, we need to invest a lot of time to gain experience, and to explore the right choice - this is more of an art than technology. Engineering and technology tend to have strict rules, but the art is not. Even when experienced practitioners fifteen years of programming time, I need to consider how a class attribute even how to select a name for the class, still need to cost a lot of thought.

Then we can define attributes specific needs by the rules? In other words, the object of which state what properties should be included? Or, whether the object should always prefer stateless? With the view below.

Entity class / business objects

Programming areas flooded with names such as the entity class and the business objects, etc., are intended to reflect the state of a certain definite class. If we choose the Employee class as an example, its role is to contain the status of an employee. So what specific state content? EmpID, Company, Designation, JoinedDate etc ...... As the textbook says, this class should be stateful, no doubt.

But how should we pay calculated?

Should we add CalculateSalary () method in the Employee class?

You should use SalaryCalculator class, whether they should be included Calculate () method?

If there SalaryCalculator categories:

  • If it should contain attributes such as BasicPay, DA HRA, etc.?
  • Employee object or whether it should be injected into the SalaryCalculator via the constructor as private member variables?
  • Or whether it should display the Employee SalaryCalculator public property (Java in the Get & Set Employee method)?

Assist / Operation / modify a class

These classes are responsible for performing a particular task. SalaryCalculator belongs to one of them. These classes have a variety of naming, for embodying their behavior and expressed by a prefix or suffix, for example:

  • SomethingCalculator categories, for example: SalaryCalculator
  • SomethingHelper categories, for example: DBHelper
  • SomethingController categories, for example: DBController
  • SomethingManager类
  • SomethingExecutor类
  • SomethingProvider类
  • SomethingWorker类
  • SomethingBuilder类
  • SomethingAdapter类
  • SomethingGenerator类

People can express different prefixes or subsequent class status, where we will not discuss too much.

Can we add a status to these classes? I suggest that you stateless dealing with these classes. Let's look at the specific reasons.

Mixed class

The package defined in object-oriented programming Wikipedia analysis, the concept of "...... packed data and functions into a single component." Does this all means that the method for operating the object should be packed into the entity class which ? I think not. Entity class should use stateful access methods, e.g. GetName (), SetName (), GetJoiningDate and getSalary () and the like. But CalculateSalary () should be excluded. why?

According to the single responsibility principle: "a class should be used only for a single reason for the change." If we add to the Employee class among CalculateSalary () method, the class due to the following two reasons are changed:

Employee class status changes: when a new property is added to the Employee of them.

Change the calculation logic appear.

Let us then clearly organize it again. Suppose we have two classes. Employee class and SalaryCalculator class. So how do the two butted against each other? A variety of implementations. First create a class object in GetSalary SalaryCalculator method, and call Calculate () is to set the variable remuneration of the Employee class. In this case, the class will likewise show characteristics of the entity classes and helper classes, we refer to as mixed classes. I personally do not recommend that you use this hybrid class.

Basic principles: "Once you find your own classes may have been transformed into mixed classes, consider its reconstruction If we find that your class does not belong to any of the above categories, please stop work immediately subsequent programming.."

Auxiliary / operation in a state class

Stateful auxiliary class will bring what issues? Before giving an answer, let us first understand the different status values ​​can contain combinations of SalaryCalculator class through the following example:

A scene - a basic value

class SalaryCalculator 
 
 { 
 
     public double Basic { get; set; } 
 
     public double DA { get; set; } 
 
     public string Designation { get; set; } 
 
     public double Calculate() 
 
     { 
 
         //Calculate and return 
 
     } 
 
 } 

Shortcoming

Then Basic salary is likely to "Accountant" then Designation may be "Director", both completely unable to match. In this case, we can not guarantee the independent operation by any mandatory SalaryCalculator way.

Similarly, if it is to perform at-threaded environment, it will lead to fail.

Scene II - i.e., state objects

class SalaryCalculator 
 
{ 
 
    public Employee Employee { get; set; } 
 
    public double Calculate() 
 
    { 
 
        //Calculate and return 
 
    } 
 
} 

Shortcoming

If two threads share SalaryCalculator objects, and different employees for each thread, the whole order of execution logic errors may result in the following:

  • Thread 1 target set employee1
  • Thread 2 target set employee2
  • Thread 1 calls the Calculate method and to obtain employee2 Salary

Which can be seen Employee association can be injected through the constructor, and so that the read-only attribute. Next we need to create SalaryCalculator object for each Employee object. Therefore, we do not design *** helper classes in this way.

Scene Three - stateless

class SalaryCalculator 
 
{ 
 
    public double Calculate(Employee input) 
 
    { 
 
        //Calculate and return 
 
    } 
 
} 

This is the case of an almost ***. But to consider is, how to use all the methods are not a member of any variable, then how do we guarantee that belong to non-state class.

As SOLID second principle says: "Extended open, closed modifications." What does this mean? Specifically, when we write a class, you must ensure that it is thoroughly completed, that is not to subsequent modifications. At the same time, it should also have the ability to achieve extended by subclassing the cover. So, our final class should look like this:

interface ISalaryCalculator 
 
{ 
 
    double Calculate(Employee input); 
 
} 
 
class SimpleSalaryCalculator:ISalaryCalculator 
 
{ 
 
    public virtual double Calculate(Employee input) 
 
    { 
 
        return input.Basic + input.HRA; 
 
    } 
 
} 
 
class TaxAwareSalaryCalculator : SimpleSalaryCalculator 
 
{ 
 
    public override double Calculate(Employee input) 
 
    { 
 
        return base.Calculate(input)-GetTax(input); 
 
    } 
 
    private double GetTax(Employee input) 
 
    { 
 
        //Return tax 
 
        throw new NotImplementedException(); 
 
    } 
 
} 

As I have repeatedly stressed before, it should be oriented programming interface. In the above code snippet, when I omitted due to space considerations interface implementation. In addition, computational logic should always be within the protected function, so as to ensure the derived class can be called when necessary.

The following is the correct consumption Calculator class:

class SalaryCalculatorFactory 
 
{ 
 
    internal static ISalaryCalculator GetCalculator() 
 
    { 
 
        // Dynamic logic to create the ISalaryCalculator object 
 
        return new SimpleSalaryCalculator(); 
 
    } 
 
} 
 
class PaySlipGenerator 
 
{ 
 
    void Generate() 
 
    { 
 
        Employee emp = new Employee() { }; 
 
        double salary =SalaryCalculatorFactory.GetCalculator().Calculate(emp); 
 
    } 
 
} 

Wherein Factory class is responsible for determining which logic package subclasses use. As described above can select a state in which, also reflect the dynamic selection mechanism. The only reason this class is to create an object is changed, so we did not violate the "single responsibility principle."

In the case of using a mixed class, we may or property from Employee.Salary Employee.GetSalary () call at a logic calculation as follows:

class Employee 
 
{ 
 
    public string Name { get; set; } 
 
    public int EmpId { get; set; } 
 
    public double Basic { get; set; } 
 
    public double HRA { get; set; } 
 
    public double Salary 
 
    { 
 
        //NOT RECOMMENDED  
 
        get{return SalaryCalculatorFactory.GetCalculator().Calculate(this);} 
 
    } 
 
} 

 

to sum up

"Do not programmed to think, do not think programming." This principle considerations bring me plenty of space for us, so grasp the correct type of stateful and stateless decision - which allowed state and when there is status display.

Entity class should have a state.

Auxiliary / operation category to be stateless.

To ensure that no state aid class.

If there are mixed classes, ensure they do not violate the principle of single responsibility.

Take the time were designed prior to programming class. The class design results to other colleagues to review and consider their feedback.

Carefully select the class name. These names will help us determine its status. Naming work and there is no fixed limit, here are some of my personal recommendations:

  • Entity class should be reflected in the name of the object type, for example: Employee
  • Auxiliary / working class name should reflect its role. For example: SalaryCalculator, PaySlipGenerator etc.
  • Never use verb class name, for example: CalculateSalary {} class

Guess you like

Origin www.cnblogs.com/dongruiha/p/11286416.html