让我们考虑一个简化的MVC架构,其中Model在不同类型的糖果上运行。 Confection
类有不同的子类型,例如Candy
,Cookie
,Doughnut
等。每个子类型又具有不同的属性集,例如{{1 }},size
,color
等。
例如,这是shape
类的一种实现:
Candy
现在,模型希望使用一组新的“甜点”来更新视图以显示。假设View要获取class Candy extends Confections {
public enum Size {
LARGE,
MEDIUM,
SMALL,
}
public enum Color {
RED,
GREEN,
YELLOW,
}
private Size size;
private Color color;
...
}
的图片,唯一的事情就是其类型和属性的字符串表示形式,例如Confection
。最愚蠢的做法是在View内部具有多个"candy_red_large"
分支和instanceof
es类型的:
switch
除了这个怪物又大又丑陋,它也没有从封装和OOP中受益。让我们考虑一种更好的方法,为每个if (confection instanceof Candy) {
result.append("candy");
switch ((Candy) (confection).color) {
case RED:
result.append("_red");
break;
...
}
...
} else ...
子类提供类似Confection
的方法,该方法将返回所需的字符串表示形式:
toString()
当模型实际上意识到具有class Candy extends Confections {
...
public String toString() {
return ("candy_" + size + "_" + color).toLowerCase();
}
}
方法的View实现细节时,我在这种方法中遇到的唯一问题是某种架构上的“权衡”,这从模型的角度来看是没有用的。
在这种情况下,将各种数据从模型映射到视图表示的最佳方法或设计模式是什么?
答案 0 :(得分:0)
也许使用一些字符串来获取您想要的东西:
class Confections {}
class Candy extends Confections {
public enum Size {
LARGE,MEDIUM,SMALL,
}
public enum Color {
RED,GREEN,YELLOW,
}
Candy(Size size,Color color) {
this.color=color;
this.size=size;
}
private Size size;
@Override public String toString() {
return "Candy [size="+size+", color="+color+"]";
}
public String toString2() {
return "candy_"+size+"_"+color;
}
private Color color;
}
public class SO53564342_mapping_complex_data_from_model_to_view {
public static void main(String[] args) {
Candy candy=null;
for(Candy.Size size:Candy.Size.values())
for(Candy.Color color:Candy.Color.values())
System.out.println((candy=new Candy(size,color)).toString()+" "+candy.toString2());
}
}
答案 1 :(得分:0)
我可以想象引入一个新的界面StringRepresentation
:
public interface StringRepresentation {
String represent();
}
StringRepresentation
将由Confections
实现。为了使Confections
的每个子对象都实现represent
,使其变得抽象:
public abstract class Confections implements StringRepresentation {}
此后,我们必须在Candy
和其他类represent
中实现。如果您想使用Enums,也可以让他们实现StringRepresentation
。
public class Candy extends Confections {
private Size size;
private Color color;
public String represent() {
return "candy_" + color.represent() + "_" + size.represent();
}
public enum Size implements StringRepresentation {
LARGE("large"),
MEDIUM("medium"),
SMALL("small");
private final String representation;
Size(String representation) {
this.representation = representation;
}
public String represent() {
return this.representation;
}
}
public enum Color implements StringRepresentation {
RED("red"),
GREEN("green"),
YELLOW("yellow");
private final String representation;
Color(String representation) {
this.representation = representation;
}
public String represent() {
return this.representation;
}
}
}
您不需要使用switch
或if
之类的条件,也不需要循环。此外,每个类/组件(如上面的枚举和类)都有自己的逻辑,因此您知道将来更改时在哪里更改表示形式。