By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
449,420 Members | 1,085 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 449,420 IT Pros & Developers. It's quick & easy.

Creating objects polymorphically

P: n/a
Hi all

Let's say I am creating a model to represent classes and properties. In
addition to this I need instances of classes and values for those
properties.

KEY:
[ClassName]
(AssociationEndName)
A classifier has many properties
[Classifier] (Classifier) 1-----* (Properties) [Property]

A classifier has many instances
[Classifier] (Classifier) 1-----* (Instances) [Instance]

An instance has many property values
[Instance] (Instance) 1----* (PropertyValues) [PropertyValue]

A Property has many PropertyValues
[Property] (Property) 1----* (PropertyValues) [PropertyValue]
I hope that's clear :-)

var personClassifier = new Classifier();
var firstNameProperty = new Property();
personClassifier.Properties.Add(firstNameProperty) ;

At this point I want to do something like this

var personInstance = Instance.FromClassifier(personClassifier);

the implementation would look something like this

public static Instance FromClassifier(Classifier classifier)
{
var result = new Instance();
result.Classifier = classifier;

foreach (var property in classifier.Properties)
{
var propertyValue = new PropertyValue();
result.PropertyValues.Add(propertyValue);
propertyValue.Property = property;
}
}

The above is a simple example. The fact is I have a pre-defined set of
property types. So descended from Property I might have

StringProperty, NumericProperty, BooleanProperty, etc

and a corresponding PropertyValue class for each

StringPropertyValue, NumericPropertyValue, BooleanPropertyValue, etc
To achieve the creation of the correct PropertyValue descendant I added an
abstract method to Property

public abstract PropertyValue CreatePropertyValue(Property property);

and implement in each descendant

public override PropertyValue CreatePropertyValue(Property property)
{
var result = new BooleanPropertyValue();
result.StronglyTypedReference = (BooleanProperty)property;
return result;
}
Now onto the question :-)

To me this seems logical, but a little messy. I don't like the fact that
the Property class creates the instance of the PropertyValue. What I would
expect to write in code is something like

var property = BooleanPropertyValue.FromProperty(booleanProperty) ;

but obviously in this case I can't hard-code the class type into my foreach
loop. So it seems I am stuck with the Property being responsible for
creating the correct PropertyValue instances. Or do I have another option?

--
Pete
====
http://mrpmorris.blogspot.com
http://www.capableobjects.com

Oct 7 '08 #1
Share this Question
Share on Google+
3 Replies


P: n/a
On Tue, 07 Oct 2008 09:42:39 -0700, Peter Morris
<mr*********@spamgmail.comwrote:
[...]
To me this seems logical, but a little messy. I don't like the fact
that the Property class creates the instance of the PropertyValue. What
I would expect to write in code is something like

var property = BooleanPropertyValue.FromProperty(booleanProperty) ;

but obviously in this case I can't hard-code the class type into my
foreach loop. So it seems I am stuck with the Property being
responsible for creating the correct PropertyValue instances. Or do I
have another option?
I have to admit, the whole way through your explanation of the design, I
found myself thinking "surely this is overcomplicated".

And I still think that. I tried to keep an open mind, but there just seem
to be a lot of extra unnecessary layers. It's possible I just don't
understand the bigger picture enough, but my impression is what it is.

That said, what you're talking about seems pretty much like a classic
factory pattern. That is, put your FromProperty() method in the
PropertyValue base class, rather than each sub-class. Then in that
method, check the type of the passed-in Property instance to determine
what kind of PropertyValue to return.

Of course, _that_ said, I'm not really clear on why you feel it's bad to
have the abstract method in the Property sub-class. The factory approach
is less "polymorphic" than the abstract method approach would be. It does
spread the logic around through each sub-class, but then putting
type-specific implementation into each sub-class is the whole point of
polymorphism. It seems like the solution you've already been using should
be fine.

Pete
Oct 7 '08 #2

P: n/a
Peter Morris wrote:
Hi all

Let's say I am creating a model to represent classes and properties.
In addition to this I need instances of classes and values for those
properties.
Rebuilding the Delphi "class of class" metaclasses? AFAIK, Joanna
Carter once wrote a nice article on this, IOW, how to do this using C#.
--
Rudy Velthuis http://rvelthuis.de

"I'm not under the alkafluence of inkahol that some thinkle
peep I am. It's just the drunker I sit here the longer I get."
-- Unknown
Oct 7 '08 #3

P: n/a
I'm actually building messages from templates. For example

[MessageTemplate] (Template) 1-----* (Properties) [MessageTemplateProperty]

The MessageTemplate might be something like

Name : string;
=========
Message : string;
Discount : decimal;
So I would create 1 MessageTemplate, and
MessageTemplateStringProperty
MessageTemplateNumericalProperty

That's the template defined by some kind of admin, now the users will create
messages based on it...

Name = "10% off handbags"
Message = "This week only. 10% of all marked prices on handbags!!!"
Discount = 10m;

Name = "15% off squirrels"
Message = "This week only. 15% of all marked prices on squirrels!!!"
Discount = 15m;
This information gets packaged up as XML something like this

<messages>
<message id="1" templateID="{GuidOfTheTemplate}">
<values>
<value id="{GuidOfTheTemplateProperty}">
This week only. 10% of all marked prices on handbags!!!"
</value>
<value name="{GuidOfTheTemplateProperty}">
10
</value>
</values>
</message>
<message id="1" templateID="{GuidOfTheTemplate}">
<values>
<value id="{GuidOfTheTemplateProperty}">
This week only. 15% of all marked prices on squirrels!!!"
</value>
<value name="{GuidOfTheTemplateProperty}">
15
</value>
</values>
</message></messages>

It's concocted, but illustrates the point :-)

Having a virtual method on the abstract MessageTemplateProperty does the
trick, but there's just something about it that makes me feel dirty, and not
good dirty :-) I was hoping there was a pattern or something that might
make more sense, otherwise I will just leave it as it is :-)

Thinking about it, I use the service provider pattern throughout my system.
Maybe I should create something like this:

public interface IMessagePropertyFactory
{
MessageProperty CreateMessageProperty(MessageTemplateProperty
templateProperty);
}

I can then get this factory from my service provider, which would mean I can
mock it easily and check that it is being called from a unit test. Or maybe
that is overkill :-)
--
Pete
====
http://mrpmorris.blogspot.com
http://www.capableobjects.com

Oct 7 '08 #4

This discussion thread is closed

Replies have been disabled for this discussion.