6

I have at first sight a simple issue but can't wrap my head around on how to solve. I have an abstract class Compound. A Compound is made up of Structures. Then there is also a Container which holds 1 Compound.

A "special" implementation of Compound has Versions. For that type of Compound I want the Container to hold the Versionof the Compound and not the Compound itself.

You could say "just create an interface Containable" and a Container holds 1 Containable. However that won't work. The reason is I'm creating a framework and the main part of that framework is to simplify storing and especially searching for special data type held by Structure objects. Hence to search for Containers which contain a Compound made up of a specific Structure requires that the "Path" from Containerto Structure is well defined (Number of relationships or joins).

I hope this was understandable. My question is how to design the classes and relationships to be able to do what I outlined.

EDIT:

Kind of translation issue. with version i did not mean in terms of "versioning" but more in terms of "different variety" but fundamentally the same. There is no active / inactive. All are active.

EDIT 2:

Also note that these classes are entity classes and hence complex inheritance and hierarchies can be problematic.

EDIT 3:

Just don't see how either pattern (Composite, decorator) can work. I tried but the problem is the "path traversal", eg. implementing it in the context of Spring-data and QueryDSL.

I've created Class diagramm with comments that might help to understand the issue. Batch = Version.

Class Diagramm

4
  • Sorry, I don't get what "A special implementation of Compound has Versions" is. Is it a subclass of Compound? Then what's the problem to define a Container in order to keep a Compound and at Runtime pass to it a "Compound" or a "CompoundWithVersions"? :) Nov 15, 2012 at 9:27
  • No, a version is a separate class that has exactly 1 Compound associated to it. Also version are numbered, eg. Version 1, Version 2 and so on. The Problem is that what needs to be referenced in the Container is 1 specific version of a compound and not the "general compound" itself. At least for this special case.
    – beginner_
    Nov 15, 2012 at 10:30
  • I seeks not to know all the answers but to understand the questions. Class diagram please. - Kwai Chang Caine Dec 8, 2012 at 23:21
  • Well that is the question, how should the class diagramm look (which pattern to use) so I can achieve what I want.
    – beginner_
    Dec 11, 2012 at 6:19

6 Answers 6

1

... to search for Containers which contain a Compound made up of a specific Structure requires that the "Path" from Container to Structure is well defined (Number of relationships or joins).

Not if you are asking the container if it has such a structure yes or no, then only the container needs to know the path. You can keep it an implementation detail in such a case.

Implement a container class for version-less compounds, and an implementation for version-ed compounds. You indirectly traverse the structures through delegation.

0

Can you have the special Compound implementation pass invocations of its Compound methods to its active Version? That way the Container wouldn't know that it has a special Compound.

1
  • 1
    Good idea however I have used the wrong "abstraction". It's not a version in terms of versioning. It' more like a variation. So there is no active / inactive. Car analogy: Compound = specific model of car. Version = includes extras like AC, leather seats, color, etc..so all versions are fundamentally the same and vary only in small details.
    – beginner_
    Nov 15, 2012 at 18:27
0

If I understand correctly, Compound is an abstract class. One implementation of a compound doesn't have Versions but another does. As @SteveEmmerson suggested, giving Compound an ActiveVersion property would solve this design problem.

The option I prefer is to apply the Composite pattern. In this design, the implementation of Compound (say, VersionedCompound) would be responsible for which Version's data to present when it's treated like a Compound.

I prefer it because this design is additive, in other words, it does not require refactoring the Compound class.

2
  • Can you elaborate further? I don't see why the Composite pattern applies or how I should implement? As far as I understood a Version would be an implementation of compound too?
    – beginner_
    Nov 16, 2012 at 7:14
  • In the Composite pattern, you have a container that can act as one of its members. In this case, you have a VersionedCompound that contains a set of Versions, but also acts like a Compound. It's the job of the VersionedCompound class to decide which version's details to return when its Compound methods are called. I think the examples at the link in my answer demonstrate how to implement this.
    – neontapir
    Nov 16, 2012 at 15:43
0

There are so many ways to accomplish variation in code structures and function.

In this case, if their are no functions that operate differently for a versioned Compound than a non-versioned Compound, then inheritance or some design pattern would be overkill.

How about just an attribute "version"? For simple compounds, the version could be "none" or 0 or 1, whatever makes most sense for the way you use it.

If for some reason the actual functions on Compound need to be implemented differently, then you do want polymorphism. In that case, I think neontapirs description of using the Composite pattern is a good direction.

How do you expect the client code to use a Compound versus a Versioned Compound?

Are these like isotopes, or left-handed/right-handed sugars?

0

This problem can be tackled using Decorator pattern. Just keep Container related to Compound, and turn Version into a decorator of Compound.

Using the reference diagram here, your problem could be mapped this way:

  • Component = Compound
  • ConcreteComponent = concrete Compound that holds Structures
  • Decorator = Version Concrete
  • Decorator = version of models or packs of extras

Hope it helps.

1
  • I will look into this The composite pattern theoretically works. However I need to be able to query (know the exact path to structure)) any "Containable" a developer will create using the preexisting "Search class". I use querydsl and it does not work with composite pattern.
    – beginner_
    Dec 11, 2012 at 6:23
0

The solution I used is this:

Class Diagram

And to reference the image in the question, a Batch extends Containable.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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