Mailinglist Archive: yast-devel (46 mails)

< Previous Next >
[yast-devel] CWM Widgets: a rant ;-)
I just wanted to share something that has been in my head for some time.
As programmers, we tend to have some personal affection to "our
creatures", so please don't take it too serious. And consider this a
very low-priority mail, compared to other recent mails in this list. :-)

I have never liked CWM Widgets much and I must say I don't know them in
depth. So I will say many non accurate things in this mail and you are
free to consider this almost as FUD :-). On the other hand, not being as
familiar as the creators can be a good thing - when you get used to the
quirks of a technology you don't see them anymore.

TLDR; Things that really need to be reusable can be made reusable with a
more straightforward and flexible approach. And using a single
"reusable" CWM in your dialog actually enforces all your code (including
the dialog itself) to play by the CWM rules. I'm not sure if I like
that. Although maybe the gain is worth the price and I'm simply failing
to see it.

Now the long version.

I consider the creation of the expert partitioner a great showcase of
the things I dislike from CWM.

There was already a working prototype in yast-storage-ng (and is still
there)[1]. It contains some "debatable" lines of Ruby code and it rates
very low in CodeClimate for many reasons. I didn't write it and, is you
ask me, I don't even like it much. :-) BUT it uses plain Ruby classes
and rely in the nice and straightforward UI::Dialog and its event loop.
You can understand how the code works in 2 minutes. And if you open a
random file, you will know in which part of the partitioner are you and
how the interaction with Y2Storage works (listing, creating or deleting
partitions, LVs, etc.) at first sight. In one word - straightforward.

Now let's take a look to the CWM-based yast-partitioner[2]. Sure it does
more things and has the limitation of being forced to clone the
not-so-nice UI of the old partitioner. But even having that into
account, the level of complexity there is a little bit daunting. When
reading a piece of code, I never know where it fits in the overall
picture. Martin already suggested to create some kind of "map" for
newcomers with diagrams and links, which is a sign. And all that because:

1) CWM Widgets are way more than widgets

They take a lot of responsibility and are in full control of the event
loop. They manage user input, route the user between dialogs/widgets,
store the result in the domain classes (or YCP modules), trigger the
real changes in the system... In a MVC pattern (just as a well known
pattern, even if we don't follow it), a single widget will be the whole
V the whole C and a even a significant part of the M.

2) CWM is a dictator :-)

Maybe as a consequence of the point above, the usage of CWM impose a
concrete way of doing things for your YaST client.

They need extra workarounds to play together with other modern parts of
YaST that embrace OOP. For example, during the development of the
partitioner, somebody wanted to create a dialog just using our beloved
UI:Dialog class. To make it possible we ended up creating a CWM widget
that represents a dialog, so the dialog is contained in the widgets
system (and not the other way around) and then it can play by the CWM
rules and be used.

I also have the impression that the CWM model encourages too much the
usage of a Singleton approach in the "models layer". Something that made
a lot of sense for YCP modules (that are singleton by definition), but I
don't like that much with OOP. But this can, of course, be just a
subjective impression.

3) Reusability can be easier than that

We already have examples of reusable "widgets" that don't embrace the
CWM model in YaST. Like the widget to stop/start/enable/disable
services, the recent presenter to show a list of actions in the
devicegraph with the ability to collapse/extend some parts or even some
parts of the mentioned expert partitioner prototype.

They are usually quite simple and straightforward. A initializer to set
the initial state or to pass the object(s) they "wrap", a handler for
the user input, a method returning the current tree of UI terms... and
that's usually it. They are compatible with any possible approach used
in the UI, not imposing a given paradigm. They can be used inside a
CWM-style dialog, inside a UI:Dialog, directly in a proposal client,
etc. because the don't over-do.

4) Relatively complex mechanism even for simple stuff

I have mixing feelings about this point. On the one hand, I kind of like
the CWM approach of using classes for everything. On the other hand,
sometimes it feels overkill for many cases to define a new class and
then instantiate a new object for very simple tasks like adding a
button. That's specially true for stuff that you don't really want to be
reusable, but that you want to fit in the whole picture of classes and
subclasses. In general, adding a button or a label is usually not as
easy as... well, adding a button or a label. :-)

Pheew! Feel much better now. ;) Deactivating rant mode.


[2] (many things are still not
merged in master at the time of writing)
Ancor González Sosa
YaST Team at SUSE Linux GmbH

To unsubscribe, e-mail: yast-devel+unsubscribe@xxxxxxxxxxxx
To contact the owner, e-mail: yast-devel+owner@xxxxxxxxxxxx

< Previous Next >