Java 枚举vs子类,哪一种是面向对象的设计?
这是我作为长度计算器编写的代码,用于计算不同类型单位的长度。我想让它以面向对象的方式设计Java 枚举vs子类,哪一种是面向对象的设计?,java,oop,enums,subclass,Java,Oop,Enums,Subclass,这是我作为长度计算器编写的代码,用于计算不同类型单位的长度。我想让它以面向对象的方式设计 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 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;
}
}
我使用enumUnit
并将不同的单位m/cm/mm
作为其成员
但我读过这篇文章,它有一个类似的例子,标记为非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";
}
}
它不是枚举,但方法非常类似,在内部使用一些状态来表示不同的类型
并给出了使用子类的OOP示例:
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";
}
}
根据他的想法,我认为我的代码应该重新编写为:
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;
}
}
我能感觉到我的代码的两种设计之间的一些差异,但仍然不能准确地说出它是什么
一些问题:
enum
的第一个版本是否不被视为OOP我认为这有点基于观点 基本思想是,在“enum”(或字符串常量,或其他)情况下,您没有oop允许的灵活性,而只是通过对象的属性而不是其类型进行标识的一种方法。将男/女类而不是
sex
作为类成员是一种很好的做法,因为它允许您进一步扩展代码(即,如果您想跟踪男性的胡须长度,则此属性对女性毫无意义)
然而,拥有一个对象可能和其他方法一样糟糕。在你的特殊情况下,我认为你做了一些过度的设计。我确实建议遵循迭代方法,我将使用person示例来说明它
最初,实现一个具有属性sex
的类Person(枚举类型就可以了)。如果您开始看到不同类型之间的分离(在属性或方法方面),则可以在类型之间执行所需的分离
在您的具体案例中,我认为为不同的单元设置不同的类有点不切实际(很难扩展,因为您需要为每个单元设置一个类——想想像皮米计、飞秒计之类的东西),而且没有必要。但是,更好的方法是在内部将长度存储在一些标准单位(即米)中,并在constructor/setter/getter中转换为所需的任何单位
enum
的第一个版本是否不被视为OOP男性
与女性
的例子中得到了很好的说明但是,这不会自动“[降低]代码的复杂性”。较小的概念表面积可以显著提高代码库的复杂性。所以,仅仅因为某些东西使用了继承或其他面向对象的设计技术,并不一定意味着它是有益的
我们应该总是考虑第二个版本吗?
简单明了,“不”。你永远不能说绝对的话(*排队鼓点讽刺)。当您的hello world程序遇到接口问题时,为了使其严格面向对象,这并不一定意味着它是一个好的设计。有些情况适合于面向对象的结构,有些则不适合;这确实需要根据具体情况来确定。我没有权利开始评论,因此在回答部分写下我的意见 依我看,你所做的是正确的。通过使用枚举,您可以在枚举变量中改变特性(在示例中为速率)。因此,您不再需要if-else条件,就像我们在个人示例中所做的那样。此外,通过使用枚举,您已经使代码一致,并且不会导致代码按类爆炸 回答你的问题: (a) 它被认为是面向对象的 (b) 当您不知道面前的对象数量时,可以使用第二种方法。也就是说,如果我们知道人们明天可以推出一个新的儿童班。在您的情况下,长度可以用mm、cm等单位测量,这些参数的数量在手之前就已经知道了。因此,以这种方式编写代码是非常好的。
(c) 取决于您希望如何设计。第二种方法也是正确的。你做的很好。
Person
示例的缺点是if
。一个类中有两种不同的行为应该通过多态性建模。你所做的基本上是:-人的问题在“有效的Java-第20项”中得到了很好的解释,你通常可以通过谷歌发现,当然,这个问题不太可能有“最佳答案”。设计方式将主要取决于您的问题域以及环境中的约束。你到底想说什么?