-3
\$\begingroup\$

I am writing an application which has lot of checks. Most of the logic is based on conditions. How can make such code comply with SOLID principles? I cannot give the code of my application here hence I will try to simulate problem with a simpler example.

class Person {
    public String gender;
    public int age;
    public int birthYear;
    public Benefits b;

    public Benefits getB() {
        return b;
    }

    public void setB(Benefits b) {
        this.b = b;
    }
}

class Student extends Person {
    public boolean isEngineerStudent;
    public boolean isMedicalStudent;
}

class Employed extends Person {
    public boolean privateSector;
    public boolean governmentSector;
    public int baseIncome;
}

class Benefits {
    public boolean isInsuraceAvailabe;
    public boolean isStipendAvailable;
    public boolean isPensionAvaiable;
    public boolean isHealthCheckupAvailable;
    public boolean isTransportAvaiable;
    public boolean isLabFacilityProvided;
    public boolean isComputerFacilityProvided;

}

public class EnableBenefits {

    public void enbableBenefits(Person p) {
        Benefits b = new Benefits();
        p.setB(b);
        if (p instanceof Student) {
            Student s = (Student) p;
            if (s.isEngineerStudent && s.age > 22) {
                s.b.isStipendAvailable = true;
                s.b.isComputerFacilityProvided = true;
            }
            if (s.isMedicalStudent && s.age > 20) {
                s.b.isStipendAvailable = true;
                s.b.isLabFacilityProvided = true;
            }
        }

        if (p instanceof Employed) {
            Employed e = (Employed) p;
            if (e.governmentSector == true && e.age > 40 && e.gender.equalsIgnoreCase("F") && e.birthYear <= 1960) {
                e.b.isPensionAvaiable = true;
                e.b.isInsuraceAvailabe = true;
                e.b.isTransportAvaiable = true;
            }
            if (e.governmentSector == true && e.age > 40 && e.gender.equalsIgnoreCase("M") && e.birthYear <= 1960
                    && e.baseIncome < 20000) {
                e.b.isPensionAvaiable = true;
                e.b.isInsuraceAvailabe = true;
            }
            if (e.privateSector == true & e.gender.equalsIgnoreCase("M") && e.birthYear <= 1960) {
                e.b.isInsuraceAvailabe = true;
                e.b.isTransportAvaiable = true;
            }
        }
        p.b.isHealthCheckupAvailable = true;
    }

}

I have purposefully made the access modifiers of instance variables as public so that it does not have too much code.

Though the code does not have too many conditions and logic, just imagine the code for student and employee logic are in hundreds of lines.

Questions:

  1. How can I write huge if conditions in a better way? Can I use Lamba here? Of course the if condition is not too big but in my real application I can easily have 8 conditions.

    if (e.governmentSector == true && e.age > 40 && e.gender.equalsIgnoreCase("M") && e.birthYear <= 1960
                        && e.baseIncome < 20000) {
                    e.b.isPensionAvaiable = true;
                    e.b.isInsuraceAvailabe = true;
                }
    
  2. Is it better to write this in the inner class?

    if (p instanceof Student) {
                Student s = (Student) p;
                if (s.isEngineerStudent && s.age > 22) {
                    s.b.isStipendAvailable = true;
                    s.b.isComputerFacilityProvided = true;
                }
                if (s.isMedicalStudent && s.age > 20) {
                    s.b.isStipendAvailable = true;
                    s.b.isLabFacilityProvided = true;
                }
            }
    
\$\endgroup\$
0

1 Answer 1

2
\$\begingroup\$

The simplest way would be to continue with inheritance here. That will give you MedicalStudent and EngineerStudent instead of using boolean fields on Student.

Then you do the same for benefits to avoid a lot of duplication in your code.

And lastly you can extract your conditions to separate methods until your logic will be super simple.

if (eligibleForMedicalBenefits(p)) {  
    p.setBenefits(medicalBenefits);
}

Your classes can look like this.

abstract class Person

class Student extends Person

class MedicalStudent extends Student

class EngineerStudent extends Student

The same goes for Employed entity and Benefits.

After these changes are introduced the eligibility method will be super simple.

public boolean eligibleForMedicalBenefits(Person p) {
    return ((p instanceof MedicalStudent) && p.age > 22);
}
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.