Archive for the ‘software development’ Category

I’m a Redliner, are you?

Wednesday, November 21st, 2012

campaign-home-page

This week I kicked off a campaign to increase the awareness and use of Redline Smalltalk, and get some financial support as well. The financial support will enable me to focus full time at least for a short while on getting Redline Smalltalk to Version 1.0. Things have come a long way since this Fan Letter To Redline Smalltalk.

Of course I could not have done this without the help of some very nice individuals: Sean T Allen, Pat Maddox, Peter Michaux, Jeff Heon, Brandon Hays, Robert Roland and Andrew Kiellor.

Hopefully you will help me too. You should follow this link to support Redline Smalltalk. You can be a Redliner too!

Javascript MVC/Maria/Design …

Thursday, June 14th, 2012

Yesterday I gave a presentation at the Melbourne Javascript Users Group on my learnings doing MVC with Javascript, my recommended MVC Library Maria and a little on East Orientation. I enjoyed giving the presentation and if you want me to present to your group just contact me. Below are the slides from my presentation. Feel free to contact me with any questions.

melbjs-maria-east

Update:

Here is a fantastic blog post that details MVC and more importantly Maria - MVC done right - IMHO.

The Sound of Javascript: How to solve a problem with Maria …

Tuesday, May 15th, 2012

maria

Overview

Have you noticed the growing movement to developing thick clients on the browser? These thick clients move a complexity from the server to the browser while promising enhanced experiences tailored to the client device. A common theme with this movement is the use of Javascript, the Model View Controller (MVC) pattern and sending data between client and server, typically in JSON format.

This post is about developing just enough of an MVC based client on the browser to see how and where all the parts fit together, what design considerations might need to be taken into account and how the MVC pattern is applied. What is not implemented is the mechanism for communicating between the client and the server to remove a complexity that might otherwise obscure the client code. Client to server communications will be discussed without implementing code.

I’ll walk you through the code to exemplify the approach taken and how MVC comes into play. A goal is be to keep things minimal and clear in the hope you can use one or more of the techniques and tools outlined in your own projects. This post may even help you select alternative tools and frameworks.

* * The title of this blog is a play on the musical The Sound Of Music which contains the song “Maria“.

The Code

The code discussed in this post can be found here

Goal

My goal is to develop a small yet exemplary application and the canonical Todo application fits that bill quite nicely, with its simple data model and a user interface that needs little explanation. A Todo application can also be quite useful without server side functionality so conceptually its a whole application. The Todo Applications core model is essentially a list of entries outlining what is to be done, with each entry having a flag indicating if the entry has been completed and a description of what is to be done. To make the design and the use of MVC as clear as I can I have chosen to model the client side application as separate from the Todo model it manipulates. I find this helped me keep the separation of Client side and Server side clear and provide a more obvious ‘entry point’ for see where the Client Application begins and ends.

Tip - I strongly suggest that when Client Server data exchange is implemented that the data exchanged is not a direct mapping of the AppModel, rather it is an exchange of messages to manipulate each ’sides’ model indirectly. For example, when server data is processed it becomes a series of calls on the AppController rather than a direct replacement of the AppModel. A direct replacement or manipulation of the AppModel would be a tight coupling that would lead to possible change impact issues later.

MVC - Model View Controller

The Todo Client Application is embodied in the classes AppModel, AppView and AppController (see figure x), with the file src/js/initializer.js bringing them into existence when the browsers window load event is fired. The initializer.js code is the equivelant of a Java or ‘C’ programs ‘main’ function. Each class (AppModel, AppView & AppController) implements their part in the Model View Controller (MVC) pattern. There is a lot of material out there describing the MVC pattern in depth so I wont regurgitate it here, suffice to say I’m following the pattern as described by GOF and implemented in Smalltalk examples.

In a nutshell a View listens for events to happen on a HTML Element. When an event happens like the input field has changed the View is notified (by Maria). The View then extracts or builds whatever data is needed so it can communicate the event to the Controller by calling one of its methods. The Controller takes the notification and applies whatever Business logic it embodies (via other classes - don’t contain it within the controller) and calls a method on the associated Model to inform it of the change. The Model applies the appropriate changes to the model and then notifies all the observers of the model (via Maria) that the Model has changed. A View typically observes both a HTML Element and a Model meaning it will have a method called on it when either the HTML element or Model changes. When the HTML element changes the Controller is notified, when the Model changes the View is rendered. This is the circle of MVC life.

