uccie
uccie

Reputation: 183

How to do not repeat myself or how to change a simple condition in a method?

I have a method, which I use multiple times in my implementation with very simple modifications. How can I avoid repeating myself?

...
    while (!queue.isEmpty()) {
        Element pivot = queue.poll();
        elements.remove(pivot);
        for (Element a : elements) {
            if (areFriends(pivot, a)) {
                db.addRelation(a, pivot);
                queue.add(a);
                elements.remove(a);
            }
        }
    }
...

I want to change the areFriends condition with a new one, f.e. areEnemies(Element pivot, Element a) and keep using the whole code and data structure. I tried to extract a void method, but in this case I have to pass all the variables (db, queue etc.) as inputs and it looks like as an anti-pattern. Do you have any idea how to solve this problem? Thank you!

Upvotes: 3

Views: 116

Answers (4)

groo
groo

Reputation: 4448

Hum.. Not sure if I fully understood your problem but this looks like a smell to implement a Template Method pattern or maybe some other Behavioral pattern.

Check: http://en.wikipedia.org/wiki/Template_method_pattern

Upvotes: 0

LaGrandMere
LaGrandMere

Reputation: 10359

Create an interface :

public interface Relation 
{
    public void execute(Element a, Element b);
}


public class AreFriendsRelation implements Relation 
{
    public void execute(Element a, Element b) 
    {
        // Return the Relation result
    }    
}

public class AreEnemiesRelation implements Relation 
{
    public void execute(Element a, Element b) 
    {
        // Return the Relation result
    }    
}

Pass your Relation object to your method:

public void MyMethod(Relation myRelation) {
...
while (!queue.isEmpty()) {
        Element pivot = queue.poll();
        elements.remove(pivot);
        for (Element a : elements) {
            if (myRelation.execute(pivot, a)) {
                db.addRelation(a, pivot);
                queue.add(a);
                elements.remove(a);
            }
        }
    }

...
}

Upvotes: 3

hmjd
hmjd

Reputation: 122001

You could define an interface:

public interface IElementFunction
{
    public boolean execute(Element e1, Element e2);
}

and the pass implementations (either named or anonymous classes) of the interface to the common function:

private void commonFunction(IElementFunction ief)
{
    while (!queue.isEmpty()) {
        Element pivot = queue.poll();
        elements.remove(pivot);
        for (Element a : elements) {
            if (ief.execute(pivot, a)) {
                db.addRelation(a, pivot);
                queue.add(a);
                elements.remove(a);
            }
        }
    }

Upvotes: 3

Amir Kost
Amir Kost

Reputation: 2168

You can use the Command design pattern. Create an interface with method public void checkElements(Element a, Element b), and create a few instances of that interface. In your method, use the interface's method, and either have your method accept an interface instance as a parameter, or have it as a class member.

Upvotes: 0

Related Questions