Faster prototypes with Just Objects Prototype

If you are like me, you need to create prototypes to see new business functionality or algorithms in action. That way we can interactively test and demonstrate a solution to customers and coworkers. The downside of many prototypes is that because they look ugly and are not easily presentable, much time can be spent to overcome those shortcomings. The problem with spending much time on making a prototype look nice is that it slows you down and prevents you from doing more meaningful work instead.
I quite often fell into this trap. I used to spend too much time working on the user interface and other rather unimportant parts of a prototype. And all of that just to make a good impression showing it off. Then I had to ask myself: How can we accelerate this? How can we prototype faster, with less ceremony and get a good enough looking functional user interface automatically?
A basic search led me towards the Naked Objects Framework which seemed like a good idea. When I wanted to test it out though, it appeared to be very complicated. I needed a much simpler, straight forward, conventions based tool. So I decided to create one myself. Behold, this is Just Objects Prototype (JOP).

Installation via NuGet is very easy. Just create a new Console Application and run “Install-Package JOP” from the package manager console. JOP uses conventions to help you focus on the logic you want to prototype. To get started, adjust your Main method to look like below.

[STAThread]
static void Main(string[] args)
{
    JustObjectsPrototype.Show.With(new object[0]);
}

When you run this code, it displays the JOP shell with nothing (no objects) in it, just like in the screenshot below.

1

As you can see, there are four parts in that window. Top most is the ribbon. It lets you create and delete object instances as well as invoke custom functionality. The left part shows a list of all the different Types, this JOP prototype knows about. If one of those Types is selected, it shows all the object instances of that Type in the top list and ribbon buttons for its static methods. When one of those object instances is selected, it shows all its properties in the bottom view and ribbon buttons for its instance methods.

Example

Lets look at an example. In this prototype I want to show a simple workflow: Suing Persons. JOP wants you to not think of anything but your object model. That is your data structures and its logic. So if we focus only on what we would need to sue persons, we may come up with persons, addresses and dossiers. And this is how that could look like in C#.

class Person
{
    public string Forename { get; set; }
    public string Surname { get; set; }
    public List<string> Nicknames { get; set; }
    public List<Address> Addresses { get; set; }
    public Dossier Sue(string why)
    {
        return new Dossier { MandateMatter = why, Culprit = this }; 
    }
    public override string ToString()
    {
        return Forename + " " + Surname 
            + (Nicknames != null && Nicknames.Any() ? " (" + string.Join(", ", Nicknames) + ")" : "");
    }
} 

class Address
{
    public string AddressText { get; set; }
}

class Dossier
{
    public bool Finalized { get; private set; }
    public string Reference { get; set; }
    public string MandateMatter { get; set; }
    public Person Culprit { get; set; }
    public void Finalize()
    {
        Finalized = !Finalized;
    }
}

These are just plain old CLR objects. Lets start the prototype with a few test instances.

var objects = new List<object>
{
    new Person { Forename = "Manuel", Surname = "Naujoks" },
    new Address { AddressText = "at home" },
    new Address { AddressText = "at work" },
    new Address { AddressText = "somewhere else" },
};
JustObjectsPrototype.Show.With(objects);

As you can see, the prototype is started with a list of objects. If we had used an Array, no new object instances could have been created since JOP tries to modify that list to keep it in sync with its internal object pool.

2

And know we see our objects in action. We can modify their properties by inserting values or reference other objects from this prototypes’ object pool. We can also invoke their methods with the ribbon buttons. When the user presses the Sue button, for example, a dialog pops up to prompt for the Sue methods’ parameters. You see that dialog in the screenshot below. Notice that we see a second ribbon button for ToString. We override the ToString method so that JOP can show a readable text when displaying a person reference in a different objects’ properties view. As far as JOP is concerned, ToString could theoretically change the objects’ state and therefore lists it as well.

3

The Sue method returns a new Dossier object. After the selected “person has been sued, the newly created dossier is available” under the Dossier type.

4

The “dossier can now be finalized” which changes the Finalized property. That property is private in code and therefore read-only on the view.

Special functionality

There are many more things JOP can do. For example mass object creation and deletion with static methods. To create many new Person object instances at once, we can introduce a dedicated method that just returns the newly created instances. To delete all Person object instances, we can introduce another method that takes an ObservableCollection as a parameter. That ObservableCollection contains all the instances of the specified type that this prototype knows of and synchronizes changes to it with the prototypes’ object pool.

public static List<Person> Create_many_persons(int how_many)
{
    return Enumerable.Range(0, how_many)
        .Select(i => new Person { Surname = "Name " + i, })
        .ToList();
}
public static void Delete_all_persons(ObservableCollection<Person> allPersons)
{
    allPersons.Clear();
}

We can allow or prohibit creation and deletion of object instances with the new and delete button by specifying a UI.Settings object when starting the prototype like below.

