2011-08-16 60 views
7

基本上我有一个接口Person,并且我有2个类实现该接口的女性和男性。工厂模式方法问题

但是对于女班,我有一个方法getPregnancyMonth,我的男性班没有。所以添加到我的界面人。

但它成为一个问题,因为我的男性类现在需要从界面继承该方法,我发现这是男性永远不会怀孕的荒谬。

什么是解决方案,我需要做一个扩展人而不是实现?

谢谢。

编辑:对不起,如果我的问题不清楚。但在这种情况下,我已经将男性/女性类的两个get/set方法添加到界面中。

示例代码:

public void process(){ 
     static void Main(Form form) { 
     Person person = Factory.createPerson(form.getGender()); 
     //populate code 
     person.setName(form.getName()); 

     if("F".equals(gender)){ 
      person.setPregnancyMonth(form.getPregnancyMonth()); 
     } 

     ...rest of code 
    } 

} 

我的问题是,因为我的接口有getPregnancyMonth,我的男性有getPregnancyMonth方法添加到具体的类来实现该接口。有没有办法避免这种情况?

+0

请解决您的问题,这不是一个工厂模式的问题,但关于继承和面向对象设计一个一般性的问题。 –

回答

1

请勿将getPregnancyMonth添加到Person。正如你发现的那样,这没有多大意义。在基于对象的编程中,基类/接口应该(理想情况下)只包含每个子类共有的细节 - 因为getPregnancyMonth对于两个子类都不常见(对于Male这没有任何意义),它不应该在Person接口中。我再次强调 - 这是在谈论理想。

至于其他的答案都建议,尽量完全避免这个问题,如果你能。例如,您可以使用instanceof来检测给定的PersonMale还是Female,并且如果PersonFemale,则只能调用getPregnancyMonth

编辑,回应评论:所描述的使用工厂方法在很大程度上毫无意义。如果我们忽略那些不希望被标记为“正常”性别的人,那么您只会创建MaleFemale对象 - 您只需在Factory中使用public static Female createFemale ()public static Male createMale ()方法即可。这样,你将避免全部你遇到过的这个麻烦。它也将摆脱像使用枚举(即“男性”,或“女性”作为参数getPerson)使用的字符串,但这是一个完全不同的问题...

如果您仍然想要使用联合工厂方法,你可以把结果作为Female

Female female = (Female) Factory.getPerson("female"); 
female.getPregnancyMonth (); 

或者,如果你有一个Person可能会或可能不会是一个Female,你可以施放太:

if (person instanceof Female) 
{ 
    Female female = (Female) person; 

    female.getPregnancyMonth(); 
} 

我不能说我太喜欢t了虽然软管接近 - 他们有自己的位置,但通常有更好的方法。

+0

但它不会让我编译,因为当Person女= Factory.getPerson(“女”)时,方法female.getPregnancyMonth()将不存在,因为Person没有该方法 – gathcea

0

它听起来像一个破碎的对象层次结构,但按照说明,您的接口需要两种方法:isFemale()和getPregnancyMonth()。然后,Male.getPregnancyMonth()将引发UnsupportedOperationException。一个更好的方法可能是设计你的模型,以便男性永远不会被置于怀孕月份被问到的位置。

1

实现/扩展在这里并不重要。您可以让isPregnant()总是为Male返回false,或者您可以直接将方法直接推入Female。鉴于你认为男性会怀孕是荒谬的,你会设计你的代码,使其只对女性而不是任何人调用isPregnant()。

顺便说一句,我不是说扔在一个if(person instanceof女性),设计你的heiarchy,以避免这种情况。

2

在我看来,getPregnancyMonth是不够通用的,在Person界面。它应该只在女性阶层中定义。

您也可以定义第二个界面,其中包含getPregnancyMonth。女性将实施两者。

+0

+1在关注该行为的界面上放置与怀孕相关的东西 – Crowie

5

getPregnancyMonth不应该在Person的界面。

个人...没有双关意图......我认为你应该创建Person作为抽象类,因为女性和男性会分享很多相同的属性和功能。

然后,您可以创建反映每种性别独特功能的女性和男性界面。

+0

或者您也可以将女性和男性保留为具体类别。 – Logan

3

不应该有任何需要移动方法进入Person接口。主要的窍门是,当涉及的时间来执行getPregnancyMonth()你必须确保你正在处理一个Female实例,而不是只是一个Person实例。

例如,如果你需要处理一堆不需要任何特殊的治疗Person的对象,可以创建一个方法,所以很容易做到:

public static void processPeople(List<Person> people) { 
    for (Person p : people) { 
     p.someMethod(); 
    } 
} 

然而,当你必须处理getPregenancyMonth()方法,你必须确保你的方法只接受Female实例:

public static void checkBirthSchedule(Female girl) { 
    girl.getPregnancyMonth(); 
    ... 
} 

换句话说,因为你想要知道的,让事情变得抽象,你可以在更高了接口,但要确保你在需要的时候转到更具体的类型。使用诸如使用更具体类型的独立方法Person这样的技术,您可以在编译时免除ClassCastException的问题,这非常好。