views:

78

answers:

3

Suppose there is a business function you need to implement, which sets some kind of a profile.

Depending on how data is received, however, setting profile will be implemented differently.

For instance parameters may be passed directly to the object which would be able to

setProfile();

or, parameters would have to be discovered and would have to be passed to profile by

setProfile(String[] data, Blah blooh);

What is the best approach in such situation? I mean, design wise how would you structure this?

I was thinking about using an Interface with abstract methods, which works, but introduces some noise. Not really sure how to best structure this.

Please advise

+5  A: 

I always get nervous around methods with many overloads. I prefer, in this case, to think of the method argument as a message, rather than parameters, and build a single method such as this:

setProfile(ProfileData data)

The ProfileData class could contain data common among all of your setProfile approaches, and you can create derived classes for specialized setProfile operations.

This approach is particularly useful if you are using serialization techniques that can automatically persist your ProfileData object based on its structure.

kbrimington
+3  A: 

I would go by abstracting the actual profile to its own class hierarchy to encapsulate it and add Generics to the setProfile(). Granted, it does add some complexity but because it also introduces indirection, the code will be more decoupled which in the long run should prove useful.

Also the actual function could be in its own class hierarchy entirely to make that part pluggable too which would mean that you'd have a Strategy Pattern in your hands. The decision to apply this, however, would require more knowledge of the system you're building and may not be suitable for what you're building.

Quick example:

/**
 * Interface for describing the actual function. May (and most likely does)
 * contain other methods too.
 */
public interface BusinessFunction<P extends Profile> {
    public void setProfile(P p);
}

/**
 * Base profile interface, contains all common profile related methods.
 */
public interface Profile {}

/**
 * This interface is mostly a matter of taste, I added this just to show the 
 * extendability.
 */
public interface SimpleProfile extends Profile {}

/**
 * This would be what you're interested of.
 */
public interface ComplexProfile extends Profile {
    String[] getData();
    Blah blooh();
}

/**
 * Actual function.
 */
public class ComplexBusinessFunction implements BusinessFunction<ComplexProfile> {
    public void setProfile(ComplexProfile p) {
        // do whatever with p which has getData() and blooh()
    }
}

/**
 * And another example just to be thorough.
 */
public class SimpleBusinessFunction implements BusinessFunction<SimpleProfile> {
    public void setProfile(SimpleProfile p) {
        // do whatever with the empty profile
    }
}
Esko
Loving it. THANK YOU
mac
A: 

For Get/Set methods, I always keep the set method as a single input. Be it a simple object, to potentially a more complex object as kbirmington has suggested. I think I do this more out of consistently than any real design advantage.

Its worth remembering though if the profile data has 10 attributes and they only supply 9 off them, there is potentially 9 different methods you would have to write based on which of those 10 attributes is actually missing.

At least with a single structure, there is one input, furthermore if the structure changes the method does not only the code inside it.

In that aspect you are programming to an interface which is a good design paradigm.

JonWillis