使用策略方法时的困惑

时间:2016-09-13 04:58:09

标签: java design-patterns arraylist strategy-pattern

我正在尝试实施策略模式,以找到包含不同类型的数值数据的arraylists的中间点,包括成对的数值数据(坐标)。我遇到了一些困难

  1. 与对和
  2. 我的策略方法' findMiddle'没有实施。
  3. 我究竟如何实施策略模式以及如何使用对在Java中工作?

    说到策略模式,我找不到符号'说出

    的行的错误
        intdata.findMiddle(new midInt());
        floatdata.findMiddle(new midFlo());
    

    当涉及到对时,主要方法输出这个......

        30 added to Integer ArrayList
        57 added to Integer ArrayList
        22 added to Integer ArrayList
        57 removed from Integer ArrayList
        5.55 added to Float ArrayList
        6.14 added to Float ArrayList
        5.42 not in Float ArrayList
        strat.coordinates$Pair@2a139a55 removed from Coordinate ArrayList
    

    最后一行输出是怎么回事?

2 个答案:

答案 0 :(得分:1)

你的设计不是乞求战略模式。这种模式最适合一个会改变其不时执行某些行动的策略的类。一个很好的例子是游戏中的玩家,其攻击策略将取决于当前正在使用的武器或将改变其布局策略的GUI容器。你拥有的是一些" Data"只接受一种类型数据的类(看起来似乎如此)所以只有一种策略会应用永远

此外,您的策略完全相同,绝不需要有所不同。因此,您可以通过使用非特定方法插入和删除单个数据容器类来一起避免策略模式。例如:

public class Container<T> {
    private List<T> list = new ArrayList<>();

    public void insert(T t) { ... }
    public void remove(T t) { ... }
    public T findMiddle() { ... }

    public static void main(String[] args) {
        Container<Integer> ints = new Container<>();
        Container<Double> doubles = new Container<>();
        Container<Pair<Double, Double>> pairs = new Container<>();

        // Insert some elements into your containers
        System.out.println(ints.findMiddle() + " is the middle integer.");
        System.out.println(doubles.findMiddle() + " is the middle double.");
        System.out.println(pairs.findMiddle() + " is the middle pair.");
    }
}

这种设计的好处是能够以多态方式使用Container类,使您无需知道要插入,移除或查找中间的类型(特别是从找到中间与所包含的类型无关。这样你就可以巧妙地使用你的容器;例如:

List<Container> containers = new ArrayList<>();
containers.add(ints);
containers.add(doubles);
containers.add(pairs);
containers.forEach(Container::findMiddle);

你可以使用策略模式,如果它是你不愿意的东西,但我不会推荐它。如果您这样做,则需要在Middle课程中添加Data个实例,并在findMiddle方法中应用该策略。请注意,这些策略中的代码(如编写的)没有任何结果。它们中的列表不是相应类中的列表。因此,它需要您对findMiddle方法进行更多考虑,但最终我认为您会发现它是对策略模式的误用。

根据您的Middle策略,请尝试以下更改:

public class MidInt implements Middle {
    @Override
    public void findMiddle(List list){
        // find and print the middle element!
    }
}

public class IntegerData {
    private final List<Integer> integers;
    private Middle middle = new MidInt();
    public void findMiddle() {
        middle.findMiddle(integers);
    }
    public void setMiddleStrategy(Middle middle) {
        this.middle = middle;
    }
    ...
}

现在,您(可选)从MidInt策略开始。如果由于某种原因定义了&#34;中&#34;整数已更改,您只需设置新的Middle策略,它就会在您下次findMiddle()时自动应用。当然,您需要更改Middle界面以反映所显示的内容。我更改了一些名称,因为您没有遵循Java的命名约定(您应该这样做)。

答案 1 :(得分:0)

据我了解,您的“中间”界面是您的策略界面。像midIntmidFlo这样的具体类应该是该策略的实现。像IntegerDatacoordinates这样的课程意味着托管策略的一个实例。如果这就是您在这里所要做的,那么您应该将策略实例传递到托管类。您没有发布IntegerData,但坐标没有接受Middle的实例的方法。

这样的行的原因
intdata.findMiddle(new midInt())

为您提供未找到的符号错误是IntegerData类没有名为“findMiddle”的方法。这段代码是否意味着找到中间的?或者它是否意味着将“midInt”的实例插入到Integer数据类中?你可以发布IntegerData来源吗?

输出中的奇怪打印,

  

strat.coordinates$Pair@2a139a55

来自行System.out.println(pair + " added to Coordinate ArrayList");时的结果如果类Pair没有“toString”方法,那么您将看到这样的输出。