Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Enums vs Subclasses, which is Object-oriented design?

This is the code I wrote as a length-calculator for lengths with different kinds of unit. I wanted it to design it in Object-oriented.

public class Length {

    private final double value;
    private final Unit unit;

    public Length(double value, Unit unit) {
        this.value = value;
        this.unit = unit;
    }

    @Override
    public boolean equals(Object obj) {
        Length length = (Length) obj;
        return this.unit.toMM(this.value) == length.unit.toMM(length.value);
    }

    public Length add(Length added) {
        return new Length(this.unit.toMM(this.value) + added.unit.toMM(added.value), Unit.mm);
    }

    public Length subtract(Length another) {
        return new Length(this.unit.toMM(this.value) - another.unit.toMM(another.value), Unit.mm);
    }

}

enum Unit {
    m(1000), cm(10), mm(1);
    private final int rate;

    Unit(int rate) {
        this.rate = rate;
    }

    public double toMM(double value) {
        return rate * value;
    }
}

I use the enum Unit and let different units m/cm/mm as its members.

But I read this article about "OOP vs Non-OOP", it has a similar example which is marked as Non-OOP:

public class Person {

    private boolean _male; // true means male, false means female.

    public Person (boolean genderFlag) {
        _male = genderFlag;
    }

    public String getGender () {
        return _male? "male": "female";
    }
}

Which is not an enum, but the approach is quite similar, use some state internally to represent different types.

And it gives the OOP example using subclasses:

public abstract class APerson {
    public abstract String getGender();
}

public class Man extends APerson {
    public String getGender() {
        return "male";
    }
}

public class Woman extends APerson {
    public String getGender() {
        return "female";
    }
}

Apply to his ideas, I think my code should be re-written as:

interface Unit {
    public double toMM(double value);
}

public class Meter extends Unit {
    public double toMM(double value) {
        return 1000 * value;
    }
}

public class Centimeter extends Unit {
    public double toMM(double value) {
        return 10 * value;
    }
}

public class Millimeter extends Unit {
    public double toMM(double value) {
        return value;
    }
}

I can feel some differences between the two designs of my code, but still can't tell exactlly what it is.

Some questions:

  1. Is the first version with enum not considered as OOP?
  2. What's the real benifit of the second version with subclasses?
  3. Should we always considered the second version for such cases?
like image 868
Freewind Avatar asked Nov 06 '25 20:11

Freewind


2 Answers

  1. Is the first version with enum not considered as OOP?

No, the first version is an object oriented design. The latter, however, is certainly more object oriented, taking advantage of inheritance to determine a behavioral characteristic.

Based on that article you mentioned, I would say that the author thinks that the former is not an object oriented design, but you'll get a plethora of answers on this subject; you've been warned.

  1. What's the real benefit of the second version with subclasses?

As the article notes, it may be less complex to not have to interrogate one's one state, and this is well illustrated in the male versus female example. However, this does not automatically "[reduce] the complexity" of the code. A smaller conceptual surface area can make a significant difference in the complexity of a code base. So, just because something is using inheritance or some other object oriented design technique, it doesn't necessarily mean it's beneficial.

  1. Should we always consider the second version for such cases?

Plain and simple, 'no'. You can't speak in absolutes, ever (*queue drums for irony). When your hello world program is suffering from interface-itis in order to keep it strictly object oriented, that doesn't necessarily mean it's a good design. Some situations lend themselves to the object oriented structures and some don't; it really needs to be determined on a case by case basis.

like image 114
Mike Avatar answered Nov 09 '25 14:11

Mike


I don't have the privilege to start commenting and hence writing my opinion in answer section.

IMO, what you are doing is the right thing. Using enums, you are using the ability to vary peculiarities (rate in your example) within the enum variables. Hence you no longer require if else condition as we do in person example. Also, by using enums you have made the code consice and do not inflict your code by class explosion.

To answer your q: (a) it is considered oops (b) you can use second methodology when you don't know the number of objects before hand. I.e. if we know that people can come up with a new child class tomorrow. In your case, length can be measured in mm, cm and so on, and the number of these parameters are known before hand. And hence it is perfectly good to code it in that manner. (c) depends on how you wish to design. Second way is correct too.

like image 27
achin Avatar answered Nov 09 '25 14:11

achin



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!