JustObjectsPrototype.Show.With(objects, JustObjectsPrototype.UI.Settings.New(s =>
{
    s.AllowNew[typeof(Address)] = false;
    s.AllowDelete[typeof(Address)] = false;
    s.AllowDelete[typeof(Person)] = false;
}));

Conclusion

There are many things JOP can do. In this little tutorial I showed how easy it is to develop just your object model and have JOP render a view around it. There are only a few things that require knowledge of the framework, like deletion of object instances. Even though you can create comprehensive applications with JOP, keep in mind that it is primarily focused on creating prototypes. It is very opinionated and not extensible, but it will enable you to build much better prototypes much faster.

If you like my prototyping solution, check out the Just Objects Prototype GitHub repository and feel free to suggest improvements or ask my anything on twitter at @halllo.

Advertisements

Better WPF DataBinding with CalcBinding

If you are like me, you want to bind Boolean properties to Visibility properties. We implement IValueConverter and therefore increase the complexity in the system. The new Type has to be named and placed correctly and we have to make sure that there is no value converter that already does what we just created. How can we speed up and improve binding and value conversion?

Recently I came across the very sweet WPF library CalcBinding. It allows for custom binding expressions without the need for an IValueConverter implementation. It is a markup extension that lets us write inversions and calculations directly in XAML. Those binding expressions also support two way binding automatically. That prevents the ViewModel from getting all kinds of highly View-related properties, which can obfuscate the abstract view model. Just like the CodeBehinds did in preMVVM age.
In this blog post I give you a quick run through of all the features I find most impressive. You can easily install it with “Install-Package CalcBinding”. Once you import its namespace in the XAML you can take advantage of the new binding like below.

1

The screenshot above shows a multi binding together with arithmetic expressions to produce a single result. The screenshot below shows additional calculations that can be used inside the binding expression. Remarkably, you get the back conversion for free. Not all calculations belong to the View. Keep in mind that calculations in the view can not easily be unit tested.

2

The screenshot below shows how to bind a Boolean to Visibility. Visibility is a Type that lives in View-land and I do not want view-specific Types to be dependencies of my ViewModels. I believe the ViewModel should be as pure as possible. This way I can easily reuse them to support not only WPF views in a MvvmCross solution, for example. Unfortunately MvvmCross has its own framework specific Types like MvxCommand.

3

The screenshot below shows how to use the ternary operator (?:) within the binding expression to concatenate strings. This could be useful if the binding’s StringFormat is not enough.

4

There is one more thing I would like CalcBinding to do. If you already looked into AngularJS or compiled data binding in the Universal Windows Platform, you may like how they support binding to events. Would it not be great if we could do the same in WPF? Exactly. And here is how, utilizing the CalcBinding markup extension. Unfortunately, even though I created a pull request, this is not yet included/supported in the official version of CalcBinding.

5

CalcBinding is amazing. Especially when binding bool properties, it is a huge time saver. And on the side it keeps my ViewModels much cleaner and prevents them from turning into huge CodeBehinds. The only disadvantage I found is that while Visual Studio seems to accept the extensive binding expressions, ReSharper lists them as errors in its solution wide error analysis view. Maybe we can teach it to ignore those. For now, it has a very positive cost-benefit profile and I am going to continue using it. If you like it as well, give credit to Alex141 and star his github project at the link above.

Neuste Werkzeuge und Probleme

Kürzlich hatten wir in unserem Entwicklungsteam Schwierigkeiten nachdem einige Teammitglieder von ReSharper 9 auf ReSharper 10 aktualisiert haben. Es hat sich am Ende herausgestellt, dass die Werkzeuge gar nicht schuld waren. Dennoch hat dieser Zwischenfall eine Diskussion über die Team-interne Verwendung von Werkzeugen ausgelöst. Dabei wurde den Aktualisierten vorgeschlagen von der neuen Version wieder auf die alte zurückzugehen. Plötzlich stand das Installieren der neusten Versionen zur Debatte und es wurde von “der Team-Version” gesprochen. Das Thema haben wir auch in unserer Retrospektive diskutiert und hier wurde dann sogar von Installations-Veto und Installations-Verbot von den Softwarearchitekten gesprochen. Hiermit möchte ich meinen Standpunkt nocheinmal schriftlich klarstellen.

Es handelt sich bei diesem Thema eigentlich um zwei Themen. Das erste betrifft Probleme, die bei der Verwendung von Werkzeugen auftreten. Das zweite betrifft den Umgang mit neuen Versionen an sich. Wenn wir beides vermischen kommen wir zu vermeintlichen Lösungen die gar keine sind.

1. Thema: Tool-Probleme

