Alright, maybe I'm doing something completely wrong (yeah, yeah, Chuck), but this isn't an apples and oranges thing.

They are both nutritional values, for example: "Calories: 120"

The difference between my two subclasses is simply how the value of the valueQuantity() attribute is derived. In one subclass the user specifies the amount, and in the other it is calculated from the components that make up the product that the nutrition information is tied to. This made me think: different implementations of the same core object means two subclasses.

I think the best thing I could do is throw the whole inheritance structure out and simply put an "if" clause on the valueQuantity() method that returns the calculated value if nutritionValueType() returns "Calculated", or simply change nutritionValueType() to an isCalculated() boolean instead.

Just doesn't seem as cool though. But I guess "working" is even cooler.

Dave

On Feb 13, 2008, at 3:57 PM, David Elliott wrote:

Hi David,

I can tell you right now that you're going down a very dangerous path here.

Consider even simple code like this:

MyObject *foo; // from somewhare
foo.setNutritionValueType(...);
// foo is still the old instance.

When you subclass like this you need to know _before_ you create the object which subclass it is to have. To do anything else is to completely defeat the very purpose of subclassing in the first place. If you are using D2W there are little methods you can use to provide the user his choice before actually creating the object. If you are not using D2W then you just ask the user in advance.

One UI pattern I've used is something like this:

Add new: [_] Apple [_] Orange    [+]

Where [+] is a regular button to add the new object to the list and Apple/Orange is a set of radio buttons. You could use a pop-up or whatever else instead. Or you could create an add button for each object.

What you cannot do is create a Fruit and then expect to be able to make it an Apple or an Orange at your whim. It doesn't work that way. Subclassing _might_ be the appropriate thing to do in your case but it's a very advanced feature of EOF that you have to plan for very well.

One other thing. If the attributes are the same regardless of the type (and by this example, they seem to be) then subclassing is the wrong thing to do entirely. If you want different behavior for different nutrition types based on the same set of attributes then I suggest you break your logic into a separate class.

For example:

class Fruit {
...
        static abstract class Calculator {
                abstract void doSomething(Fruit fruit);
        };
        static class AppleCalculator extends Calculator {
                ...
        };
        static class OrangeCalculator extends Calculator {
                ...
        };

static NSDictionary _calculatorForType = new NSDictionary(new String[]
                {       "APPLE"
                ,       "ORANGE
                }, new Calculator[]
                {       new AppleCalculator()
                ,       new OrangeCalculator()
                });
...
};

You might even implement a cover method like so:
static Calculator calculatorForType(FruitType ft)
{
return (Calculator)_calculatorForType.valueForKey(ft.fruitTypeCode ());
}

That will get you polymorphism (thus allowing you to avoid nasty switch or if/elif) without requiring the objects themselves have their own distinct types.

Note that the above isn't compiled, it's just a general example I typed straight into this mail. Also note I've been doing more C++ than Java coding lately so I probably have semicolons where I don't need them.

There's other ways to do it too. For example, you can give each object its own instance of Calculator in which case it will be easier to make it a non-static inner class and acually store the pointer to it as a _calculator i-var or something of the sort.

It all really depends on how much state you need or do not need to put in the separate Calculator class.

-Dave

On Feb 13, 2008, at 3:26 PM, David Avendasora wrote:

Well, I've got it working, somewhat. I'm creating a new instance of the other subclass, copy all the attributes and relationships over, then delete the old instance.

The problem I'm having is that I'm somehow getting two instances of the target subclass. Maybe someone can look at this code and tell me what I'm doing wrong.

public void setNutritionValueType(NutritionValueType aValue) {
        if (nutritionValueType() == null || aValue == null) {
                super.setNutritionValueType(aValue);
        } else if (aValue != nutritionValueType()) {
                CalculatedNutritionValue nv = new CalculatedNutritionValue();
                editingContext().insertObject(nv);
                nv.setIsSuspect(isSuspect());
nv.addObjectToBothSidesOfRelationshipWithKey(nutritionBlock(), "nutritionBlock"); nv.addObjectToBothSidesOfRelationshipWithKey(nutritionElement(), "nutritionElement"); nv.addObjectToBothSidesOfRelationshipWithKey(aValue, "nutritionValueType");
                nv.setSortOrder(sortOrder());
nv.addObjectToBothSidesOfRelationshipWithKey(unitOfMeasure(), "unitOfMeasure");
                nv.setValueQuantity(valueQuantity());
                editingContext().deleteObject(this);
        }
}

It seems very simple. I just don't get where I'm getting a second instance. If I save the EditingContext, I do get two new records in the DB.

Any guesses? Anyone?

Dave

On Feb 13, 2008, at 3:01 PM, Ken Anderson wrote:

David,

I've been down this path many times, and my current recommendation is to just have some kind of type on the object that identifies it as one or the other. I have a situation where I store the class name of a 'calculator' class in the EO, and then dynamically call static methods on that class to do the heavy lifting.

Ken

On Feb 13, 2008, at 11:15 AM, Mike Schrag wrote:

I could just create a new object of the new class and delete the existing one
yes

What is the best way to get WO to pickup the subclass change immediately?

Or is this just a bad way of doing things?
yes

Inheritance hierarchy is to be treated like a PK -- It's an unchanging attribute of an EO. In fact, it's actually part of the EOGlobalID.

What you're describing is very similar to the Employee vs Manager modeling problem. The general consensus is that when an Employee becomes a Manager, it's not changing types, it's changing Roles, so it's actually a Person=>Role, where Role is Manager or Employee and you are just changing the relationship, not the intrinsic type.

You should consider type to be immutable for your own safety and the safety of those around you. The correct way is to delete your old class and make a new one, or maintain a relationship to (something like) a NutrionValueCalculator that changes (if there is a lot of other state in this object other than just this value).

ms

_______________________________________________
Do not post admin requests to the list. They will be ignored.
Webobjects-dev mailing list      ([email protected])
Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/webobjects-dev/kenlists% 40anderhome.com

This email sent to [EMAIL PROTECTED]

_______________________________________________
Do not post admin requests to the list. They will be ignored.
Webobjects-dev mailing list      ([email protected])
Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/webobjects-dev/webobjects% 40avendasora.com

This email sent to [EMAIL PROTECTED]



_______________________________________________
Do not post admin requests to the list. They will be ignored.
Webobjects-dev mailing list      ([email protected])
Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/webobjects-dev/dfe%40tgwbd.org

This email sent to [EMAIL PROTECTED]




_______________________________________________
Do not post admin requests to the list. They will be ignored.
Webobjects-dev mailing list      ([email protected])
Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/webobjects-dev/archive%40mail-archive.com

This email sent to [EMAIL PROTECTED]

Reply via email to