3

About a third of my code is wrapped inside a Facade class. Note that this isn't a "God" class, but actually represents a single thing (called a Line). Naturally, it delegates responsibilities to the subsystem behind it.

What ends up happening is that two of the subsystem classes (Output and Timeline) have all of their methods duplicated in the Line class, which effectively makes Line both an Output and a Timeline. It seems to make sense to make Output and Timeline interfaces, so that the Line class can implement them both. At the same time, I'm worried about creating parallel class and interface structures.

You see, there are different types of lines AudioLine, VideoLine, which all use the same type of Timeline, but different types of Output (AudioOutput and VideoOutput, respectively). So that would mean that I'd have to create an AudioOutputInterface and VideoOutputInterface as well. So not only would I have to have parallel class hierarchy, but there would be a parallel interface hierarchy as well.

Is there any solution to this design flaw?

Here's an image of the basic structure (minus the Timeline class, though know that each Line has-a Timeline):

enter image description here

NOTE: I just realized that the word 'line' in Timeline might make is sound like is does a similar function as the Line class. They don't, just to clarify.

0

    3 Answers 3

    1

    What ends up happening is that two of the subsystem classes (Output and Timeline) have all of their methods duplicated in the Line class, which effectively makes Line both an Output and a Timeline.

    The above sentence sounds like bad design.

    I would expect that most of the methods in a facade class invoke at multiple subsystem classes or at least multiple methods in a single subsystem class.

    If you facade is doing lots of simple delegation (example, facade method doSomething simply calls another class' doSomething), you probably should refactor.

    Specifically, if a delegate class does not interact with the rest of the subsystem, the client should probably should probably interact with the delegate directly, instead of through the facade.

    2
    • The issue is that the Line class is really ONE "object". It has multiple responsibilities, but it's one "thing". It seems odd for the rest of my program to struggle to manage three objects
      – sinθ
      CommentedAug 7, 2013 at 22:41
    • @MikeG there may be some composition patterns that can make the usage of multiple objects as easy to work with as like one object.
      – rwong
      CommentedOct 7, 2013 at 4:30
    1

    Are some of your clients interested chiefly in Line as a Timeline, and others interested in it chiefly as an Output? If so, consider sprouting classes or interfaces from Line that stand between it and clients, each of these new classes wraps a pointer to a Line and abstracts away implementation while focusing the API.

    At first, the feels like a facade for a facade, but it opens up new refactoring horizons. You can pull methods from Line to the new classes. You may discover new helper classes you can extract. Perhaps one of your implementation classes will turn out to belong here as well.

      0

      I really agree with both of the other answers. The primary problem here is that Line has multiple responsibilities. You are falling into the fallacy of believing that classes correspond to a "thing", when really a class should correspond to a "responsibility".

      That being said, it is certainly possible for a class to have the single responsibility of "providing a single facade delegating to several other classes to simplify client code". It sounds like that might be what you are describing; it depends whether Line has any behavior of it's own, besides delegation. I don't usually do this, because I don't find it cumbersome to have client code talk to several objects, but that may be chalked up to personal preference.

      It seems to make sense to make Output and Timeline interfaces, so that the Line class can implement them both. At the same time, I'm worried about creating parallel class and interface structures.

      What motivates you to do that? Is there some need for that change, or is it just that you think it would be "more right"? If the latter, I would just leave your code as is. Working code is king.

        Start asking to get answers

        Find the answer to your question by asking.

        Ask question

        Explore related questions

        See similar questions with these tags.