Looking at src/js/AppController.js you will notice little more than what is required to subclass the Maria Controller class and some may feel the controller is therefore unnecessary. Resist the urge to remove a Controller that is as simple as this because doing so removes a clear indication of where certain functionality belongs and tempts the lazy or uninformed developer to directly bind aspects of the Model to the View and that isn’t MVC. Not following MVC quickly couples and bridles the parts of an application with responsibilities that don’t belong, starting you on a road to despair.

Maria

To implement MVC I wanted to use a library that would implement MVC effectively yet not dictate an approach with lots of methods or classes that must be implemented, nor require a large library of dependent Javascript to be loaded. The Maria library developed by Peter Michaux and available here is such a library. Maria is thin and un-opinionated* making working with it simple and quick. At the time of writing this Maria is not well documented but I was lucky enough to have the support from Peter for my experiment. Maria is so straight forward that I rarely called on Peter to explain the library, instead we mostly discussed design issues like the progressive enhancement of existing HTML or the dynamic rendering of HTML by View objects, both of which Maria supports. Even if you don’t use Maria I suggest you have a look at the code behind it as an example of good Javascript.

* Maybe Maria is opinionated and I just happen to agree with the opinion.

Design Considerations

I chose to use a kind of progressive enhancement approach in the Todo Application, where the AppView attaches sub-views to HTML elements already present on the page when the AppView is created. This supported my working style where I created the HTML separately to writing and running my Javascript. With most applications there will come a time when a view cannot attach to an existing HTML element and will have to create elements at runtime. Consider this when making the choice of which style you want to use. Doing both helps make my Todo Application an example of both approaches.

Another design decision I made was to ensure dependencies are passed to a class instance when they’re are created. For me this helped make the dependencies more explicit and facilitated easier testing. However Javascript is such a flexible beast that inverting dependencies for testing isn’t strictly required as you can get at the innards of an object quite easily. I’d say that I probably inverted the dependencies more out of a personal style or ethic of not referring to global variables and not instantiating what could be passed in. Note that Maria follows the Smalltalk MVC implementation closely and will create a Controller for a view on demand (see maria getDefaultControllerConstructor) but I didn’t use this approach, and to Maria’s credit this didn’t cause any problems.

A design decision I have touched on already is embodied in AppModel, a Class that represents the data of the Client Application as a whole. The AppModel contains a reference to the set of Todos that are being manipulated. This set of Todos could be seen as the core model but a higher level abstraction helps here as the Model in MVC is typically manipulated through an assortment of views and sub-views created on the same Model. When this model is not the ‘parent’ you eventually end up with a Controller needing to track a parent and a child model, or a model that keeps a parent relationship unnecessarily. Typically the top level model will expose the behavior that manipulates sub-models making it ideal as a parent and ‘documenting’ the behavior of the Application, ie: addTodo().

The Application

My Todo Application is minimal in that it only captures items to be done and doesn’t currently allow you to mark an item as done. This is enough to illustrate the points I wanted to make in code and to use the Maria framework in a ‘real’ way.  The code for the Todo application is available in here (link) and what follows is a walk through of the code from the entry point through each class as it participates in the MVC pattern to enable the collection of Todos. It is hoped that following the code from the entry point down with a description of each line is the most appropriate way of describing what is going on and how the parts of the application come to interact with each other.

maria-files

Running The Application

To run the Todo Application you need to make the todo-maria.js file by issuing the “make” command in the root folder. This results in a todo-maria.js file being created in a ‘build’ sub-folder. When this is done you can open the index.html file with your browser and you should see the Todo Application. Should you run into problems please check the README file in the distribution.

src/js/initializer.js

maria-initializer

