根据对象属性确定哪个枚举返回

时间:2017-08-20 23:36:33

标签: java oop design-patterns enums

我想知道是否有一些设计模式可以帮助我解决这个问题。

我们假设我有一个班级Person,其中有三个属性:namenicknamespeaksEnglish以及带{的枚举PersonType {1}},TypeOneTypeTwo

让我们说TypeThree Personnickname speaksEnglishTypeOne。如果它有nickame但不是speaksEnglish,那么它是TypeTwo。如果它没有nickame,那么TypeThree

我的第一个想法是使用某个if-else的方法并返回相关的Enum。将来我可以在Person和其他类型的PersonType中拥有更多属性来决定。

所以,我的第一个想法是使用一堆if (...) { return <PersonType> }switch-case创建一个方法,但我想知道是否有一些我可以使用的设计模式而不是ifs和{ {1}}。

3 个答案:

答案 0 :(得分:0)

我建议你只使用简单的继承与不可变对象。

因此,首先你必须创建抽象类:

public abstract class AbstractPerson {

    private final String name;
    private final Optional<String> nickname; 
    private final boolean speaksEnglish;
    private final PersonType personType;

    protected AbstractPerson(final String name, final Optional<String> nickname, final boolean speaksEnglish, final PersonType personType) {
        this.name = name;
        this.nickname = nickname;
        this.speaksEnglish = speaksEnglish;
        this.personType = personType;
    }

    public String getName() {
        return name;
    }

    public Optional<String> getNickname() {
        return nickname;
    }

    public boolean getSpeaksEnglish() {
        return speaksEnglish;
    }

    public PersonType getPersonType() {
        return personType;
    }

}

使用PersonType枚举:

public enum PersonType {

    TypeOne, TypeTwo, TypeThree;

}

现在,我们在子类中有三个选项和相应的构造函数:

public final class EnglishSpeakingPerson extends AbstractPerson {

    public EnglishSpeakingPerson(final String name, final String nickname) {
        super(name, Optional.of(nickname), true, PersonType.TypeOne);
    }

}

public final class Person extends AbstractPerson {

    public Person(final String name, final String nickname) {
        super(name, Optional.of(nickname), false, PersonType.TypeTwo);
    }

    public Person(final String name) {
        super(name, Optional.empty(), false, PersonType.TypeThree);
    }

}

在这种情况下,我们的具体类是不可变的,其类型是在创建时定义的。你不需要创建if-else梯子 - 如果你想创建新类型,只需创建新的类/构造函数。

答案 1 :(得分:0)

我不认为Type可以真正属于Person的属性。我并不反对@ ByeBye的答案,但是在实现这种实现时,如果引入了新类型,您仍然会更改Person类。

X型人最终是一个人。假设ManagerDeveloper都是公司的员工,因此将它们作为派生自Employee的专业类非常有意义。类似地,在你的情况下,将人类型作为属性然后做所有if-else的东西显然违反了SOLID。

我会改为Person类的具体实现,并将自己标记为抽象的。

public abstract class Person {
    public Person(string name) {
        Name = name;
    }
    public abstract string Name { get; set; }
    public abstract string NickName { get; set; }
    public abstract bool SpeaksEnglish { get; set; }
}

public class TypeOnePerson : Person {
    public TypeOnePerson(string name, string nickName) : base(name) {
        NickName = nickName; // Validate empty/ null 
    }
    SpeaksEnglish = true;
}

public class TypeTwoPerson : Person {
    public TypeOnePerson(string name, string nickName) : base(name) {
        NickName = nickName; // Validate empty/ null 
    }
    SpeaksEnglish = false;
}

我也认为这个问题与语言无关,这是一个纯粹的设计问题。所以请耐心等待,因为上面的代码是在C#中。然而,这并不重要。

答案 2 :(得分:0)

考虑到OO原则,为什么要创建具有可选属性组合的对象?如果它的一两个问题然后可选方法将保持可维护,但类型将基于许多组合(在未来的代码中将充满布尔代数)和问题也说&#34; ...将来我可以在Person和其他类型的PersonType中有更多属性来决定。&#34;。

我建议使用Decorator模式的方法,它允许我们创建具有完整代码重用的自定义对象。 Person将是Component和Optional属性(它们是类型,例如NickName,验证为行为)将是具体的装饰器。

任何添加到人添加新的Concrete Decorator 类型仍然是两个独立的问题。 Decorator Pattern 是这类要求的最佳候选者。它的意图来自GOF书(通过Erich gamma)模式目录说 - &#34; 动态地将附加职责附加到对象。装饰器为子类化提供了灵活的替代方法,以扩展功能&#34;。 [虽然对于极少数预期的扩展,早期的答案更有意义。]