假设我有一个具有不同Scenes的应用程序。每个场景都有一个由多个ScreenElement组成的布局,例如,将绘制到Canvas的矩形框。对于某些Scenes,将使用相同的框。因此,鉴于干燥,我想使用继承。
我想要做的是将ScreenElement存储在一个HashMap (或者最终是一个EnumMap)中,这样我就可以在代码的其他地方调用ScreenElement来更改它们的属性。
这是我现在想出来的..。
以下是基本布局:
Public class BasicLayout {
private HashMap<String, ScreenElement> screenElements;
public BasicLayout() {
screenElements = new HashMap<>();
screenElements.put("BACKGROUND", new ScreenElement(...));
screenElements.put("BOXONE", new ScreenElement(...));
screenElements.put("BOXTWO", new ScreenElement(...));
}
public HashMap<String, ScreenElement> getScreenElements() {
return screenElements;
}
public ScreenElement getScreenElement(String elementName) {
return screenElements.get(elementName);
}
public void draw(Canvas canvas) {
for (ScreenElement screenElement: screenElements) {
screenElement.draw(canvas);
}
}
}那么另一个布局可能是这样的:
Public class OtherLayout extends BasicLayout {
private HashMap<String, ScreenElement> screenElements;
public OtherLayout() {
screenElements = new HashMap<>(super.getScreenElements);
screenElements.put("BOXTHREE", new ScreenElement(...));
screenElements.put("BOXFOUR", new ScreenElement(...));
}
@Override
public HashMap<String, ScreenElement> getScreenElements() {
return screenElements;
}
@Override
public ScreenElement getScreenElement(String elementName) {
return screenElements.get(elementName);
}
@Override
public void draw(Canvas canvas) {
for (ScreenElement screenElement: screenElements) {
screenElement.draw(canvas);
}
}问题是,通过解决代码复制(我不再需要在我的OtherLayout**),中添加背景、BOXONE和BOXTWO ),我引入了代码复制!**
现在我需要复制getScreenElements、getScreenElement和draw方法。在这种情况下,您需要重写它们,因为如果没有,getScreenElements总是返回背景、BOXONE和BOXTWO,即使在实际需要背景、BOXONE、BOXTWO、BOXTHREE和BOXFOUR (例如在使用“`OtherLayout”的Scene中)。
希望这是合理的,有人有一个巧妙的解决方案!
澄清:
BasicLayout都应该有背景,BOXONE和BOXTWOOtherLayout都应该有背景,BOXONE,BOXTWO,BOXTHREE和BOXFOUR。发布于 2018-11-16 13:21:16
这应该是可行的:
public class BasicLayout {
protected HashMap<String, ScreenElement> screenElements = new HashMap<>();
public BasicLayout()
{
screenElements.put("BACKGROUND", new ScreenElement(...));
screenElements.put("BOXONE", new ScreenElement(...));
screenElements.put("BOXTWO", new ScreenElement(...));
}
public HashMap<String, ScreenElement> getScreenElements() {
return screenElements;
}
public ScreenElement getScreenElement(String elementName) {
return screenElements.get(elementName);
}
public void draw(Canvas canvas) {
for (ScreenElement screenElement: screenElements) {
screenElement.draw(canvas);
}
}
}
public class OtherLayout extends BasicLayout {
public OtherLayout() {
screenElements.put("BOXTHREE", new ScreenElement(...));
screenElements.put("BOXFOUR", new ScreenElement(...));
}
}发布于 2018-11-16 14:00:01
我不认为解决继承问题是避免重复的好选择。您总是违反Liskov替换原则是某种解决方式(在您的情况下,不是这样解决:)。这就导致了更大的问题。
第二点继承应该只用于共享行为,而不是数据。
我认为,就你的情况而言,代表团/组成更适合:
public OtherLayout() {
screenElements = new HashMap<>();
screenElements.putAll(new BasicLayout().getScreenElements());
screenElements.put("BOXTHREE", new ScreenElement());
screenElements.put("BOXFOUR", new ScreenElement());
}因为从外观上看,这两个类唯一常见的是源元素映射中的元素。
还有一个更笼统的注解。不要像错误的抽象那样害怕重复。引用现代计算机科学先驱的话(Edsger Dijkstra):
抽象的目的不是含糊不清,而是要创造一个新的语义层次,在这个层次上,我们可以绝对精确。
发布于 2018-11-16 13:35:15
基于示例代码,只需要一个类就可以在构造函数中接受它将负责的元素。例如:
public class Layout {
private final Map<String, ScreenElement> screenElements;
public Layout(Map<String, ScreenElement> screenElements) {
this.screenElements = screenElements;
}
// other methods
}从您的示例来看,代码库中的某个地方将知道如何创建一个BasicLayout或OtherLayout。重构该代码并提取映射,然后传递给构造函数。例如:
// in some method that knows when to create a `BasicLayout` or `OtherLayout`
Map<String, ScreenElement> basicScreenElements = new HashMap<>();
basicScreenElements .put("BACKGROUND", new ScreenElement(...));
basicScreenElements .put("BOXONE", new ScreenElement(...));
basicScreenElements .put("BOXTWO", new ScreenElement(...));
Layout basicLayout = new Layout(basicScreenElements);
// ....
Map<String, ScreenElement> otherScreenElements = new HashMap<>();
otherScreenElements .put("BOXTHREE", new ScreenElement(...));
otherScreenElements .put("BOXFOUR", new ScreenElement(...));
Layout otherLayout = new Layout(otherScreenElements);https://stackoverflow.com/questions/53338543
复制相似问题