【问题标题】:Composite pattern in javajava中的复合模式
【发布时间】:2012-11-11 08:44:52
【问题描述】:

我现在正在开发一个程序,该程序允许您创建形状(正方形、矩形和圆形),您还可以选择通过选择已创建的形状来创建复合形状...我正在使用两个观察者形状。一种用于正方形/矩形,一种用于大圆形,这些观察者列出了形状的参考点和大小。创建复合形状时,如果复合形状中有正方形/矩形,则应在正方形/矩形框中列出组件。

我应该使用复合图案创建复合形状。所以基本上复合形状和我的圆形、正方形和矩形需要以相同的方式处理

我有一个称为形状的对象数组,复合形状是一个包含形状数组的对象。

我的问题是如何通过形状数组检查复合形状类型的对象,然后通过复合形状数组检查矩形或正方形的实例?

抱歉没有包含代码,但我的程序有点大,有很多类

这是我用来检查正方形或矩形实例的方法...这两种方法属于两个不同的类。当形状只是简单形状但复合形状不显示时,这些形状会显示在右侧观察者窗口中。例如,如果我有一个包含 3 个形状的形状列表……形状 1 是一个大圆圈,形状 2 是复合形状,形状 3 是矩形。假设复合形状有 2 个正方形。现在这将显示大圆圈和矩形,但不会显示复合形状组件。我以为一旦我找到了compoundShape,instanceof 就会从 compundshape 数组中挑选出一个 instanceof 正方形或矩形

这里是复合形状 toString 方法

public String toString(){
    String output="";
    output += "Compound Shape: /n";
    for (int i = 0; i< numShapes; i++){
        output += shapes[i].toString();
    }
    return output;
}

这是我用来查找正方形或矩形实例的 do 方法

do {//squares rectangles
        currentShape = shapes.getShape();
        if (shapes.squareRectangleFinder())
            outputString1 += currentShape.toString();
    }while (shapes.next());

这里是正方形查找器方法

public boolean squareRectangleFinder() {
    if ((shapes[currentShape] instanceof Square)||(shapes[currentShape] instanceof Rectangle)){
        return true;
    }
    return false;
}

【问题讨论】:

  • 听起来像是一项家庭作业...考虑一下您不应该“检查通过”。您需要通过复合类公共接口抽象和提供哪些行为或属性?或者也许通过共享界面所有形状共享。
  • 您可以使用instanceof 运算符来检查数组中的元素是否是CompoundShape 类的实例。
  • 确实如此,但可能不符合家庭作业试图教授的精神。
  • “我使用两个观察器来观察形状。一个用于正方形/矩形,一个用于大圆形” 这听起来像是你的班级设计的问题。例如,如果将方法 isRectangular() 添加到 Shape,则可以解决 squareRectangleFinder() 问题。如果这是所有形状的一个重要属性,那就让它成为所有人的属性。或者添加一个类RectangularShape,它定义了这个属性和子类RecangleSquare
  • 在阅读了维基百科的文章后,我很清楚复合模式是关于不使用instanceof。 - 您只需在 CompoundShape 上实现与在普通模型上相同的功能。

标签: java composite


【解决方案1】:

我想这就是“复合模式”应该做的。根据Wikipedia

客户应该忽略对象组合和单个对象之间的区别

在我的理解中应该这样做(getter/setter,省略添加/删除操作):

interface Shape {
    public int getLeftmostCoordinate();
}

class Rectangle implements Shape {
    private int top;
    private int left;
    private int width;
    private int height;

    public int getLeftmostCoordinate() {
        return left;
    }
}

class Circle implements Shape {
    private int x;
    private int y;
    private int r;

    public int getLeftmostCoordinate() {
        return x - r;
    }
}

class CompoundShape implements Shape {
    private Shape[] shapes;

    public int getLeftmostCoordinate() {
        int left = shapes[0].getLeftmostCoordinate();

        for (int i=1; i<shapes.length; i++) {
            int candidate = shapes[i].getLeftmostCoordinate();
            if (candidate < left) {
                left = candidate;
            }
        }

        return left;
    }
}

【讨论】:

  • 虽然这个答案说的是真的,但这不是好的面向对象实践,而且几乎可以肯定不是家庭作业试图教的内容。由所有 Shapes、Compound、Circle 或其他任何东西实现的共享接口应该抽象出对这种技术的需求,它实际上应该只在存在反射的情况下用于抽象元编码。
  • @SAJ14SAJ 当然,但问题本身具有误导性,他问如何区分这些类。查了一下维基百科,复合模式应该做的完全相反。
  • @SAJ14SAJ 这个怎么样?
  • 我认为是这样的:-)
  • 我编辑了我的帖子以包含应该做我需要的代码片段......如果不清楚,我真的很抱歉,但我有大约 12 个不同的类,不知道怎么做显示我在这里做什么
猜你喜欢
  • 2023-04-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多