将复杂数据从模型映射到视图

时间:2018-11-30 20:18:42

标签: java oop model-view-controller design-patterns architecture

让我们考虑一个简化的MVC架构,其中Model在不同类型的糖果上运行。 Confection类有不同的子类型,例如CandyCookieDoughnut等。每个子类型又具有不同的属性集,例如{{1 }},sizecolor等。

例如,这是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实现细节时,我在这种方法中遇到的唯一问题是某种架构上的“权衡”,这从模型的角度来看是没有用的。

在这种情况下,将各种数据从模型映射到视图表示的最佳方法或设计模式是什么?

2 个答案:

答案 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

Candy中字符串表示的示例

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

}

好处

您不需要使用switchif之类的条件,也不需要循环。此外,每个类/组件(如上面的枚举和类)都有自己的逻辑,因此您知道将来更改时在哪里更改表示形式。