in this example a navigation service is used to navigate between different view. as i understand the navigation service works like a factory that loads a certain view according to a given string. To load a special view for a model object on can pass the navigation service a second object of base type in addition to the string. This object can be acquired by the specialized presenter to initialize the view. As the second object is of base type a downcast is required inside the presenter before use.
my question is if downcasting in this scenario is a good or let's say common style. as i understand the interface of the view factory should not change and therefore a string is passed to the load method instead of having a special method for each view. from that decision the downcast is necessary.
should I go like this in my application or should I avoid downcasting.
does anyone have a link to real world application that uses mvp that can serve as a good example.?
> in this example a navigation service is used to navigate between different > view. as i understand the navigation service works like a factory that loads > a certain view according to a given string. To load a special view for a > model object on can pass the navigation service a second object of base type > in addition to the string. This object can be acquired by the specialized > presenter to initialize the view. As the second object is of base type a > downcast is required inside the presenter before use.
> my question is if downcasting in this scenario is a good or let's say common > style. as i understand the interface of the view factory should not change > and therefore a string is passed to the load method instead of having a > special method for each view. from that decision the downcast is necessary.
> should I go like this in my application or should I avoid downcasting.
> does anyone have a link to real world application that uses mvp that can > serve as a good example.?
Let me make sure I have this straight. You are passing in a string to tell the factory what kind of sub-class to create, then you are having to down-cast the object returned to the sub-class you know it is?
If that is the essence of what you are saying, then the problem with it should be obvious.
Daniel T. wrote: > Let me make sure I have this straight. You are passing in a string to > tell the factory what kind of sub-class to create, then you are having > to down-cast the object returned to the sub-class you know it is?
> If that is the essence of what you are saying, then the problem with it > should be obvious.
Not to me: Does Java still lack covariant return types?
> Let me make sure I have this straight. You are passing in a string to > tell the factory what kind of sub-class to create, then you are having > to down-cast the object returned to the sub-class you know it is?
Let's say I have a bunch of model classes e.g. "Circle", "Box", "Triangle. All classes are sub classes of bases class "Geometry" To edit certain properties I have a properties view for each type. The specific view is created by a factory that is passed a string to determine the type. Together to the string the model object ("Circle", "Box" or "Triangle") is passed. The model object is than passed to the specific presenter of the view. As the additional parameter for the model object is of base type "Geometry" I have to down-cast the model object to either "Circle", "Box" or "Triangle" inside of the presenter.
In this case the factory has only one method to create a view:
createView(String type, Geometry model)
To avoid casting the factory might have a create method for each geometry:
Jannis Linxweiler wrote: >> Let me make sure I have this straight. You are passing in a string to >> tell the factory what kind of sub-class to create, then you are having >> to down-cast the object returned to the sub-class you know it is? > Let's say I have a bunch of model classes e.g. "Circle", "Box", > "Triangle. All classes are sub classes of bases class "Geometry" To edit > certain properties I have a properties view for each type. The specific > view is created by a factory that is passed a string to determine the > type. Together to the string the model object ("Circle", "Box" or > "Triangle") is passed. The model object is than passed to the specific > presenter of the view. As the additional parameter for the model object > is of base type "Geometry" I have to down-cast the model object to > either "Circle", "Box" or "Triangle" inside of the presenter. > In this case the factory has only one method to create a view: > createView(String type, Geometry model) > To avoid casting the factory might have a create method for each geometry: > createBoxView(Box b) > createCircleView(Circle c) > What should I prefer?
#3 is what is known as covariant input parameters. There are programming languages that, given #3 will select the correct operation in #2 to execute (the process is called "multiple dispatch" ) .
If you are not using such prog langs, then you can emulate #3 using the Visitor pattern.
You can also scrutinise #3. For all code akin to #3, what is the actual value of <SomeType> ?? <SomeType> = Geometry, Circle etc ??
If the latter, you can use the createView op in #2 directly. If the former, you have the convariant input parameters problem.
Once you have assessed which scenario(s) exist, and what the occurrence pattern is, then you can decide which solutions are most appropriate.
"Jannis Linxweiler" <j.linxwei...@gmx.de> writes: > Let's say I have a bunch of model classes e.g. "Circle", "Box", > "Triangle. All classes are sub classes of bases class "Geometry" To > edit certain properties I have a properties view for each type. The > specific view is created by a factory that is passed a string to > determine the type. Together to the string the model object > ("Circle", "Box" or "Triangle") is passed. The model object is than > passed to the specific presenter of the view. As the additional > parameter for the model object is of base type "Geometry" I have to > down-cast the model object to either "Circle", "Box" or "Triangle" > inside of the presenter.
If you know the subtype you want to create and you know the subtype of the object that is returned by the Factory, why are you using a Factory at all? Why not just construct an instance of Circle, Box, or Triangle?
Alternatively, have the Factory return the appropriate Presenter so that the code that invokes the Factory doesn't need to know about any View or Presenter subtypes.
Regards,
Patrick
------------------------------------------------------------------------ S P Engineering, Inc. | Large scale, mission-critical, distributed OO | systems design and implementation. p...@spe.com | (C++, Java, Common Lisp, Jini, middleware, SOA)
> > Let me make sure I have this straight. You are passing in a string to > > tell the factory what kind of sub-class to create, then you are having > > to down-cast the object returned to the sub-class you know it is?
> Let's say I have a bunch of model classes e.g. "Circle", "Box", "Triangle. > All classes are sub classes of bases class "Geometry" To edit certain > properties I have a properties view for each type. The specific view is > created by a factory that is passed a string to determine the type. Together > to the string the model object ("Circle", "Box" or "Triangle") is passed. > The model object is than passed to the specific presenter of the view. As > the additional parameter for the model object is of base type "Geometry" I > have to down-cast the model object to either "Circle", "Box" or "Triangle" > inside of the presenter.
> In this case the factory has only one method to create a view:
> createView(String type, Geometry model)
> To avoid casting the factory might have a create method for each geometry:
> createBoxView(Box b) > createCircleView(Circle c) > .
> What should I prefer?
Out of the two choices, I prefer the latter. If you make a new sub- class of Geometry, you will have to change your createView function (or make another one and have each work on a proper sub-set of geometry objects.) This means that the createView(String type, Geometry model) function is lying when it implies that it can work with any Geometry object. Don't write code that lies.