From: Sasa on
Hi,

Sorry for pushing the topic, but I still have some doubts about it and
would like to hear from you.

The example I'm going to give is based on the .NET Windows Forms, but
it's really a design related question not related to technology. I'll
try to explain the relevant stuff to non .NET people, so if you have
patience/time read on...

In .NET world, there is a class called Form which essentially represents
a windows form (basically standard MS Windows' window). A Form class has
fairly large interface which can be used to manipulate the window. This
includes methods/properties such as changing window position/size,
setting its style, back color, caption etc. as well as adding child
controls.

When designing custom form via MS Visual Studio designer, the
corresponding C# code (if one does it in C# project of course) is
designed which uses the aforementioned class Form and its interface to
achieve the look created in the designer.

Following are facts about generated code:
1. The generated code is placed in a separate class.
2. The class is derived from the Form class.
3. The generated code uses only public features of the Form class. It
introduces no overrides.
4. For each child control added to the form via the designer, the
appropriate member variable is added to the generated class. I can use
this member to manipulate the child control in the runtime.
5. For each event I want to handle, the designer creates appropriate
method in the generated class.

In the spirit of the topic I started earlier ("yet another deriving
question") I would say that there is no need to derive from the Form.
The generated code could easily be modified to instantiate the Form
class and achieve the desired look by using its public interface.
Now, new class still must be created, if nothing else then because of
points no. 4 and 5. But there is no need for this class to be derived
from the Form.

Benefit of such approach:
If the generated class would wrap the instance of the Form as a private
member (rather than inheriting from it), it could protect its users from
the direct dependency to the Form class.

Downsides:
1. It is hard to imagine that .NET Windows Forms developer will ever
want to use something else.

2. If the generated class is derived from the Form its users get the
usual Form public interface for free. Recall what I said, that the Form
class has large interface. This could be resolved by making the
generated class contain and return the reference to the contained Form,
but by doing this, the single benefit gets lost.

This re raised some basic questions. Is polymorphism (as the VS designer
uses it) appropriate here, even though the derived class doesn't change
the behavior, but only adds new one? Which approach do you see as
preferable and why?

Thanks,
Sasa
From: Frans Bouma on
Sasa wrote:
> In .NET world, there is a class called Form which essentially
> represents a windows form (basically standard MS Windows' window). A
> Form class has fairly large interface which can be used to manipulate
> the window. This includes methods/properties such as changing window
> position/size, setting its style, back color, caption etc. as well as
> adding child controls.
>
> When designing custom form via MS Visual Studio designer, the
> corresponding C# code (if one does it in C# project of course) is
> designed which uses the aforementioned class Form and its interface
> to achieve the look created in the designer.
>
> Following are facts about generated code:
> 1. The generated code is placed in a separate class.
> 2. The class is derived from the Form class.
> 3. The generated code uses only public features of the Form class. It
> introduces no overrides.

Why would it use overrides? The thing is: the code which makes up YOUR
form is stored in a method, called InitializeComponent. That method is
called from the constructor generated into the code which makes up your
form.

This is done on purpose. Say, this wasn't done and InitializeComponent
was a method of the class Form, called from its empty constructor (i.e.
no parameters).

There's no constructor generated into your form code, just an override
of the InitializeComponent method.

Now, you create a new constructor which accepts a parameter.
Your form doesn't work anymore, as the base constructor isn't called.

With the method generated into the empty constructor, you see you need
to call that method in the constructor. It's still not solid though,
but there's no real solution for this, other than introducing a
pre-load method which is called by the framework. This actually creates
more confusion: what happens when?, the same confusion seen with
ASP.NET forms.

> 4. For each child control added to the form
> via the designer, the appropriate member variable is added to the
> generated class. I can use this member to manipulate the child
> control in the runtime.
> 5. For each event I want to handle, the
> designer creates appropriate method in the generated class.

this actually is simply doing things you could do yourself as well.
Instead of setting the eventhandler in the designer, you can also wire
the event in the constructor, or the load event handler.

> In the spirit of the topic I started earlier ("yet another deriving
> question") I would say that there is no need to derive from the Form.
> The generated code could easily be modified to instantiate the Form
> class and achieve the desired look by using its public interface.
> Now, new class still must be created, if nothing else then because of
> points no. 4 and 5. But there is no need for this class to be derived
> from the Form.

Sure you could do that, smells like the MVC pattern :)
The thing is actually academic: do you want to store your form's
control code how the form looks INSIDE the form class (as it belongs to
that form class and to that form class alone) or do you want to store
it outside the form class, which avoids a subclass but REQUIRES a
separate controller class?

> Benefit of such approach:
> If the generated class would wrap the instance of the Form as a
> private member (rather than inheriting from it), it could protect its
> users from the direct dependency to the Form class.

why would aggregation be of any advantage here? Overriding a simple
thing like the OnClosing method of the form is in your approach a
problem.

> Downsides:
> 1. It is hard to imagine that .NET Windows Forms developer will ever
> want to use something else.

and rightfully so.

> 2. If the generated class is derived from the Form its users get the
> usual Form public interface for free. Recall what I said, that the
> Form class has large interface. This could be resolved by making the
> generated class contain and return the reference to the contained
> Form, but by doing this, the single benefit gets lost.

So concluding, what you propose isn't that great... ? :)

> This re raised some basic questions. Is polymorphism (as the VS
> designer uses it) appropriate here, even though the derived class
> doesn't change the behavior, but only adds new one? Which approach do
> you see as preferable and why?

The initially generated class which represents YOUR form doesn't use
polymorphism YET, but can do that, if you want to. As you might know, a
Form is actually a Control. So you can override whatever virtual
property/method of Control in your own Form class to make it act
differently in a piece of code which acts on Controls.

It's this polymorphic behavior which makes it possible to use forms as
controls in docking /sliding frames in a .NET app :)

Frans

--
------------------------------------------------------------------------
Lead developer of LLBLGen Pro, the productive O/R mapper for .NET
LLBLGen Pro website: http://www.llblgen.com
My .NET blog: http://weblogs.asp.net/fbouma
Microsoft MVP (C#)
------------------------------------------------------------------------
From: Sasa on

"Frans Bouma" <perseus.usenet.NOSPAM.(a)xs4all.nl> wrote in message
news:xn0equz4q68tnu000(a)news.xs4all.nl...
> Sasa wrote:
>> In .NET world, there is a class called Form which essentially
>> represents a windows form (basically standard MS Windows' window). A
>> Form class has fairly large interface which can be used to manipulate
>> the window. This includes methods/properties such as changing window
>> position/size, setting its style, back color, caption etc. as well as
>> adding child controls.
>>
>> When designing custom form via MS Visual Studio designer, the
>> corresponding C# code (if one does it in C# project of course) is
>> designed which uses the aforementioned class Form and its interface
>> to achieve the look created in the designer.
>>
>> Following are facts about generated code:
>> 1. The generated code is placed in a separate class.
>> 2. The class is derived from the Form class.
>> 3. The generated code uses only public features of the Form class. It
>> introduces no overrides.
>
> Why would it use overrides? The thing is: the code which makes up YOUR
> form is stored in a method, called InitializeComponent. That method is
> called from the constructor generated into the code which makes up your
> form.
>
> This is done on purpose. Say, this wasn't done and InitializeComponent
> was a method of the class Form, called from its empty constructor (i.e.
> no parameters).
>
> There's no constructor generated into your form code, just an override
> of the InitializeComponent method.
>
> Now, you create a new constructor which accepts a parameter.
> Your form doesn't work anymore, as the base constructor isn't called.
>
> With the method generated into the empty constructor, you see you need
> to call that method in the constructor. It's still not solid though,
> but there's no real solution for this, other than introducing a
> pre-load method which is called by the framework. This actually creates
> more confusion: what happens when?, the same confusion seen with
> ASP.NET forms.

I never said the code must introduce overrides, and I agree with you.
I just explained this for the purpose of the topic.

>
>> 4. For each child control added to the form
>> via the designer, the appropriate member variable is added to the
>> generated class. I can use this member to manipulate the child
>> control in the runtime.
>> 5. For each event I want to handle, the
>> designer creates appropriate method in the generated class.
>
> this actually is simply doing things you could do yourself as well.
> Instead of setting the eventhandler in the designer, you can also wire
> the event in the constructor, or the load event handler.

That's perfectly clear. Again, I just wanted to point out some interesting
features of the generated code.

>> In the spirit of the topic I started earlier ("yet another deriving
>> question") I would say that there is no need to derive from the Form.
>> The generated code could easily be modified to instantiate the Form
>> class and achieve the desired look by using its public interface.
>> Now, new class still must be created, if nothing else then because of
>> points no. 4 and 5. But there is no need for this class to be derived
>> from the Form.
>
> Sure you could do that, smells like the MVC pattern :)
> The thing is actually academic: do you want to store your form's
> control code how the form looks INSIDE the form class (as it belongs to
> that form class and to that form class alone) or do you want to store
> it outside the form class, which avoids a subclass but REQUIRES a
> separate controller class?

The question is what is Form class, and should the generated code be
specialization of the Form, or simply its user.

>> Benefit of such approach:
>> If the generated class would wrap the instance of the Form as a
>> private member (rather than inheriting from it), it could protect its
>> users from the direct dependency to the Form class.
>
> why would aggregation be of any advantage here? Overriding a simple
> thing like the OnClosing method of the form is in your approach a
> problem.

That's a downside, but I'll discuss it below. Aggregation is advantage
because it decouples user of my class from the Form class. Now I might agree
that it doesn't have significant practical benefit, because we are assuming
that Form class has stable interface, and that existing interface will be
supported in the future versions, and that there probably won't be any
significant alternative to the Form class in the future (however the last
one we don't know for sure).

>> Downsides:
>> 1. It is hard to imagine that .NET Windows Forms developer will ever
>> want to use something else.
>
> and rightfully so.
>
>> 2. If the generated class is derived from the Form its users get the
>> usual Form public interface for free. Recall what I said, that the
>> Form class has large interface. This could be resolved by making the
>> generated class contain and return the reference to the contained
>> Form, but by doing this, the single benefit gets lost.
>
> So concluding, what you propose isn't that great... ? :)

I'm not really proposing it. The idea came to my mind, but I am basically
not sure which approach is more in the OO spirit. I am really trying to
explore this to gain better feeling on when to use inheritance, and when
not.

>> This re raised some basic questions. Is polymorphism (as the VS
>> designer uses it) appropriate here, even though the derived class
>> doesn't change the behavior, but only adds new one? Which approach do
>> you see as preferable and why?
>
> The initially generated class which represents YOUR form doesn't use
> polymorphism YET, but can do that, if you want to. As you might know, a

Of course it could. But the way I understand polymorphism - its purpose is
to vary implementation while keeping the same (base) interface. If I need to
override, it is another responsibility. In that case I basically want to
introduce new Form which modifies the default behavior of the Form class.
However, in my mind, the designer generated code doesn't modifies the
behavior of the Form. It reuses the Form in order to achieve look&feel of my
form. The very fact, that its code can be converted to the black box is the
proof of that. What do you think?

> Form is actually a Control. So you can override whatever virt
From: H. S. Lahman on
Responding to Sasa...

> The example I'm going to give is based on the .NET Windows Forms, but
> it's really a design related question not related to technology. I'll
> try to explain the relevant stuff to non .NET people, so if you have
> patience/time read on...
>
> In .NET world, there is a class called Form which essentially represents
> a windows form (basically standard MS Windows' window). A Form class has
> fairly large interface which can be used to manipulate the window. This
> includes methods/properties such as changing window position/size,
> setting its style, back color, caption etc. as well as adding child
> controls.
>
> When designing custom form via MS Visual Studio designer, the
> corresponding C# code (if one does it in C# project of course) is
> designed which uses the aforementioned class Form and its interface to
> achieve the look created in the designer.
>
> Following are facts about generated code:
> 1. The generated code is placed in a separate class.
> 2. The class is derived from the Form class.

As soon as I read this I started jumping up and down. (See below.)

> 3. The generated code uses only public features of the Form class. It
> introduces no overrides.

I'm confused. Where does automatic code generation come into the picture?

> 4. For each child control added to the form via the designer, the
> appropriate member variable is added to the generated class. I can use
> this member to manipulate the child control in the runtime.
> 5. For each event I want to handle, the designer creates appropriate
> method in the generated class.
>
> In the spirit of the topic I started earlier ("yet another deriving
> question") I would say that there is no need to derive from the Form.

I agree.

The Form is (should be) primarily a data holder whose only behavior
responsibility might be to talk to the OS Window manager to render the
image. IOW, it is an entity from the UI problem space.

In contrast, whoever understands the problem semantics of what
information should actually go into the display is a quite different
critter that is abstracting the customer problem space. Those entities
are apples & oranges.

> The generated code could easily be modified to instantiate the Form
> class and achieve the desired look by using its public interface.

Right. Instantiate it, invoke all the Form setters to initialize the
display, and then invoke Form.doIt() to render the data.

However, you only mentioned the associated controls in passing. I
suspect it is not just a Form instance that needs to be created; you
will also need to create associated Control instances as well. IOW, I
suspect there is need of some sort of factory object here to get
everything done. The segues to application partitioning.

If the UI is complex, the problem space entity that knows what
information to display would likely be in a different subsystem. It
would make a display request with a bundle of data to the UI subsystem
interface. Within the UI subsystem some sort of factory object would
field that request and do the actual instantiation and initialization.
Only that factory object would understand Form and its associated
Controls. IOW, the problem space entity thinks in terms of "display
account" but the UI thinks in terms of "create forms and controls". The
factory object provides the mapping of the message from the customer
space entity to forms and controls.

> Now, new class still must be created, if nothing else then because of
> points no. 4 and 5. But there is no need for this class to be derived
> from the Form.
>
> Benefit of such approach:
> If the generated class would wrap the instance of the Form as a private
> member (rather than inheriting from it), it could protect its users from
> the direct dependency to the Form class.

Uh oh. I am concerned you have now created a god object as your
"generated class". Separate the concerns. Rendering a UI is a
different suite of responsibilities than determining what needs to be
rendered. Let whoever decides what needs to be rendered talk to the guy
who renders on a peer-to-peer basis.

Note, BTW, that if you put the customer space entity in a different
subsystem than the UI entities, the subsystem interface provides all the
decoupling you need (so long as it is a pure message-based data transfer
interface). Because the UI subject matter is so different and requires
different abstractions (Form/Control), it is pretty standard practice to
encapsulate it in its own subsystem for applications with complex UIs.
(A bonus in doing so is that once one abstracts the UI invariants, such
a subsystem can be reusable across applications having the same sort of UI.)

For simple UIs that might be overkill. If you employ some sort of
factory object to create the Form and its associated Controls, that
object provides a decoupling buffer. IOW, it presents a "display
account" interface to the problem space entity and then proceeds to map
that into the setter interface of the Form. Now the object that knows
what data to display needs to know nothing about Forms and Controls.


*************
There is nothing wrong with me that could
not be cured by a capful of Drano.

H. S. Lahman
hsl(a)pathfindermda.com
Pathfinder Solutions
http://www.pathfindermda.com
blog: http://pathfinderpeople.blogs.com/hslahman
"Model-Based Translation: The Next Step in Agile Development". Email
info(a)pathfindermda.com for your copy.
Pathfinder is hiring:
http://www.pathfindermda.com/about_us/careers_pos3.php.
(888)OOA-PATH



From: Frans Bouma on
Sasa wrote:
> "Frans Bouma" <perseus.usenet.NOSPAM.(a)xs4all.nl> wrote in message
> news:xn0equz4q68tnu000(a)news.xs4all.nl...
> > Sasa wrote:
> >> In the spirit of the topic I started earlier ("yet another deriving
> >> question") I would say that there is no need to derive from the
> Form. >> The generated code could easily be modified to instantiate
> the Form >> class and achieve the desired look by using its public
> interface. >> Now, new class still must be created, if nothing else
> then because of >> points no. 4 and 5. But there is no need for this
> class to be derived >> from the Form.
> >
> > Sure you could do that, smells like the MVC pattern :)
> > The thing is actually academic: do you want to store your form's
> > control code how the form looks INSIDE the form class (as it
> > belongs to that form class and to that form class alone) or do you
> > want to store it outside the form class, which avoids a subclass
> > but REQUIRES a separate controller class?
>
> The question is what is Form class, and should the generated code be
> specialization of the Form, or simply its user.

The generated code is code which you don't have to type in anymore.
That's the purpose. So if you delete the generated code, you have to
write the code to fill the form with controls and make the controls do
things and have logic act upon actions performed by the user.

Some people like to make things overly complicated and stack class
upon class and create whole frameworks to display a couple of forms. To
have an external controller for your form (viewer) is only sufficient
if you need to re-use the controller code with other viewers as well.
Often this is not the case.

So the code belonging to the form is IMHO better of INSIDE the form
class, for the sole reason that it belongs to that particular form
class. Why else use OO?

> >> Benefit of such approach:
> >> If the generated class would wrap the instance of the Form as a
> >> private member (rather than inheriting from it), it could protect
> its >> users from the direct dependency to the Form class.
> >
> > why would aggregation be of any advantage here? Overriding a simple
> > thing like the OnClosing method of the form is in your approach a
> > problem.
>
> That's a downside, but I'll discuss it below. Aggregation is
> advantage because it decouples user of my class from the Form class.

that's just saying it does decouple them, but it doesn't explain the
advantage.

> Now I might agree that it doesn't have significant practical benefit,
> because we are assuming that Form class has stable interface, and
> that existing interface will be supported in the future versions, and
> that there probably won't be any significant alternative to the Form
> class in the future (however the last one we don't know for sure).

it has a severe downside: you've to replicate the Form's interface in
your own class, which creates MORE code, and for what?

WHY do you want to make this so overly complicated? I fail to see it.
Software development isn't getting better by making things complicated.

> >> Downsides:
> >> 1. It is hard to imagine that .NET Windows Forms developer will
> ever >> want to use something else.
> >
> > and rightfully so.
> >
> >> 2. If the generated class is derived from the Form its users get
> the >> usual Form public interface for free. Recall what I said, that
> the >> Form class has large interface. This could be resolved by
> making the >> generated class contain and return the reference to the
> contained >> Form, but by doing this, the single benefit gets lost.
> >
> > So concluding, what you propose isn't that great... ? :)
>
> I'm not really proposing it. The idea came to my mind, but I am
> basically not sure which approach is more in the OO spirit. I am
> really trying to explore this to gain better feeling on when to use
> inheritance, and when not.

that's simple. Only use inheritance if you want to create a
specialized type of an existing type. So YOUR form is a specialized
type of the existing type Form: you add specific code to it.

If you're not doing that, you don't need inheritance.

> >> This re raised some basic questions. Is polymorphism (as the VS
> >> designer uses it) appropriate here, even though the derived class
> >> doesn't change the behavior, but only adds new one? Which approach
> do >> you see as preferable and why?
> >
> > The initially generated class which represents YOUR form doesn't use
> > polymorphism YET, but can do that, if you want to. As you might
> > know, a
>
> Of course it could. But the way I understand polymorphism - its
> purpose is to vary implementation while keeping the same (base)
> interface. If I need to override, it is another responsibility. In
> that case I basically want to introduce new Form which modifies the
> default behavior of the Form class. However, in my mind, the
> designer generated code doesn't modifies the behavior of the Form.

adding code to a form is also changing behavior: you add behavior, so
the behavior isn't THE SAME as the superclass: the superclass' behavior
is a subset of the subclass' behavior IN THAT CASE (i.e. you don't
override a single method).

> It
> reuses the Form in order to achieve look&feel of my form. The very
> fact, that its code can be converted to the black box is the proof of
> that. What do you think?

I think you should let go the VB6 way of thinking and use what's done
for you and you should try to avoid to make everything more complicated
than it is.

Good code is simple, readable, understandable maintainable code which
does what it should do. Complicated complex code which also does what
it should do is IMHO bad code.

> > It's this polymorphic behavior which makes it possible to use forms
> > as controls in docking /sliding frames in a .NET app :)
>
> AFAIK most of the methods/properties of the Control class and its
> derivatives are not virtual. Most of the virtual methods are the
> OnXXX methods which do nothing more than fireing of the events. I'm
> trying to figure out is this a good example of the polymorphism? Do
> you consider this to be good design of the code?

Microsoft's guidelines say that a method or property should only be
virtual if there's a solid use-case scenario available which requires
that that method is virtual so the class is extensible