我在我的一个程序中使用装饰器模式来装饰具有不同毕业要求的课程。几个例子:
new BasicCourse("Course Foo", 1); // parameters are name and credits
new DisciplinaryBreadth(DBR.MATH, new BasicCourse("Course Foo", 1));
new IntroToHumanities(IHUM.FIRST_QUARTER,
new ProgramInWritingAndRhetoric(PWR.FIRST_YEAR,
new BasicCourse("Course Bar", 2)));
new ProgramInWritingAndRhetoric(PWR.FIRST_YEAR,
new IntroToHumanities(IHUM.FIRST_QUARTER,
new BasicCourse("Course Bar", 2)));
后两者在交换性质上是相同的。
我正在实现hashcode()
and equals()
,以便可以在 HashMap 中使用 Courses。我必须更改 Eclipse 的自动生成的 equals 函数,以便可交换的课程彼此相等。我不了解哈希码的生成以及我的平等,所以我想知道我是否需要对哈希码函数做同样的事情。
以下是 Eclipse 为每个装饰器提供的内容:
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((inner == null) ? 0 : inner.hashCode());
result = prime * result
+ ((requirement == null) ? 0 : requirement.hashCode());
return result;
}
这会为交换课程产生相同的哈希吗?
编辑
每个装饰器都有一个requirement
变量,该变量对应于具有该装饰器的课程所满足的要求。例如,DisciplinaryBreadth 类具有 DBR 类的要求,它是可能的 Disciplinary Breadth 要求的枚举。ProgramInWritingAndRhetoric 类具有 PWR 类的要求,这是可能的 Program in Writing 和 Rhetoric 要求的枚举。等等。
每个装饰器中的需求变量是一个不同的枚举。所有课程都实现了获得各种毕业要求的方法(例如getDbrs()
,getIhum()
)。
装饰器调用他们内部课程的方法来处理除了他们定义的需求之外的所有需求。例如 IntroToHumanities 类调用inner.getDbrs()
and inner.getPwr()
,但使用它的需求变量作为它的getIhum()
方法。getName()
他们还为and方法调用其内部 Course 的getCredits()
方法,而 BasicCourse 类使用其构造函数中设置的最终成员定义这些方法。
inner
变量只是每个装饰器包装的内部课程。内部变量和需求变量在每个装饰器的构造函数中设置并且是最终变量。
这是 ProgramInWritingAndRhetoric 类的 equals 方法:
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (!(obj instanceof Course))
return false;
Course other = (Course) obj;
if (getName() == null) {
if (other.getName() != null)
return false;
} else if (!getName().equals(other.getName()))
return false;
if (getCredits() != other.getCredits())
return false;
if (!getDbrs().equals(other.getDbrs()))
return false;
if (!requirement.equals(other.getPwr()))
return false;
if (!getIhum().equals(other.getIhum()))
return false;
if (!getEc().equals(other.getEc())) //another Graduation Requirement
return false;
return true;
}
我跳过了一些对 null 的检查,因为我在构造函数中检查了它们,所以你不能使用 null IHUM 创建课程,例如。其他毕业要求的实现也类似,唯一的区别是使用要求变量的位置。