This file is packaged into the todo-maria.js file by the ‘Makefile’ where the initializer code is run as the full todo-maria.js is interpreted. The code in this initializer
creates the root triad of AppModel, AppView and AppController with their dependencies when the browser window has loaded. Since the AppView requires an existing HTML document there is no need to create the view before the document is ready. The initializer fragment of code uses the Maria event listener API to register our function to be called when the window loads. The initializer tests if the global ‘window’ object is defined before continuing because in my test scenarios the ‘window’ object is not present. There is probably a nicer approach than this but I have not looked into it.

src/js/AppView.js

maria-appview

The AppView is the main view of the application but it doesn’t attach itself to any HTML element, instead it binds other views to HTML elements using the DocumentToViewBinder class. The AppView requests the DocumentToViewBinder to bind the HTML elements ‘entry’ and ‘list’ to the associated View and Controllers, with each sharing the same AppModel. You can think of the AppView as an Abstract View. You should note that the AppView is an observer of the AppModel and when the AppModel is changed the update() method is called on the AppView. This update() method doesn’t perform any action as the sub-views themselves perform these actions as they are also observers of the AppModel.

src/js/AppModel.js

maria-appmodel

The AppModel class represents the data model for the whole application and is composed of a set to contain the Todo’s. The ‘Set’ class is provided by Maria and it has some neat Collection methods making working with a collection more natural than when working with an array. When additional data is required for the application it would be added to the AppModel. When a Controller needs to manipulate data it calls a method on the AppModel to ask it to do the work. At the time of writing this the AppModel exposes the Todo set with a method and this is wrong, wrong, wrong. The AppModel should instead allow a function to be applied to each element of the Todo Set, keeping the implementation private and using the Tell Don’t Ask principle. I’ll be changing this as a priority.

src/js/AppController.js

maria-appcontroller

The AppController coordinates requests from the View to update the model. Looking at the code right now you can see that the AppController does nothing more than subclass the Maria Controller and remember the associated Model. Not all the controllers in the Todo Application are this trivial but resist the urge to remove the ones that are. Controllers that do nothing provide two things, a place to add functionality when needed and a clear indication that the associated View doesn’t make requests to modify the associated model. A Controller is the ideal place to expose the behaviour needed to update the model, typically taking the notification from the View and then packaging that up in a new object before calling a method on the model. This flow is shown in the InputController which I’ll detail below.

src/js/DocumentToViewBinder.js

The DocumentToViewBinder is a Factory for finding a HTML element from the DOM and creating an associated View and Controller. It is the element map passed to the DocumentToViewBinder that defines which Views are bound to which HTML elements, and these views will typically register to be notified when certain events are fired by the elements they are bound to. See InputView as an example of this. Technically the DocumentToViewBinder should be constructed with another class that handles the finding of the HTML element to be bind, as mixing this responsibility into the DocumentToViewBinder class violates the Single Responsibility Principle. I’ll add this as a TODO for me.

src/js/namespace.js

The namespace.js file ensures that a todo object exists into which all the todo application components can be bound. Using a namespace reduces the probability that class names and function names will collide with already defined classes and functions.

src/js/InputView.js

maria-inputview

The InputView class listens for events on the associated HTML text input field, and for notifications of the AppModel being updated. Maria will call the ‘initialize’ method on a View to give it the opportunity to register for the events on the HTML element that is it interested in. In this case the InputView is interested in the ‘change’ event on the HTML element and when that event occurs it wants the ‘inputChanged’ method called on the InputView. When the ‘inputChanged’ method is called the View extracts the contents of the HTML text input field and tells the associated InputController that the view changed passing the input text along. The InputView also provides an ‘update’ method which is called (by Maria) when the AppModel has been updated. In this case the InputView does nothing with this notification and I could remove this method as Maria provides a no-operation implementation, however I left it defined as an explicit extension point for people less familiar with Maria or myself at a future date.

src/js/InputController.js

maria-inputcontroller

The InputController provides a method to be called when input has been given via the InputView. When input is received it is packaged up into a simple object and the method for adding todo entries is called on the AppModel. The View is also asked to clear its input ready for the next input.

src/js/ListView.js

maria-listview

The ListView class is slightly different to the InputView in that it doesn’t listen for event on any HTML elements, instead it listens only for notifications that the
AppModel has changed. When the AppModel has changed the ListView clears the associated HTML unordered list and adds each of the items in the Todo set as items in the unordered list.

