Creating objects polymorphically

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Peter Morris

    #1

    Creating objects polymorphically

    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]
    (AssociationEnd Name)


    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 personClassifie r = new Classifier();
    var firstNameProper ty = new Property();
    personClassifie r.Properties.Ad d(firstNameProp erty);

    At this point I want to do something like this

    var personInstance = Instance.FromCl assifier(person Classifier);

    the implementation would look something like this

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

    foreach (var property in classifier.Prop erties)
    {
    var propertyValue = new PropertyValue() ;
    result.Property Values.Add(prop ertyValue);
    propertyValue.P roperty = 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

    StringPropertyV alue, NumericProperty Value, BooleanProperty Value, etc


    To achieve the creation of the correct PropertyValue descendant I added an
    abstract method to Property

    public abstract PropertyValue CreatePropertyV alue(Property property);

    and implement in each descendant

    public override PropertyValue CreatePropertyV alue(Property property)
    {
    var result = new BooleanProperty Value();
    result.Strongly TypedReference = (BooleanPropert y)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 = BooleanProperty Value.FromPrope rty(booleanProp erty);

    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
    ====







  • Peter Duniho

    #2
    Re: Creating objects polymorphically

    On Tue, 07 Oct 2008 09:42:39 -0700, Peter Morris
    <mrpmorrisNO@sp amgmail.comwrot e:
    [...]
    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 = BooleanProperty Value.FromPrope rty(booleanProp erty);
    >
    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 "polymorphi c" 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

    Comment

    • Rudy Velthuis

      #3
      Re: Creating objects polymorphically

      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

      Comment

      • Peter Morris

        #4
        Re: Creating objects polymorphically

        I'm actually building messages from templates. For example

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

        The MessageTemplate might be something like

        Name : string;
        =========
        Message : string;
        Discount : decimal;


        So I would create 1 MessageTemplate , and
        MessageTemplate StringProperty
        MessageTemplate NumericalProper ty

        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="{Gu idOfTheTemplate }">
        <values>
        <value id="{GuidOfTheT emplateProperty }">
        This week only. 10% of all marked prices on handbags!!!"
        </value>
        <value name="{GuidOfTh eTemplateProper ty}">
        10
        </value>
        </values>
        </message>
        <message id="1" templateID="{Gu idOfTheTemplate }">
        <values>
        <value id="{GuidOfTheT emplateProperty }">
        This week only. 15% of all marked prices on squirrels!!!"
        </value>
        <value name="{GuidOfTh eTemplateProper ty}">
        15
        </value>
        </values>
        </message></messages>

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

        Having a virtual method on the abstract MessageTemplate Property 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 IMessagePropert yFactory
        {
        MessageProperty CreateMessagePr operty(MessageT emplateProperty
        templatePropert y);
        }

        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
        ====





        Comment

        Working...