Java – business rules – where are they in OOP?

I have a lesson: timetable

public class Schedule {

private int locationNum;
private int cost;
private String costReason; 
private Date weekOfChange;
private Date dayOfChange;
private String changeReason; 

// and all those getters and setters

public Schedule(int locationNum,int cost,String costReason,Date weekOfChange,Date dayOfChange,String changeReason) throws ApplicationException {
//change is all or nothing - all attributes are present or none
if((weekOfChange!=null && dayOfChange!=null && changeReason!=null) || (weekOfChange==null  && dayOfChange == null && changeReason == null))  {
this.weekOfChange = weekOfChange;
this.dayOfChange = dayOfChange;
this.changeReason = changeReason;
}
else { throw new ApplicationException();}
//similary another if block to ensure that if cost is specified 
//then there exists the corresponding reason code for it.
}
}

So far, I like my schedule course However, I did not complete the inspection, and I will have to do some other inspections:

>Is a valid store number in the locationnum database. > Is one of six different changereason codes in the changereason text database. > Wait

Usually, I do not write these in Schedule class. Obviously, I can not call DAO. from this class. Therefore, I will have a business layer and some kind of validator class, accept an object of type schedule, perform a pile of database validation in order, and collect display / any errors

Now, this is my question:

>If you think of schedule as a POJO and think that the object is not responsible for validating itself – I have to move all the code in the constructor to the validator class of the business layer But if I do, is it an arrangement? Is this what they call a violation of the principle of single responsibility? > Let me assume that I move the code in the constructor to the business layer class so that various validations are now in my business layer Let's say someone changed dayofchange to null in my data store, and now I'm loading objects from my database Now, with this object, my application can be cracked, can't it? Because I can write code and assume that the verification rules are met I think my question becomes confusing, but what I want to say is that in this case, I prefer to complete these checks in the constructor to ensure the integrity of the data hidden by the schedule class. > How is it usually done? What are best practices?

Thank you for participating in this discussion

Solution

If you really have "all those getters and setters", you need to validate your class better than constructors If the invariants of your class are that all weekofchange, dayofchange and changereason must be null or not all must be non null, then your setter will soon put your class in an invalid state Do you mean to have a maker or do you mean that your class is immutable?

Before you worry about verification, you should analyze your class View all valid states and invariants for a given state Then you'll see if your class should be mutable or immutable If you have interdependent covariates (such as weekofchange, dayofchange and changereason), it makes sense to package them into your own class and use the combination in the schedule class This will put the "rules" about these transaction fields in one place and simplify the schedule

Same as other areas of cooperation (e.g. cost and cost reasons) Then, the schedule consists of a self - validating class If both are immutable and the schedule is immutable, your self will be easier

So, answer your question: it's better for a class to define its state and invariants, and only expose the minimum value to its collaborators when feasible The responsibility for the internal status of the schedule should depend on the schedule and can be carried out relatively easily with little design

So you have

class Schedule {
         private Change change;
         private Cost cost;
         private Location location;

        public Schedule(Location location,Cost cost,Change change) {
           this.change = change;
           this.cost = cost;
           this.location = location;
        }
}

Just like coloborators

public class Change {
    private Date weekOfChange; //shoudln't these two fields be one,a date is a date after all??
    private Date dayOfChange; //shoudln't these two fields be one??
    private String changeReason; 

    public Change(Date weekOfChange Date dayOfChange,String changeReason) {
      this.weekOfChange = weekOfChange;
      ...etc.
    } 
}

Although I strongly recommend that you protect your class invariants by defensively copying any mutable values passed by client code

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>