Testing

I used the BusterJS framework for testing for two main reasons, firstly it provides behavior style testing that I am used to from my use of Ruby and RSpec, and secondly because it was being used by Maria for it’s testing. I found BusterJS to be fast and effective and its ability to automatically test on different browsers is very attractive.

At times I found that my tests would fail but running them two more times and they would pass. I have not looked into this and would not use BusterJS in a Continuous Integration environment until I could find out why this is happening.

You should note that some of the tests are not up to my usual standard as they don’t check all arguments passed to methods when they check a method call. This means it is possible to forget a parameter and tests continue to pass. I let the tests get this way as I was new to BusterJS and the underlying SinonJS library. I’ll be tightening up the tests.

Conclusions

Writing my Todo Application as a browser based client was a worth while experience and it helped me get a grasp on what it means to develop this style of application. Some important things I learned were:

  1. Follow MVC and always have a Controller even if it does nothing. Don’t communicate directly from View to Model, or Model to View. The MVC circle of life is all about being called back in response to events on objects being observed.
  2. Create a top level Model composed of other models to conceptualize the Client as a whole. I went so far as to have a top level Controller and View which helped.
  3. Use Maria or another MVC framework that is light and unobtrusive. I recommend you start with Maria even if you plan on moving onto more opinionated frameworks as it will provide a grounded understanding of MVC principles.

Your feedback is welcomed.

RASMATAZ: a safer assembler …

Saturday, November 12th, 2011

 pipes

I like Assembly language. Assembly is clean and simple and fast, although verbose. I like Ruby’s interactive command line (IRB). Ruby’s interactive command line is quick to start and easy to use to test snippets of code. So what about having both of these, that is RASMATAZ, an Assembler written in Ruby that you can interact with via IRB or just execute from the command line. The biggest win is not having to re-start you machine when the instructions go off and give the operating system conniptions.

This is an example of the assembly you can execute with RASMATAZ:

mov rax, [rdx]
label :spin
push rax
pop rcx
dec rcx
jnz :spin

The assembly loosely follows the Intel syntax and you can see the full instructions and add your own in the file ‘machine.rb’.

You can interact with RASMATAZ using IRB by starting IRB and issuing a load to load your program, for example:

> load 'example.rasm', nil

