- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在开展一个学校项目,我们需要创建一个管理任务和项目的基本应用程序。我们的项目遵循 MVC 模式。重点在于应用程序的设计,我们的团队一直在努力解决某个设计问题:
封装 View 和 Controller 之间传递的数据
这意味着我们要确保 View 没有任何对真实数据的引用。我们尝试通过创建值类来解决这个问题,但这是一个巨大的解决方法。这些是最终类,本质上是普通模型类的副本。例如,如果您有一个 Project 类,那么您还将有一个名为 ProjectValue 的最终类,其所有字段与 Project 相同,只是它们是allfinal 使值类的对象不可变,因此 View 中没有任何内容可以更改。复制所有这些类来获得一些额外的封装感觉不太合适,必须有一种更简单的方法。
我将尝试用一个例子来解释这个问题:
用户想要查看所有项目。因此,他将启动应用程序并单击标有“显示项目”的按钮。该按钮将在 Controller 中启动一个名为 getAll()
的方法:
public PList<ProjectValue> getAll()
{
PList<ProjectValue> projects = PList.empty();
for (BranchOffice office : company.getBranchOffices())
{
for (Project project : office.getProjects())
{
projects = projects.plus(project.getValue());
}
}
return projects;
}
首先它循环遍历所有分支机构。对于分支机构中的每个项目,它都会获取项目的值对象 (project.getValue()
) 并将其放入列表中,而不是普通项目中。
模型类及其内部值类的示例:
public class Resource implements Serializable, Comparable<Resource> {
/**
* Variable registering the name for this resource.
*/
private String name;
private BranchOffice office;
/**
* Variable registering the resource type for this resource.
*/
private ResourceType type;
/**
* Variable registering the reservations that reserve this resource.
*/
private Set<Reservation> reservations;
/**
* Initializes the resource with a given name and type.
*
* @param name
* The name for the resource, f.e. Audi
* @param type
* The type of the resource, f.e. Car
* @throws InvalidResourceException
*/
public Resource(String name, BranchOffice office, ResourceType type)
throws InvalidResourceException
{
try
{
setName(name);
setBranchOffice(office);
setType(type);
setReservations(null);
} catch (InvalidRequiredStringException
| InvalidRequiredResourceTypeException e)
{
throw new InvalidResourceException(e.getMessage(), this);
}
}
/**
* @return the key
*/
public String getKey() { return name; }
/**
* @return the type
*/
private ResourceType getType() { return type; }
private String getName() { return name; }
public Set<Reservation> getReservations() { return reservations; }
public BranchOffice getBranchOffice()
{
return office;
}
/**
* @param name the name to set
* @throws InvalidRequiredStringException
*/
private void setName(String name) throws InvalidRequiredStringException
{
if (name != null && !name.trim().isEmpty())
this.name = name;
else
throw new InvalidRequiredStringException(INVALID_NAME, name);
}
private void setBranchOffice(BranchOffice office)
{
if (office == null) {
throw new IllegalArgumentException(INVALID_OFFICE);
} else {
this.office = office;
}
}
/**
* @param type the type to set
* @throws InvalidRequiredResourceTypeException
*/
private void setType(ResourceType type)
throws InvalidRequiredResourceTypeException
{
if (type == null)
throw new InvalidRequiredResourceTypeException(INVALID_TYPE, type);
else
this.type = type;
}
/**
* Set the list of reservations to a given list.
*
* @param reservations
* | The list you want to set the reservations to.
*/
private void setReservations(Set<Reservation> reservations)
{
if (reservations != null) this.reservations = new HashSet<>(reservations);
else this.reservations = new HashSet<>();
}
/**
* Adds a given reservation to the list of reservations.
*
* @param reservation
* | The reservation you want to add to the reservations.
*/
private void addReservation(Reservation reservation)
{
this.reservations.add(reservation);
}
/**
* Checks if this resource conflicts with a given resource.
*
* @param resource
* The resource you want to check against.
* @return
* True if this resource conflicts with the given resource.
*/
public boolean conflictsWith(Resource resource)
{
if (getType().hasConflictWith(resource.getType())) return true;
else return false;
}
/**
* Checks if a resource if available for a given timespan
*
* @param timespan
* @return True if the timespans do not overlap.
*/
public boolean isAvailable(TimeSpan timespan)
{
if (reservations != null && !reservations.isEmpty())
{
for (Reservation reservation : reservations)
if (reservation.overlapsWith(timespan))
return false;
// TODO: checken of resource beschikbaar is binnen timespan (bv.
// datacenter enkel beschikbaar tussen 12:00 en 17:00
return true;
}
return true;
}
@Override
public int hashCode()
{
final int prime = 31;
int result = 1;
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
@Override
public boolean equals(Object obj)
{
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Resource other = (Resource) obj;
if (name == null)
{
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
public ResourceValue getValue()
{
return new ResourceValue(this);
}
@Override
public int compareTo(Resource o)
{
return this.getKey().compareTo(o.getKey());
}
public boolean isOfType(ResourceType other)
{
return getType().equals(other);
}
public void reserve(Reservation newReservation) throws InvalidReservationException
{
for(Reservation reservation : getReservations())
if(reservation.conflictsWith(newReservation))
throw new InvalidReservationException("Reservation conflicts with another reservation", newReservation);
addReservation(newReservation);
}
public boolean isOfSameType(Resource resource)
{
return isOfType(resource.getType());
}
public class ResourceValue
{
private final String name;
private final ResourceType type;
private ResourceValue(Resource resource)
{
this.name = resource.getName();
this.type = resource.getType();
}
/**
* @return the name
*/
public String getName() { return name; }
/**
* @return the type
*/
public ResourceType getType() { return type; }
}
public void deleteReservation(Reservation reservation)
{
getReservations().remove(reservation);
}
}
我已经复制了整个类,它看起来有点乱,但尝试查看类的底部,在那里你可以找到值类。我选择这门课是因为它是最小的一门课。在此示例中,值类不会复制所有字段,而仅复制 View 所需的字段。
我的问题是:“有没有更简单的方法来保持 View 和 Controller 之间的封装?”
最佳答案
It just doesn't feel right to kind of duplicate all these classes
当您将应用程序拆分为多个层时,最好使用这种“ObjectValue”也称为“ObjectDto,数据传输对象”[1]。过去没有模型对象的纯粹副本,您可以根据您想要执行的操作添加、删除、修改字段。
也就是说,您可以使用一些库将实体“映射”到 ObjectValue。例如,ModelMapper http://modelmapper.org/ .
PersonDto personDto = mapper.map(personModel, PersonDto.class);
编辑:[1] 根据评论,ValueObject 和 DTO 不是同一件事,即使主要原理保持不变。 IMO,这只是命名约定的问题。
DTOs are simple objects that should not contain any business logic that would require testing
关于java - View 和 Controller 之间的封装,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31428352/
我正在编写一个具有以下签名的 Java 方法。 void Logger(Method method, Object[] args); 如果一个方法(例如 ABC() )调用此方法 Logger,它应该
我是 Java 新手。 我的问题是我的 Java 程序找不到我试图用作的图像文件一个 JButton。 (目前这段代码什么也没做,因为我只是得到了想要的外观第一的)。这是我的主课 代码: packag
好的,今天我在接受采访,我已经编写 Java 代码多年了。采访中说“Java 垃圾收集是一个棘手的问题,我有几个 friend 一直在努力弄清楚。你在这方面做得怎么样?”。她是想骗我吗?还是我的一生都
我的 friend 给了我一个谜语让我解开。它是这样的: There are 100 people. Each one of them, in his turn, does the following
如果我将使用 Java 5 代码的应用程序编译成字节码,生成的 .class 文件是否能够在 Java 1.4 下运行? 如果后者可以工作并且我正在尝试在我的 Java 1.4 应用程序中使用 Jav
有关于why Java doesn't support unsigned types的问题以及一些关于处理无符号类型的问题。我做了一些搜索,似乎 Scala 也不支持无符号数据类型。限制是Java和S
我只是想知道在一个 java 版本中生成的字节码是否可以在其他 java 版本上运行 最佳答案 通常,字节码无需修改即可在 较新 版本的 Java 上运行。它不会在旧版本上运行,除非您使用特殊参数 (
我有一个关于在命令提示符下执行 java 程序的基本问题。 在某些机器上我们需要指定 -cp 。 (类路径)同时执行java程序 (test为java文件名与.class文件存在于同一目录下) jav
我已经阅读 StackOverflow 有一段时间了,现在我才鼓起勇气提出问题。我今年 20 岁,目前在我的家乡(罗马尼亚克卢日-纳波卡)就读 IT 大学。足以介绍:D。 基本上,我有一家提供簿记应用
我有 public JSONObject parseXML(String xml) { JSONObject jsonObject = XML.toJSONObject(xml); r
我已经在 Java 中实现了带有动态类型的简单解释语言。不幸的是我遇到了以下问题。测试时如下代码: def main() { def ks = Map[[1, 2]].keySet()
一直提示输入 1 到 10 的数字 - 结果应将 st、rd、th 和 nd 添加到数字中。编写一个程序,提示用户输入 1 到 10 之间的任意整数,然后以序数形式显示该整数并附加后缀。 public
我有这个 DownloadFile.java 并按预期下载该文件: import java.io.*; import java.net.URL; public class DownloadFile {
我想在 GUI 上添加延迟。我放置了 2 个 for 循环,然后重新绘制了一个标签,但这 2 个 for 循环一个接一个地执行,并且标签被重新绘制到最后一个。 我能做什么? for(int i=0;
我正在对对象 Student 的列表项进行一些测试,但是我更喜欢在 java 类对象中创建硬编码列表,然后从那里提取数据,而不是连接到数据库并在结果集中选择记录。然而,自从我这样做以来已经很长时间了,
我知道对象创建分为三个部分: 声明 实例化 初始化 classA{} classB extends classA{} classA obj = new classB(1,1); 实例化 它必须使用
我有兴趣使用 GPRS 构建车辆跟踪系统。但是,我有一些问题要问以前做过此操作的人: GPRS 是最好的技术吗?人们意识到任何问题吗? 我计划使用 Java/Java EE - 有更好的技术吗? 如果
我可以通过递归方法反转数组,例如:数组={1,2,3,4,5} 数组结果={5,4,3,2,1}但我的结果是相同的数组,我不知道为什么,请帮助我。 public class Recursion { p
有这样的标准方式吗? 包括 Java源代码-测试代码- Ant 或 Maven联合单元持续集成(可能是巡航控制)ClearCase 版本控制工具部署到应用服务器 最后我希望有一个自动构建和集成环境。
我什至不知道这是否可能,我非常怀疑它是否可能,但如果可以,您能告诉我怎么做吗?我只是想知道如何从打印机打印一些文本。 有什么想法吗? 最佳答案 这里有更简单的事情。 import javax.swin
我是一名优秀的程序员,十分优秀!