Reto Fuerte y Duro

En estos días se me ha ido mucho la olla al ver cómo a diario se me presentan situaciones que, si fuera un kootre, resolvería rápida y fácilmente.

Me pregunto si no hay una manera mucho mejor y más sencilla de hacerlo.

Básicamente lo que quiero hacer un es diseñador de FlowDocuments con algo parecido a los Bindings pero sin ser un FlowDocument. Me explico: Si cogemos un FlowDocument y le metemos cosas, vamos a tener eso, un FlowDocument.

Lo que quiero es un modelo más abstracto que no esté atado a WPF. Hacer lo que hace WPF sin WPF es un jodido caos.

Ejemplo. Tenemos un documento vacío y queremos añadir un párrafo. Haciéndolo desde el código es más sencillo que el mear. Pongo un FlowDocument y le meto un Paragraph.

¡Pero no queremos eso! Caca.

Queremos representar nuestro modelo de negocio, que en este caso son elementos que se representará gráficamente. O sea, el modelo es la propia UI, o algo que se le parece mucho. En realidad se trataría de un modelo que casi se confundiría con las clases de WPF. El tema está en que sea, además, diseñable.

¿Qué me decís?

¿Es un temita, eh? Pues tengo unas ganas locas de saber cómo podría abordarse con altas probabilidades de éxito. El mundo de los diseñadores es bastante jodido y prueba de ello es que algunos de los más grandes programadores se dedican a ello, como Unni Ravindranathan o Harikrishna Menon.

Bueno, ahí lo dejo, por si algún ávido Master se digna a proponer soluciones.

¡Talueg!

¿Objetos dinámicos en una DataGrid?

¿Qué broma es esta? ¡Enlazar una lista de elementos con un número indeterminado de propiedades es un fucking inferno!

Pero por otra parte, nadie dijo que representar cosas con un número variable de propiedades fuese a representarse fácilmente. Más bien es todo un reto.

Estoy investigando cómo hacerlo y parece ser que hay gente que lo ha conseguido haciendo uso del DynamicObject de .NET 4.0. Al parecer hay que lidiar con algún problema morrocotudo, ya que el DataGrid con “AutoGenerateColumns” obtiene las propiedades mediante el Type no mediante cada instancia. Golpe bajo.

A ver cómo me las apaño, que me he puesto en contacto con algunos lobos de mar que controlan del tema, pero parece que casi se esconden bajo las setas.

¡Cada problema es un mundo, chavalis!

La insuficiencia de SCRUM

Un gran artículo que he encontrado y que merecer la pena leer.

http://billschofield.typepad.com/my_weblog/2009/08/the-insufficiency-of-scrum.html

Cuando una metodología teóricamente ágil se vuelve torpe. A veces, el desarrollo con SCRUM me recuerda al juego World Of Goo, cuando se construyen torres de unos seres gelatinosos llamados Goos.

Al principio todo es ágil, poniendo los muñequitos en las bases como locos, pensando más bien poco en si todo está bien colocado.

image

Cuando va cogiendo cierta altura, la torre empieza a menearse de un lado a otro. Poner cada Goo es cada vez más difícil. Hay que pensárselo dos veces para poner el siguiente.

image

El ritmo alocado decelera y la mayoría del tiempo se pasa intentando retocar la estructura para que la torre sea más estable.

image

Pero normalmente es demasiado tarde. El aire azota la torre de Goos y en algún momento, a veces sin tocar nada aparentemente, todo colapsa sobre la base y se viene abajo.

image

A tomar por saco.

How to avoid code duplication. Case 1.

As a Clean Code lover, I really hate duplicated code.

In his homonymous book, Robert C. Martin states

”duplication may be the root of all evil in software”

And I think he IS absolutely right.

You better keep your code away from clones… or they will come back to you in the shape of a muddy monster that, for sure, will eat you.

I personally came to a situation in which I find it difficult to avoid repeating myself. This is the case:

I have a method that makes some calculations in a 2D plane (for layout and runtime design). This method takes some lengths and some points and make the necessary modifications to a control in order to a 2D transform to it. Let’s see a real sample in C#:

  • This sample method is really random, but it demostrates the problem. Each version works with one dimension, vertical or horizontal. Essentially both methods do the same, and the structure is almost identical. How to simplify these 2 into ONE?

For horizontal values:

        public static Rect DoSomethingCoolHorizontal(Rect inputRect)
        {

            var multiplyHorzPositions = inputRect.Left * inputRect.Width;

            Rect p = new Rect();

            p.Left = multiplyHorzPositions;
            p.Top = inputRect.Top;

            p.Width = multiplyHorzPositions;
            p.Height = inputRect.Height;            

            return p;
        }

For vertical values:

        public static Rect DoSomethingCoolVertical(Rect inputRect)
        {
            var multiplyVerPositions = inputRect.Top * inputRect.Height;

            Rect p = new Rect();

            p.Left = inputRect.Left;
            p.Top = multiplyVerPositions;

            p.Width = inputRect.Width;
            p.Height = multiplyVerPositions;

            return p;
        }

You may notice those 2 methods are 95% the same. But each one calculates the values for each axis. Vertical and horizontal use different properties.

The duplication in these kind of methods, follow  this simple rule:  when in the first method it says “left”, in the second it says “top”. As expected, “width” is replaced by “height”. The same would have been applicable for x and y.

In the case above, the rest is exactly the same, except for the return, that reverses the order of the Point arguments). They are so repetitive that even a text search&replace would do the job in order to replicate the same calculations for the other axis.

To clarify the method, you have to take into account that the structs that carry the properties are Rectangles with 4 attributes, that actually are 2 (2 for each dimension).

I tried to keep it beautiful, but I failed miserably again and again. That’s why I asked myself to Uncle Bob. I hope he could shed a bit light on this.

EDIT

Attention: Robert Martin did his magic again! I asked him in Twitter and has been so considerate and kind that he rewrote the sample in Java with the duplication totally eliminated. He provided a link with the source code. Just see the comments section.

WOW.

The solution to this lies in making a method that swaps vertical / horizontal dimensions. The call to the Vertical derivative is the Horizontal one with 2 swaps (argument and result):

        public static Rect DoSomethingNonDuplicateVertical(Rect inputRect)
        {
            return DoSomethingCoolHorizontal(inputRect.Swap()).Swap();
        }

With the Swap method being:

        public Rect Swap()
        {
            return new Rect(Top, Left, Height, Width);
        }

The constructor of the Rect class is:

  public Rect(double left, double top, double width, double height)
        {
            Left = left;
            Top = top;
            Width = width;
            Height = height;
        }

Now IT REALLY DOES SOMETHING COOL.

Thanks, Uncle Bob. Great tip!

Después de todo, temporary failure!

http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/23072c67-b024-4e62-b587-0e494b1d438a

Ahí queda la razón de mi retraso: no tengo ni idea de cómo transformar la idea en un Custom Control con sus Items y SubItems.

Todo esto es para la barra de herramientas. Me kagun! Al final no lo hice con las propiedades adjuntas que publiqué ayer.

Pues no, esto no fue la solución. Pero sí que lo hice finalmente con un Behavior (son la pera).