Dell: The D is for Customer Disservice ..

December 1st, 2012

This post is about the bad Customer Service I received  from Dell’s online chat facility and how I think putting Customer Service Operators in front of Customers without the proper tools is tantamount to sending troops into battle without weapons. Your going to loose the battle for a happy Customer, and your staff are the casualties.

Unhappy Dell

About 10 years ago I had a Motorola mobile and I wanted to know if I could use it in the United States. I rang the local provider I was with to ask. The Customer Service representative said they could not answer my question and that I should try Motorola directly and could I hold. I then heard a flicking noise like the pages of a telephone directory were being turned. This was 10 years ago. I asked the operator what she was doing and she responded “I’m looking up Motorola’s number for you, I can’t put you through but I can give you their number.”. What helpful service. I was a customer of the provider for quite some time after that and I was very happy with the service.

Today I read an article on on the new Dell XPS 13 Developer Edition which comes with Linux installed. I went to Dell Australia and searched for it. No Luck, so I went to the Dell US site thinking that maybe it has been released in the States and down under might be lagging behind. Nope, no Dell XPS 13 Developer Edition on the site. I used the search box top right. Why would Dell announce a product was available and yet not list it on the site. Frustrating.

I was just about to leave the site when a window popped up  and asked me if I would like to talk to a Customer Service Operator and I clicked Yes. What follows is a transcript of that discussion, which Dell emailed to me when I closed the chat window. I have removed the names of the operators since this post isn’t about them, it is about the bad Customer Service I received because of the tools provided to them. Needless to say I didn’t buy a Dell today and I’m not sure if I ever will again. Although I probably should not even have considered them after the Battery in the Dell Latitude I have failed to charge just 3 months after getting it. Another story.

chat log

What I want to happen is for the search to return the product I’m looking for.  Secondly, when dealing with Customer Service I want the first person I deal with to be able to handle my query. When being handed from one person to another I expect not to have to repeat my story, especially when it is in electronic form for all to see.

Dell, please don’t send your troops to the front line without proper support, its abusing them and loosing you Customers. Please don’t tell me your systems are not compatible or don’t talk as that is just an excuse. I write software and I could make them talk.

When Customer service systems don’t align or sync to provide Service then you are simply automating a processes to upset customers quickly. Do you really want that?

I’m a Redliner, are you?

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 …

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.

Automatically integrating Java with Smalltalk …

June 7th, 2012

spock-stuffy

I have been working on Redline Smalltalk for some time, and just now I have made some changes that I am very proud of.

With the new additions it is now possible to automatically integrate Java classes with Redline Smalltalk allowing you to talk to Java classes as though they were 1st Smalltalk objects. There will be a longer more detailed post on this topic in the Redline blog very soon. The 2 second brief on how to integrate a Java class is to put the following in your Smalltalk script or class.

import: ‘com.domain.JavaClass’ as: ‘LocalName’.

What the above does it allow you to refer to com.domain.JavaClass via the identifier ‘LocalName’. The object referenced by ‘LocalName’ is a Smalltalk object and responds to messages just like any Smalltalk object.

Behind the scenes Redline Smalltalk uses Java Reflection to query the Java class and generate Smalltalk code that represents an Adaptor for the class. This Smalltalk code is then compiled on the fly to JVM bytecode and executed.

I’m proud of this work and I really hope you give it a try, and come back to the Redline blog for the full details .

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

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.

Courtesy is catching …

April 18th, 2012

bowing

I received an email from a friend regarding my interactions with him, and the positive effect they have had on him and his interactions with others. It appears that courtesy is catching.

Here is the email:

“We haven’t had a chance to chat for a while but the things you write have had an impact on my interactions with others. One thing I noticed is you take the time for a pleasantries like “nice to chat with you”. I always try to be polite with others when I interact with them but never quite as far as showing appreciation just for the opportunity to interact. Lately I’ve been adding a few of these kinds of pleasantries when interacting with others. Even with people I have good working relationships with, I’m finding they appreciate the acknowledgement and I enjoy giving it. So it is a bonus for everyone.

So thanks for leading me by example. :-)

RASMATAZ: a safer assembler …

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 …

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 …

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 …

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