Was sollten wir tun, wenn wir Probleme mit einem Werkzeug haben? Für mich ist die Antwort eindeutig: Beheben und zwar so schnell wie möglich! Ein Versions-Downgrade kann meiner Meinung nach nur das letzte Mittel sein. Wer ist dafür verantwortlich? Meiner Meinung nach die, die das problematische Werkzeug einsetzen. Und wenn das unbedingt eine bestimmte Person sein muss, dann bitte der CTO. In unserer Abteilung sehen sich die Architekten verantwortlich für den Einsatz von Entwicklungstools. Meiner Meinung nach ist das Schwachsinn. Entwicklungstools haben mit Softwarearchitektur nichts zu tun. Ich befürchte sogar, dass wir unsere Architekten mit Problemen, Fragen und Diskussionen rund um die Tools von den tatsächlichen und wichtigeren Aufgaben bezüglich der Softwarearchitektur abhalten und ablenken. Laut Wikipedia geht es bei Softwarearchitektur um

eine strukturierte oder hierarchische Anordnung der Systemkomponenten sowie Beschreibung ihrer Beziehungen

oder ähnlich

Strukturen eines Softwaresystems: Softwareteile, die Beziehungen zwischen diesen und die Eigenschaften der Softwareteile und ihrer Beziehungen.

Architekten kümmern sich nicht um die Werkzeuge der Bauarbeiter, das machen die Bauarbeiter selber.

2. Thema: Neue Versionen

Ich glaube unsere Architekten beschäftigen sich nur deswegen so viel mit Werkzeugen, weil es sonst keiner macht und sie es gerne kontrollieren wollen. Aber allein die Idee, vorzugeben welche Werkzeuge zu verwenden sind und welche nicht, finde ich höchst fragwürdig. Meiner Meinung nach widerspricht das der Selbstorganisation, dem elften Prinzip des agilen Manifests:

The best architectures, requirements, and designs emerge from self-organizing teams.

Ich meine damit nicht, welches Versionsverwaltungssystem das Team einsetzt oder welche Framework-Version der Buildserver nutzt. Diese Punkte sehe ich tatsächlich im Entscheidungsbereich der Team-übergreifenden Einheiten und den Kundenanforderungen. Aber die Version von Visual Studio und ReSharper sehe ich im Entscheidungsbereich der Teammitglieder. Schließlich kennen die ihre Werkzeuge und Konsequenzen am Besten. Das Argument für eine homogene Versionslandschaft ist Code-Kompatibilität und Pair-Programming-Vereinfachung. Beides kann ich gut verstehen und beides ist in der Realität auch mit heterogener Versionslandschaft kein Problem. Zusätzlich haben wir ja mit Versionskontrolle und CI ausreichende Sicherheitsmechanismen um selbst theoretischste Probleme auf diesem Gebiet zu verhindern.

Aber ist es sinnvoll das ein Teammitglied Visual Studio 2012 und ein anderes Visual Studio 2015 nutzt? Nein. Wo ist das Problem? Das Problem sehe ich in der alten Version. Meiner Meinung nach hat das Team ein doppeltes Ziel. Zum Einen sollten alle im Team die gleiche Version einsetzen und zum Anderen sollten alle die neuste Version einsetzen. Zu jeder Zeit? Nein, statt immediate consistency lieber eventual consistency. Es stellt sich also die Frage nach dem Zeitpunkt der Umstellung. Ich würde sagen, early adopters sofort um die neue Version im praktischen Einsatz zu evaluieren. Wenn es Probleme gibt sollten diese behoben werden (siehe Thema 1) und zwar von den early adopters. Dann sollte das restliche Team maximal zwei Sprints später ebenfalls umsteigen. Um das zu ermöglichen sollte die Verfügbarkeit einer neuen Version von den early adopters angesprochen und das Team damit über den Begin einer Evaluierungsphase informiert werden.

Warum stellen wir überhaupt um? Es geht dabei um Verbesserung und Innovation. Unter dem Strich ist die neue Version besser. Ansonst hätte es sie ja nicht geben müssen. Die neuen Versionen haben weniger Fehler und neue Features. Wenn man sich nicht mit den neusten Tools beschäftigt, kann man auch nicht wissen, wie diese das Arbeiten erleichtern und sogar beschleunigen. Zum Beispiel bietet Visual Studio 2015 mit dem Visual Live Tree und Delegates im Debug-Window zwei Funktionen auf die ich nicht mehr verzichten möchte. Und ReSharper 10 enthält Postfix Templates out of the box. Außerdem, wenn man immer am Ball bleibt ist es auch einfacher auf eine noch neuere Version umzusteigen, die besonders außergewöhnliche Features bietet. Das ist wie beim Mergen von Branches. Je länger man wartet, desto weiter laufen die Pfade auseinander und desto schwieriger ist es, diese wieder zu vereinen.

Es ist wichtig, dass wir hier alle am selben Strang ziehen und zwar nach vorne.