Отображение сложных данных из модели в представление - PullRequest
0 голосов
/ 30 ноября 2018

Давайте рассмотрим упрощенную архитектуру MVC, где Model работает с различными типами кондитерских изделий.Существуют различные подтипы класса Confection, такие как Candy, Cookie, Doughnut и т. Д. Каждый подтип, в свою очередь, имеет различные наборы свойств, например size, color, shapeи т. д.

Например, это одна реализация класса Candy:

class Candy extends Confections {
    public enum Size {
        LARGE,
        MEDIUM,
        SMALL,
    }

    public enum Color {
        RED,
        GREEN,
        YELLOW,
    }

    private Size size;
    private Color color;

    ...        
}

Теперь Модель хочет обновить представление с новым набором конфет для отображения.Допустим, единственное, что View нужно для получения изображения Confection, - это строковое представление его типа и свойств, например, "candy_red_large".Самая глупая вещь для этого - иметь несколько instanceof ветвей и switch es для типов внутри View:

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

Единственная проблема, которую я вижу в этом подходе, это некоторыесвоего рода архитектурный «компромисс», когда Model фактически осведомлен о деталях реализации View, имеющих метод toString, который бесполезен с точки зрения Model.

Какой наилучший подход или шаблоны проектирования использовать втакой случай для отображения разнородных данных из представления Model to View?

Ответы [ 2 ]

0 голосов
/ 03 декабря 2018

Идея

Я мог бы представить новый интерфейс 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;
    }
  }

}

Выгода

Вам не нужноиспользовать условия, такие как switch или if, и вам не нужны циклы.Кроме того, каждый класс / компонент - как и выше перечисления и классы - имеет свою собственную логику, поэтому вы знаете, где изменить представление при изменении в будущем.

0 голосов
/ 01 декабря 2018

может использовать некоторые строки, чтобы получить то, что вы хотите:

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());
    }
}
...