简体   繁体   中英

Advice needed on coding best practices

I want to understand if the following coding practice is good or bad practice.

I pass a Value Object to a method as a parameter and the called method is returning the same parameter Value Object. I particulary think since it the same object be referenced we dont need to put it as return type.

Class A
{
  initStudent()
  {
    Student studentObj = new Student();
    //do some processing

    studentObj = processStudent(studentObj);
  }

  processStudent(Student pObj)
  {
    //do something

    return pObj;
  }
}

it is sometimes needed to get a parameter and return a parameter of the same type, even if the manipulation is on the parameter for some reasons:
1. if the object is immutable (ie String)
2. if the object actualy can be changed (a good example for it is <T>[] List.toArray(<T>[]) where if there is not enough space in the parameter array, a new one is created, otherwise, the array is written on the parameter)
3. it also implicitly tells the user the value might be changed...
4. don't be afraid to do it if needed, many projects use it (ie Apache Lucene)

Yes you shouldn't be returning it. Use access modifiers and return types properly.

public class A
{

  public Student initStudent()
  {
     Student studentObj = new Student();
     //do some processing

     processStudent(studentObj);

     return studentObj;
  }

  private processStudent(Student pObj)
  {
       //do something
  }
}

Indeed you don't need to return the object. Just return nothing.

Class A
{

  void initStudent()
  {
     Student studentObj = new Student();
   //do some processing
    processStudent(studentObj);
  }

 private void processStudent(Student pObj)
   {
       //do something
   }

}

Edit: Also, as adarshr pointed out, the Student object that you created will be of no use if it does not "go out" of the initStudent() method. Probably you may want to return it, or store it in a Collection instance field.

I think it is a good practice to return the object if the method modifies it. So the signature of the method makes it clear that the object gets modified and you don't have implicit side effects.

If the method is not intended to modify the object you should not return it.

what about setting studentObj as a member variable as it's the same class

EDIT: I suppose that processStudent will call some methods on Student, which is called feature envy - that method 'wishes to be in Student'. This is not a good practice, instead create that processing inside Student class by creating new method

I would rather aim toward a dependency injection combined with the decorator design pattern

In the main code I would handle the student initialisation and pass it to get it decorated

studentObj = new Student();

decoratedStudentObj = new A(studentObj);

finalStudentObj = decoratedStudentObj.getStudent()

Which would trigger the getStudent() method in all of the different classes and modify all the student object in casacade.

So you could eventually end up with something like this :

studentObj = new Student();

decoratedStudentObj = new A(studentObj);

decoratedStudentObj = new A(decoratedStudentObj );

decoratedStudentObj = new B(decoratedStudentObj);

decoratedStudentObj = new C(decoratedStudentObj );

finalStudentObj = decoratedStudentObj.getStudent()

An other advantage from dependency injection would allow you to have different student types defined and you would have to duplicate any of your code as long as all students objects implements the same interface/method set

IE:

studentObj = new Student()

decoratedStudentObj = new A(studentObj);

finalStudentObj = decoratedStudentObj.getStudent()


highSchoolStudentObj = new HighSchoolStudent()

decoratedHighSchoolStudentObj  = new A(highSchoolStudentObj);

decoratedHighSchoolStudentObj = new B(decoratedHighSchoolStudentObj );

finalHighSchoolStudentObj   = decoratedHighSchoolStudentObj .getStudent()


collegeStudentObj = new CollegeStudent()

decoratedCollegeStudentObj  = new A(collegeStudentObj );

decoratedCollegeStudentObj  = new C(decoratedCollegeStudentObj);

finalCollegeStudentObj  = decoratedCollegeStudentObj.getStudent()

And finally its easier to implement UnitTesting since you can easily mock the student class to test your processing class independantly.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM