Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/fsharp/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 根据对象属性决定返回哪个枚举_Java_Oop_Design Patterns_Enums - Fatal编程技术网

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

Java 根据对象属性决定返回哪个枚举,java,oop,design-patterns,enums,Java,Oop,Design Patterns,Enums,我想知道是否有一些设计模式可以帮助我解决这个问题 假设我有一个类Person,它有三个属性:name,昵称和speaksEnglish,还有一个枚举PersonType,带有TypeOne,TypeTwo和TypeTwo 假设一个人有昵称和说英语这是一个TypeOne。如果它有nickame,但不说英语,那么它就是TypeTwo。如果它没有nickame,那么它就是TypeThree 我的第一个想法是使用一些if-else并返回相关Enum的方法。将来我可以在Person和其他类型的Person

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

假设我有一个类
Person
,它有三个属性:
name
昵称
speaksEnglish
,还有一个枚举
PersonType
,带有
TypeOne
TypeTwo
TypeTwo

假设一个
昵称
说英语
这是一个
TypeOne
。如果它有
nickame
,但不
说英语
,那么它就是
TypeTwo
。如果它没有
nickame
,那么它就是
TypeThree

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


所以,我的第一个想法是创建一个方法,使用一堆
if(…){return}
开关大小写
,但是我想知道是否有一些设计模式可以用来代替
ifs
开关大小写

,我建议您对不可变对象使用简单的继承

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

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;
    }

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

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梯形图-如果您想创建新类型,只需创建新的类/构造函数。

我不认为
类型
真的可以成为
人的属性。我并不反对@ByeBye的答案,但通过这种实现,当引入新类型时,您仍然会改变
Person

X类型的人最终是一个人本身。假设
经理
开发人员
都是一家公司的员工,因此将他们作为从
员工
派生出来的专业类是很有意义的。类似地,在您的情况下,将person type作为属性,然后执行所有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#。不过,这并不重要。

就考虑OO原则而言,为什么要创建具有可选属性组合的对象?如果它的问题是一个或两个,那么可选方法将保持可维护性,但类型将基于许多组合(在未来的代码中将充满布尔代数),问题还说“……在未来,我可以有更多的个人属性和其他类型的个人类型来决定。”

我建议使用Decorator模式,它允许我们创建具有完全代码重用的定制对象。Person将是组件,可选属性(它们是类型,例如昵称,验证为行为)将是具体的装饰器


任何增加的人和增加新的混凝土装饰类型仍然是两个独立的关注点。装饰器模式是这种需求的最佳候选者。它来自GOF book(由Erich gamma编写)模式目录的意图是:“动态地将额外的职责附加到对象上。装饰器为扩展功能提供了一种灵活的子类化替代方法”。[虽然对于非常少的预期扩展,早期的答案更有意义。]

如何向枚举添加一个抽象方法,比如方法“布尔测试(Person)”,以便每个枚举类型都能够检查该人是否属于该类型。稍后,您只需要遍历Enum.values()并调用test(person)。不确定是否是最好的主意,但您将把逻辑放在一个地方e避免所有那些if/elseAre您的
Person
对象是可变的还是不可变的?我喜欢您的选择,但我认为类型必须是类的一部分-我们必须避免使用
instanceOf
之类的结构。如果我们想要按类型筛选,或者类似的东西,那么它将非常有用。对于类型检查,您不需要执行
instanceOf
。因为您的所有代码都将与
抽象而不是特定的实现对话。特定的实现只会在代码需要
Person
的地方注入。但是如果您有
Person
的列表,并且只想过滤
typetwopperson
,您就没有这样的信息
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;
}