Re: Properties Shared Amongst Objects
- From: "H. S. Lahman" <hsl@xxxxxxxxxxxxxxxxx>
- Date: Sun, 17 Feb 2008 15:52:52 GMT
Responding to Sanford...
In an application I'm writing, I have a group of objects that are instances of the same class. These objects share the same property values. For example, if I have the following class:
class Component
{
private:
float value;
public:
// Stuff...
float GetValue() const
{
return value;
}
void SetValue(float value)
{
this->value = value;
}
};
And I then have several objects of type Component:
Component c1;
Component c2;
Component c3;
The components are part of a single group, so the "Value" property has the same value for all of the objects in the group. When SetValue is called on one object, it needs to be called for all of the objects in the group with the same value passed to each.
The Composite design pattern is applicable here in that I can add all of the objects to a composite component and treat the group of objects as one.
So far this seems like overkill. There must be some problem space basis for deciding which components are in which group that is apparently fixed over the life of the components. So one might have:
[Group]
| 1
|
| R1
|
| contains
| *
[Component]
+ value
While Group.value is uniquely associated with a particular component, the actual value assigned is actually determined by the instantiation of the relationship. Since the relationship is unconditional, when a Component is instantiated and added to the R1 collection, one could properly set the value.
For <a simplistic> example,
[VehicleClass] // SUV, sedan, etc.
| 1
| member of
|
| R1
|
| *
[Vehicle]
+ has4WheelDrive // boolean
The bottom line is that whatever object understands the problem context enough to know what group a component belongs to would logically know what value Component.value should have. The same principle should apply to the added complexity.
[Note that one could accomplish the same thing with generalization by making [Component] a subclass of [Group] and placing 'value' as a [Group] attribute so that it depends on the identity of the Group directly. However, if there is only one flavor of [Component] that doesn't work and the notion of 'group' may be unrelated to the notion of 'component' (i.e., no problem space is-a), making the generalization contrived.]
So far, so good. However, there is a type of property in my application that needs to be "smoothed" over time. In other words, instead of going from a value of, say, 100 to 1000, the value needs to be interpolated between 100 to 1000, say over a few milliseconds. This is easy enough to realize by running property changes through a lowpass filter. The cost of doing so is non-trivial. If each object smooths the property changes itself, the computation costs add up; since the property values are the same for a group of objects, the interpolation is duplicated in each object.
If I understand this correctly, the value of Component.value is not fixed at instantiation time but it is periodically set during the solution. That still works fine if the new value must be set for every Component in the group at the same time. One just "walks" the R1 collection to set the new value.
The fact that the new value needs to be interpolated between the old value and some target value is a quite different problem. That is a job for whoever determines what the new value is. Now if the way the new value is computed differs from one group to another, that might be a matter for a Strategy pattern, as Daniel T. suggests:
* sets R2 1
[Group] ---------------- [InterpolationStrategy]
+ maxTime + interpolate (newValue, actualMs)
| 1 A
| | R3
| R1 +--------+------...
| | |
... ... ...
where interpolate(...) navigates R2 to get the interpolation time from the right Group and navigates R2 -> R1 to get the right Components and their values to update.
However, for the complexity of your example, I suspect that might also be overkill. The interpolation algorithm can be parameterized so the same algorithm is used for all comonents. IOW, one wouldn't need to subclass the strategy; one would just need attributes in [Group], such as the settling time to reach a new value, that characterize how the interpolation should work for a particular group. If so, that algorithm can be in Group.interpolate().
--
There is nothing wrong with me that could
not be cured by a capful of Drano.
H. S. Lahman
hsl@xxxxxxxxxxxxxxxxx
Pathfinder Solutions
http://www.pathfindermda.com
blog: http://pathfinderpeople.blogs.com/hslahman
"Model-Based Translation: The Next Step in Agile Development". Email
info@xxxxxxxxxxxxxxxxx for your copy.
Pathfinder is hiring: http://www.pathfindermda.com/about_us/careers_pos3.php.
(888)OOA-PATH
.
- Follow-Ups:
- Re: Properties Shared Amongst Objects
- From: Leslie Sanford
- Re: Properties Shared Amongst Objects
- References:
- Properties Shared Amongst Objects
- From: Leslie Sanford
- Properties Shared Amongst Objects
- Prev by Date: Re: Variant record issues (Re: Why is Object Oriented so successfull)
- Next by Date: Re: Properties Shared Amongst Objects
- Previous by thread: Re: Properties Shared Amongst Objects
- Next by thread: Re: Properties Shared Amongst Objects
- Index(es):
Relevant Pages
|