0

I'm looking at a very large object within the application I'm working on, which is there to basically hold all the data together at a large level. Recently, we have started moving some methods out of other objects on the ModelData to the ModelData itself, because these methods are changing drastically now that we are implementing the ExistingModelData (refer to code below if you haven't already).

public RemoveStuffAction //Called from View
{
    public void doWork(HttpServletRequest request, HttpServletResponse response)
    {
        SessionData sessionData = WebUtils.getSessionData(request);
        //We actually use contracts here for validation and such
        //Passes contract to a service - ultimately resulting in..
        ModelData modelData = sessionData.getModelData();
        modelData.removeStuff(request.getParameter("stuffID"));
        //other cleanup

        //the old Code
        //ModelData modelData = sessionData.getModelData();
        //modelData.getStuffManager().removeStuff(stuffID);
        //other cleanup

        //save of model..
        //forward mapping..
        //exception handling..
    }
}

public abstract ModelData
{
    //lots of stuff

    //Methods to modify the stuff
    public void removeStuff(String stuffID) //example
    {
        this.getStuffManager().removeTheStuffFromHere(stuffID);
    }
}

public NewModelData extends ModelData
{
    //not much stuff
}

public DuplicateModelData extends ModelData
{
    //not much stuff
}

public ExistingModelData extends ModelData
{
    //quite a bit of stuff
    //Overrides many methods to modify the stuff
    public void removeStuff(String stuffID) //example
    {
        //we need the data there because we need to know what used to be there, 
            //even though it is supposed to now be removed
        //what determines whether we need to know what was there or not is determined by 
            //whether this is ExistingData or not.
        this.getStuffManager().getStuff(stuffID).markAsRemoved();
    }
}

Basically, instead of creating overriding classes for all the Objects that could be changed on the model and implementing new Remove methods (and then worrying about all the times we also Add those objects so we add the correct one in each of those spots) we are moving these methods to the ModelData class and letting that one overridden class handle the removal of our Objects through inheritance.

What we have works fine, and its pretty clear to everyone on the team whats going on. I also feel with the JavaDoc we've got on ModelData that things are explained pretty well, but it just starts to bother me that we are moving so many methods to these classes - making already large classes even larger in terms of amount of text.

I've considered creating two new objects just to hold all these methods, and place the original version on the ModelData and an overridden version on the ExistingModelData, but I don't do it because I feel like it doesn't actually accomplish anything - it just shortens the amount of code in that particular class, which only makes my OCD feel a little better - and then I'll have to add an extra method call everywhere we need to use the methods in the new objects.

I also recognize that I could be too close to the situation right now and might be missing something obvious.

Is there something I could do which makes more sense and creates a cleaner design?

  • Are those really the names of the classes? – Robert Harvey Jul 17 '15 at 16:30
  • @RobertHarvey No - the specific names of the classes doesn't matter to the question. – DoubleDouble Jul 17 '15 at 16:31
  • 1
    Sounds like a god object to me. I think you might have bigger problems here. – user22815 Jul 17 '15 at 16:32
  • Foo Bar examples are often too abstract to make good fodder for analysis. Can you make your examples more specific? – Robert Harvey Jul 17 '15 at 16:42
  • @RobertHarvey I have updated with better generic names, and a slightly more specific example of one of the methods – DoubleDouble Jul 17 '15 at 17:29
2

Given that the removal is handled in generally the same way, there is really nothing wrong with this approach of having a default handling in the parent class and overridden implementations where required. Adding other intermediary objects does not solve the fact that you have some common operations that are applicable across a range of classes.

If you are concerned about having large classes where a lot of minimally functions are dumped, consider making the ModelData class a facade that contains a number of other classes that implement specific types of operations. I have used this approach when creating service processing ecosystems where a large number of operations are available that have been similarly structured.

  • +1 Agreed. I found personally that although I abhorred creating alternative "generic" classes to house large functions - It became very useful to me to start driving out the workload using subclasses. It makes your generic class very readable, but you can drill-down to specific classes for more details/processing as required. – Sh4d0wsPlyr Jul 17 '15 at 19:45

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.