-3

I am trying to implement the strategy pattern to find the middle point of arraylists that hold different types of numerical data including paired numerical data(coordinates). I am having some difficulty

  1. with the pairs and
  2. my strategy method 'findMiddle' is not implementing.

How exactly do I implement the strategy pattern and how do I work in Java using pairs?

When it comes to the Strategy Pattern, I get a 'cannot find symbol' error for the lines that say

    intdata.findMiddle(new midInt());
    floatdata.findMiddle(new midFlo());

And when it comes to the pairs, the main method outputs this...

    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

What is going on in this last line of output?

lenti
  • 1
  • 1
  • You'll probably want to pass the list into `findMiddle()` instead of creating an empty list, getting its size (zero), dividing that by two (zero), adding one (one), and printing that one is the middle element in the empty list (that isn't even true). – Ry- Sep 13 '16 at 05:02
  • You can't even write code that is compilable, as you don't even understand why `intdata.findMiddle(new midInt());` cannot compile, won't it be too early for you to try out design pattern? (And to be honest, what you are writing has nothing to do with strategy pattern...). Imho, you should at least learn basics of Java first (including proper naming convention.) – Adrian Shum Sep 13 '16 at 06:06
  • and, your last question has nothing to do with strategy pattern. You should be able to figure out it is string concatenation involving a class you created (Pair) is not showing something you expected. In short, you have to override `toString()`. – Adrian Shum Sep 13 '16 at 06:11

2 Answers2

1

Your design isn't one begging for the strategy pattern. That pattern is best fit for a class that would change its strategy for performing some action from time to time. A good example is a player in a game whose attack strategy would depend on the weapon currently being used or a GUI container that will change its layout strategy. What you have is a number of "Data" classes that accept only one type of data (so it seems) so only one strategy will apply ever.

In addition, your strategies are exactly the same and in no way need to be different. Therefore, you can avoid the strategy pattern all together by making a single data container class with non-specific methods for inserting and removing. For example:

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

The benefit to this design is the ability to use the Container class in a polymorphic way allowing you to not need to know what type you're inserting, removing, or finding the middle of (especially since finding the middle is in no way tied to the type contained). This way you could use your containers cleverly; for example:

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

You could use the strategy patter if it was something you weren't willing to go without but I wouldn't recommend it. If you do, you will need to add a Middle instance to your Data classes and apply that strategy in your findMiddle method. Note that the code in those strategies (as written) accomplishes nothing. The list in them is not the list in the respective classes. So, it requires that you put some more thought into the findMiddle method(s) but in the end I think you'll find it's a misuse of the strategy pattern.

Given your Middle strategies, try these changes:

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

Now, you (optionally) start with the MidInt strategy. If for some reason the definition of the"middle" integer changed you would just need to set the new Middle strategy and it would automatically be applied the next time you findMiddle(). Of course, you'll need to alter the Middle interface to reflect what's shown. I changed some of the names since you're not following Java's naming conventions (which you should do).

ChiefTwoPencils
  • 13,548
  • 8
  • 49
  • 75
  • @lenti, what's your point? Are you required to use the pattern or is it just something you thought would work? I won't question your professor without seeing the requirements but it's sort of putting the cart before the horse applying design patterns before more elementary techniques like generics. In the end you're just returning the middle element; explain how that requires a specific strategy based on the type contained? – ChiefTwoPencils Sep 13 '16 at 06:33
  • I'm required to use the pattern so that finding the middle can be used no matter the data type. I'm just still confused on how the thing works. – lenti Sep 13 '16 at 06:43
  • @lenti, like I said, that's an odd requirement considering the pattern doesn't really apply here. You have a lot of unnecessary repetition in your code and methods that benefit in no way being specialized (removeInt, removeDouble). I'll add a bit more but if you notice the strategies basically do the same thing. If instead of printing what the element is you returned it the way I show, there needs to be only one "strategy" negating the point of the pattern. Do what they say and then politely ask them what the point was. – ChiefTwoPencils Sep 13 '16 at 06:49
  • @lenti, I added some changes. It's not a complete change of all your code (I'll leave that for you) but it gives you an idea of where you went wrong. – ChiefTwoPencils Sep 13 '16 at 07:01
0

As I understand it, your "Middle" interface is your strategy interface. Concrete classes like midInt and midFlo are meant to be implementations of that strategy. And classes like IntegerData and coordinates are meant to host an instance of a strategy. If that is what you mean to do here, then you should be passing an instance of a strategy into the hosting classes. You didn't post IntegerData but coordinates doesn't have a method for accepting an instance of Middle.

The reason that lines like

intdata.findMiddle(new midInt())

gives you the symbol not found error is that the IntegerData class doesn't have a method called "findMiddle" method. Was that bit of code meant to find the middle? Or was it meant to insert an instance of "midInt" into the Integer data class? Could you post IntegerData sources?

The strange printing in the output,

strat.coordinates$Pair@2a139a55

results from when you did the line System.out.println(pair + " added to Coordinate ArrayList"); If the class Pair does not have a "toString" method, then you will see outputs like this.

Teto
  • 475
  • 2
  • 10