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