Want to improve this question? Update the que开发者_JAVA百科stion so it focuses on one problem only by editing this post.
Closed 5 years ago.
Improve this questionI tend to have a class to describe a general concept and subclasses to describe variances in that concept. For example, Polygon
<|-- {Rectangle
, Triangle
, etc.}.
However, I often find I have various representations of these hierarchies. For example, I want to keep the graphical representation (eg, a QPolygon), or the physical representation (mass, centerOfMass), etc. separate from another representation I have.
In my case, I have a hierarchy of purely-data objects (Command
<|-- {WaitCommand
, UnknownCommand
, etc.}) and I have a matching GUI representation for each of the data classes (WaitCommandPanel
, UnknownCommandPanel
).
My problem is that once I construct the data representation I need to make the leap from the data to the GUI.
Given a list of data objects, I want to be able to construct the corresponding GUI elements but keep the two representations separate.
One [lousy] solution would be for each Command
to have the ability (ie, Command::getPanel()
) to return its GUI representation. I don't like this because my data classes now have representation code in them.
The other solution (which I've adopted for the time being) is to do a lookup. That is, when initiating the GUI, given a list of Command
s (the generalization), the function determines what object to create based on its specialized type. I don't like this either.
Any suggestions?
IMHO, neither data class no rendering class have a responsibility to make a decision about which renderer to use for a given data object. I do prefer your second option. I usually use a map that maps data-type into a renderer class. Also note that such mapping is context specific (web rendering will use different renderers from destop app, or fitness context).
Such mapping can be constructed automatically, for example using attributes (in .Net) or maybe naming convention (in Lua). Or using external XML-config file.
Summary: somebody have to make that decision, and according to SRP neither renderer nor data object shall be responsible for that. Such logic is application-context specific, and as such should be 'above' both of those actors (i.e. renderer and data).
You may want to look into using an inversion of control (IoC) container to build up your classes.
Each class would contain an interface of of it's associated class. The IoC container would then inject the implementation of that class into your object according how you have configured it.
精彩评论