For here you can interact with your program using one of the following commands:

  • registers
    dumps the current values of the registers, for example
    >registers
    => {:rax=>0, :rbx=>0, :rcx=>0, :rdx=>0, :rsi=>0, :rdi=>0, :rbp=>0, :rip=>0, :rsp=>0}
  • stack
    dumps the current value on the stack, for example
    => []
  • memory
    dumps the current values in memory, for example
    => [#<RASMATAZ::Instruction:0×00000002924af8 @pointer=0, @mnemonic=:label, @arg1=:start>, …
  • step
    steps forward by executing a single instruction. For example
    #<RASMATAZ::Instruction:0×00000001c97308 @pointer=0, @mnemonic=:label, @arg1=:start>
    => 1
  • go
    executes from current instruction until the program ends.

RASMATAZ is written entirely in Ruby with the assembly instructions being a DSL, the machine, stack, memory and registers are all Ruby objects. The DSL is defined in the file rasmataz/dsl.rb and the instructions and the virtual machine they execute against are defined in the file rasmataz/machine.rb.

RASMATAZ is an experiment of mine to see how far I could go with an assembler with out of the box Ruby. It is at the proof of concept stage but available to anyone to fork and continue if they wanted to. I’ll be coming back to RASMATAZ at a future point to develop of prototype for a new type of virtual machine that is not based around executing instructions like traditional virtual machines.

The source for RASMATAZ is here on github.

A Goal Pyramid: Helping make decisions …

Sunday, October 30th, 2011

goalpyramid

When a Team starts on a piece of work they implicitly know the goal is to get the job done as efficiently as possible. There are probably other goals that are not verbalised and therefore not implicitly in the minds of the Team and this is a big problem, big enough to destroy the Team and significantly hamper getting the job done. A shared understanding of the goals of the Team helps focus decisions as each decision can be related to how it helps accomplish the goals. Without established goals decisions making can break down into a battle of wills which is extremely costly in multiple ways (this is covered in the book ‘Getting to Yes’ which I blogged about here. The goals of the Team are not just the Company goals they are also Team members personal goals like ‘I want to learn technology X’ or ‘I think the design should be Y’. These personal goals are rarely explicit bubbling along just below the surface with a building current that can derail a project.

Explicit and honest goals can help a Team focus and make decisions quickly and in a manner that feels more cohesive and transparent rather than driven by the loudest person, biggest personality or <insert sterotype here>. What follows is a proposed technique for making the goals of the Team explicit and prioritised to enable a Team to move forward efficiently with a transparent mechanism for making decisions quickly, reducing personal conflict and focusing the Team on getting the job done. After all, getting the job done is always the number one goal.

A Goal Pyramid is a hierarchy of ten (10) Goals starting with one at the top, two on the next row, three on the next and so on to form a Pyramid. It is suggested that the Goal Pyramid be kept to ten (10) goals. The first and highest priority goal is the core Business goal, “to get the job done as efficiently as possible”. If this isn’t the Goal at your Company then you should change the first and highest priority goal to that. This top goal is not a negotiable goal like the rest that make up the pyramid. To find and fill out the other goals you need the team to list all the goals they can think of and then prioritize them into the top nine (9). These top nine (9) goals will make up the rest of the pyramid from left to right, top to bottom starting on row two. The goals on row two have a higher importance than those on row three etc. A pyramid is used rather than a list or another shape as it allows the number one (1) goal to be clear while allowing the remaining goals to share in importance on each row, and have priority over those on lower rows.

The list of goals to prioritize should be succinct and clear to each team member so they know what they will be voting for to form their top nine (9). Each goal should have a title, a description and a “because when we don’t …” section which lists the impact/remifications of not focusing on the goal back to the number one (1) goal. For example, “Goal: Clean Code. Description: We should follow the principles set out in the book Clean Code. Because: When we don’t the code base becomes harder to work with slowing our ability to ‘<number 1 goal here>’”. In arranging your pyramid graphically I suggest putting the ‘Goal:’ in the Pyramid and having a legend under it to elaborate on the ‘Goal:’. However, nothing should stop you from having all this information in each pyramid segment if you wish.

A difficulty and thing to watch out for in forming the pyramid is getting the team members to be open, honest and transparent in why the goal matters. For example, a goal of “Keep Simple” looks fine until you dig deeper and draw out the fear behind this goal which might be a fear of meeting the deadline or a fear of a design that is not fully understood. ie: I want to keep the design simple because I don’t understand your proposed design. This particular example draws out a different issue, that of information sharing / knowledge transfer to understand a design more. This is an intended side effect of forming the Goal Pyramid. Encourage your team to think hard about the goals and to be as honest and fearless in presenting them to be voted upon. Wanting to use a particular tool or approach is a fine goal and it needs to be related back to the number one goal, made known and prioritised with the team. Letting the who team in on a goal means we can all work together towards multiple goals. A win-win situation.

    • Goal: Simple Goal statement
    • Description: A longer more informative description of the goal.
    • Because:  A set of reasons for the goal.

Once your Goal Pyramid is formed you can refer to it in situations where a decision is required, helping focus the discussions on the goals and to break deadlocks which can occur when Team members are in a battle of wills. A systematic analysis of how a path of action effects reaching the number one Team Goal will usually be resolved quicker than battle of wills and assist in preserving ego. For example, lets say a Team member wants to use a new and exciting piece of technology and a goal in the pyramid is “Goal: No risk. Description: Don’t take unnecessary risks. Because: When we take risks where a tried and proven path exists we jeopardize our ability to ‘<number 1 goal here>’, we can say no in a non-personal and professional manner by pointing out this ‘agreed’ team goal. Note, we don’t have to say no, we can say yes in a way that meets our goals. For example, in the same case above we might ask the team member for a plan or strategy for mitigating the risks, or offer our own like “why don’t you make a branch and work on this after hours or weekends to prove it out, taking the risk away from the team?”.

I have not yet tried a Goal Pyramid, and I plan to do so as soon as I can. I formulated it because I see a use for it in solving problems I have experienced in my career. One thing I have learnt in many years is that there are rarely if any technical problems that hamper a team delivering, rather people problems have been the root cause. I hope to use a Goal Pyramid as a tool to facilitate getting through some of these people challenges. Should you make or use a Goal Pyramid then please let me know as I would like to provide feedback here on success or failure of this approach. I will do the same.

Edit: This link was emailed to me and I think it is relevant to this post: http://blog.8thlight.com/brian-pratt/2011/10/25/simplicity-of-teamwork.html

Tips for iOS development …

Friday, October 14th, 2011

logo

Monday mornings at work there is a buzz about the weekend, especially the outcome of sporting events. Someone is usually strutting around on a high because their team won, or ribbing someone because their team lost. This social interaction is what PlayUp have captured in their flag ship application PlayUp Live, along with live scores, fixtures and more. You should click this link now and check it out.

The journey over the last six months to get the iOS version out (support for other mobile platforms is coming) has been quite a challenge and this post is about those challenges and key take-outs you wont want to miss if you are developing an iOS app that connects to a back end. PlayUp is really exciting and it will grow to be as big as a Twitter or a Facebook, so Im expecting a few more challenges and growing pains and it will be worth it. While this isn’t a job advertisement feel free to contact me if you think this sort of challenge is for you (james dot ladd at iplayup.com).

These are my personal top #5 take-outs from working on the project

#1 Small Team

The number one #1 learning from working on the project is to keep the team small, with two people on the UI and two people the backend integration with the server. The server side is not factored into this count as this is quite variable, however the typical code base size for an iPhone app suggests 4 - 6 developers maximum.

#2 Shared Vision

The team should share a consistent vision of the product they are building. Multiple competing visions or changes in the vision can derail the project significantly. There is a reasonably common held belief that a key person leaving a project can kill it, and this is even more so if that person is the vision holder. A vision holder who is strongly focused and driven to reach that vision with good communication skills is a must.

#3 One Application

The back end of an iPhone application is as important as the front-end, and involving both teams in understanding the requirements of the other is essential. Both parts are crucial to the overall success of the product and directly effect the schedule and outcomes. A shared design and understanding of the architecture is key.

#4 Fast Feedback

The cycle time on building a feature and showing the relevant stakeholders effects the schedule and this loop should be as small as humanly possible. Getting the app onto the stakeholders device is nice and in some cases essential but it takes longer. Getting the stakeholders to be ok with a ‘first-draft’ that isn’t pixel perfect is another way to reduce cycle time to get feedback quickly, so is not writing tests for this ‘first-draft’. However, there are some cases where writing tests in the ‘first-draft’ will allow you to make changes faster later on. You know your app and will have to decide on your own balance.

#5 Libraries

Depending on your application you may need to use off the shelf libraries, and these libraries need to be thoroughly evaluated. Take the time to do this because in the heat of battle is probably not the best time to find out it was not the most robust choice.

East example code …

Wednesday, August 10th, 2011

People still ask me about East Oriented code. I hope what follows helps shed some light on the topic of East and immutable objects and how they play nicely with each other. Attached are some files (I hope I can attach them) in Ruby which implements a contrived example.

In my example I have a Customer object which can be initialised with values and after which these values can not be changed = immutable. To print the Customer you send the printOn message passing in the ‘thing’ you want the customer printed on to.

Customer forms a customer writer ‘contract’ between itself and classes that implement the customer writer contract. This contract enables the customer to print onto any object that supports the ‘contract’ - essential any object that responds to the messages the Customer sends from printOn.

To help with the example I have two objects that implement the ‘contract’, CustomerConsoleWriter and CustomerJsonWriter.

The magic is that the Customer doesn’t need to change when you introduce new writers, be they a CustomerDatabaseWriter or  a CustomerHtmlWidgetWriter etc.

You can further extend this magic by having writers that know how to delegate to other writers - for example you could construct a CustomerFileWriter with a CustomerHtmlWidgetWriter to write a Html representation of the Customer to a file.

I have left this combinatory magic to you.

Here is a run using the interractive ruby shell (IRB) showing this magic in action (I have removed output that isnt relevant)

:001 > $:.unshift File.dirname(__FILE__)
:002 > require ‘customer’
:004 > require ‘customer_writer’
:005 > require ‘customer_console_writer’
:006 > require ‘customer_json_writer’
:007 > c = Customer.new(’Ronny’, ‘H’, 33)
 => #<Customer:0×2a7de90 @name=”Ronny”, @surname=”H”, @age=33>
:008 > w1 = CustomerConsoleWriter.new
 => #<CustomerConsoleWriter:0×2a74318>
:009 > w2 = CustomerJsonWriter.new
 => #<CustomerJsonWriter:0×2a33db8>
:010 > c.printOn(w1)
Name: Ronny
Surname: H
Age: 33
 => nil
:011 > c.printOn(w2)
{”Name”=>”Ronny”, “Surname”=>”H”, “Age”=>33}
 => nil

*end* I cut out some of the Ruby IRB text.

So now you see an immutable object go East and provide a mechanism that allows a loose coupling and unlimited possibilities for printing Customers - e: limited by whatever classes you supply.

The internals of the Customer object can change without effecting the contract. Other contracts could be created - like a translation contract or a storage contract (see below).

For testing you can use a Mock with expectations on it to test that a Customer is conforming to the Customer Writer contract and you don’t need any existing writers. Likewise you can test CustomerWriters without having any valid Customer objects.

What objects need the data from Customer - all those that implement the CustomerWriter contract.

What about storing ?  I suggest a storeOn method in Customer that send store message. eg: storeName
The difference would be what the Writers do with that message. Like writing the binary rather than string representation. Id probably separate classes that respond to storeOn from those that understood printOn.

With the dynamics of languages like Ruby or Smalltalk you can make the writers even more magic. Consider the Customers age being a class Age rather than a number - When passed to the writer with printAge() the writer could then send it as_date() and now both a Date and an Age object can be printed. This is more about making writers smarter than East and immutability.

Imagine if you took the approach of using a dynamic factory approach to the writers whereby the Customer could use a factory to lookup the writer given the thing you are writing to - for example:   customer.printOn({})    would take the type / class of the object supplied and dynamically create an instance of the writer to use - in this case the passed objects is a hash, so the factory would find a CustomerHashWriter to write to.    There are a lot of possibilities.

When I think about it the only things I typically do with an object can be categorised as one of the following:

1. print - human representation
2. store - non-human representation
3. read - from non-human representation
4. convert - from one representation to another.

I typically use the following methods corresponding to the categories above:

1. printOn
2. storeOn
3. readFrom
4. convertTo

Creation and destruction are needed too, but these are typically handled by the implementation language.

I have in the past written an entire system using this approach and it was simple to modify and understand.

Here is the Ruby code: East Ruby Example

More East …

Sunday, June 12th, 2011

more-east

Recently I was a special guest on ADDcasts back in episode 4: http://addcasts.com/2011/04/21/episode-4-special-guest-james-ladd-talks-to-us-about-running-smalltalk-on-the-jvm-immutability-and-how-to-write-good-oo-code/. After the episode aired I received some questions about East. What follows is part of my response which I am posting to continue the discussion on East in the hope that more people try the technique.

Im interested in learning new ways to write software and make what I am writing more readable to others, so Im ok with people disagreeing. I learn more if they do.

I think I led with a poor example and reasoning as I have limited time to think on weekends as I look after my twin boys who are 2.5

Lets forget the accessor and mutator side of things and just focus on the implications of asking an object for information and working on it, rather than asking that object with the information to do the work. This is the key principle - Tell Don’t Ask

When we allow callers to ask for data and we want to know what they do with that data we have to find all callers and look in detail at what they do with the data. Usually what they do with it will be spread over multiple statements, even if those statements just a ‘get’ of multiple attributes. When they can ask for each ‘field’ this task becomes larger and possibly harder. Why did they ‘get’ just 2 attributes here but in other code they ‘get’ 6?

In addition, when we allow callers to ask for the data I usually see multiple callers doing the same processing on the returned data. This might be as subtle as a conversion to uppercase, but I have seen much more repetition creep in. How often have you seen this in the caller:

returned_collection.each {}

This repetitive processing should be in one place - and highlites a missing concept/abstraction. For example, Why does the caller iterate over the returned_collection?

When you face the calls East and ask the object with the information to do the work then the use cases become more evident. For example, “customer.printOn envelope” provides more meaning than looking at multiple call sites. Note I’m not discussing the implementation of Envelope here - personally Id be using an object, even if in Ruby/Smalltalk.

When the use cases are encapsulated in an object like Envelope then the commonality of multiple “functional object” objects can be refactored and kept DRY.

Testing in the case where you can ask an object for attributes requires a lot of setup like when I call this accessor, then return that value”. In contrast when faced East the testing  changes. Usually there is a simpler expectation like “when I call this method, that object receives these calls.”

What I would like to see happen is for people to try this approach and see how it effects their design and their process of getting from A to B. Personally I have found the process to be more effective in time and the ability to understand the resulting code, which I also find there is less of.

Presenting at Smalltalk Solutions 2011

Wednesday, January 19th, 2011

Redline

For some time now I have been working on a personal project: Redline Smalltalk and blogging about it here.

In March 2011 Ill be presenting the journey so far at Smalltalk Solutions 2011 in Las Vegas

If you get along to the conference please come and say g’day.

Disable The File Save Dialog

Monday, September 27th, 2010

No File Save Dialog

The web application I am developing allows the User to download various files in different formats. To test this works I’m using a combination of things, with Ruby WATIR-WEBDRIVER for the front end and Firefox for the browser and all automated with Hudson as the Continuous Integration (CI) Server.  The problem I face is that Firefox wants me to tell it what to do with the files each time I download them and this isn’t going to work for my CI needs.  So how can I prevent Firefox from asking me what to do with each file I download?

The functionality is there inside Firefox and WATIR-WEBDRIVER and you just need to turn it on. What follows are the steps to do this:

Create a Firefox Profile

Run the following command from your command prompt / terminal:

firefox -ProfileManager -no-remote

This will start an instance of the Firefox Profile Manager (see below) where you can create a new profile. I called mine “no-download-dialog”. You may also have an existing profile for running WebDriver but leave this alone. Click “Create Profile” and follow the wizard.  When back on the profile manager select “Don’t ask at Startup.”. Click “Start Firefox”.  NOTE that we are now using the Firefox Profile we just created.

Make a File Association

Firefox allows you to disable asking you what should happen to files being downloaded when there is a file association for that type of file.  So using this Firefox instance go to a Web site and download a file of the type you are going to download during your tests. In my case these were XML and Word documents. During the download Firefox will ask you where you want to save the file and allow you to select the option to “Do this automatically for files like this from now on” (See below). Select this option and save the file.

Now that file is downloaded Firefox should have an association between the file type and the action you want to perform. To make sure this is correct go to the Firefox Preferences (sometimes called Options) and select the Applications tab. I’m using Linux so this is Edit->Preferences->Applications (See below).  Scroll down the list of Content Types and Actions until you find the Content Type for your file. If you can’t find it then maybe your Web Server is sending something else as the Content Type when you download files.  When you find the Content Type check that the Action is set to “Save File”, if it isn’t you can change it now.

As a final test find another file of the required type and download it and you should not see a file dialog. However, you may see the Download Manager window, which can be disabled in the Preferences->General tab. De-select the “Show the downloads window when downloading a file”.

Test with Profile

Now that you have a profile that doesn’t ask what to do with downloaded files you need to tell your tests which profile to use. I’m using WATIR-WEBDRIVER but the same abilities are provided with other tools that sit atop Selenium. In your code where you obtain a browser instance add an argument to specify the Firefox profile to use. For me this looked liked this:

Watir::Browser.new(:firefox, :profile => 'no-download-dialog')

In some other tools or in Java you may need to specify the profile on the command line like this:

java -jar selenium-server.jar -firefoxProfileTemplate "<your no download dialog profile name>"

Set the Default Profile

So that Firefox is using the default profile when started outside of testing you need to tell it to use the “default” profile again. To do this Start Firefox Profile Manager and choose “default” and make sure “Don’t ask at startup” is selected and then exit.  Firefox should behave as normal when started outside of testing

Now when Firefox is run by by the Continuous Integration Server it will not stop the tests to ask you where to save files.