Martin Fowler defines Software Architecture

Yesterday I saw the following video of a brief talk by Martin Fowler, in which he defines software architecture. I have grumbled about that term myself, in that firstly it is often ill-defined, and secondly it can be pretentious. I have sometimes defined software architecture as “high level design”, or as the design of systems complex enough to warrant substantial input from someone who is been around the block many times.

Fowler’s definition is crisp: Software architecture is those decisions which are both important and hard to change. This means it includes things like the choice of programming language, something architects sometimes gloss over or dismiss. Both aspects land squarely on the economics of software development. Said another way, software architecture is those decisions which, if made poorly, will make a project either succeed or fail, in a needlessly expensive way.

This connection resonates deeply with me. I have often talked about the economics of software development, the economic impacts of tool choices, the economic impacts of process selection, platform selection, etc. But Fowler’s talk made a connection I had never set out loud at least: the economic concerns, not only the technical ones, are software architecture.

 

Record Development Meetings with Hangouts On Air

At Oasis Digital, our project teams coordinate in numerous ways, sometimes by meeting “live”. At these meetings we discuss, we plan, we model, we code, we review. For teams/projects where everyone is physically present at headquarters, this is readily done by plugging in to a large TV re-purposed as a computer monitor. (Proposed bumper sticker: “My other monitor is a 60 inch Samsung”.)

For some teams and projects, though, not everyone is at our St. Louis office. Some of our developers are around the US, and occasionally projects include developers around the world. Therefore, some of our development meetings take place online, using a variety of meeting tools. Mostly these meetings are useful only at the moment they occur, but it is useful to record them for developers who are unable to attend “live”.

There are countless tools to choose from. We have had particularly good results with Google Hangouts. Unfortunately normal Hangouts has no recording feature – the recording capability is available only in the form of “Hangsout On Air”, which is more typically used to “broadcast” an online meeting. Google Apps customers, though, can use Hangouts on Air, decline to broadcast to anyone at all, then share the recording privately.

The process is not obvious. Here is how to use Hangouts On Air to privately record and share online meetings:

  1. Consider performing all of these steps in a dedicated browser. For example, use Chrome for Hangouts, while using Firefox for other browsing. This reduces the opportunity for Hangouts (which is irritatingly bound to the browser) to interfere with other use of your computer.
  2. Log in to YouTube. Use the Google account selector in the upper right to select your company Google Apps account, if you are logged in an more than one account.
  3. If you don’t already have a YouTube “Channel”, which you probably don’t, click to create one. It is harmless, since for this Hangouts On Air purpose you don’t need to every actually publish anything to your “channel”.
  4. Click “Video Manager”. The button for this is not in the most obvious place (the left navigation), rather it is along the top, and small.
  5. Click Live Events.
  6. Click to create a new live event.
  7. Give your meeting event a name.
  8. The description, keywords, etc. do not matter, since you won’t be publishing.
  9. Adjust the setting to make it Private. This is a vital step, don’t miss it.
  10. Don’t share it with anyone yet. That comes later.
  11. Choose the default Quick settings, there is nothing important to adjust in the Custom settings.
  12. Click to start the Hangout On Air. This will launch the same Hangouts app as any other Hangout – almost. As of December 2014, the features for Hangouts on Air are somewhat behind the normals Hangouts app in features and screen layout.
  13. Click the invitation/add button in the Hangouts controls at the top of the Hangouts window.
  14. Copy the link. Paste it in group chat so that other developers (meeting attendees) can join.
  15. Wait for everyone to get in the meeting. Adjust microphones, webcams, speakere, etc.
  16. Remind everyone to turn on their webcam and keep it on if possible. This provides a much better experience for anyone watching the video later – they get more of a sense of having “been there” for the meeting.
  17. Discuss anything that isn’t part of the project in question, etc. while waiting for everyone to be ready.
  18. Click Start Broadcast. This will start the “broadcast” to noone (because this HoA is private and not shared with anyone), and more importantly, start the recording.
  19. During the meeting, remember that whatever is visible in the Hangouts app window, will be recorded. Adjust this regularly to keep it relevant to the discussion. Often the default behavior of switching to whoever is speaking, works well.
  20. Remember that Hangouts On Air recordings are limited to pseudo-high-def, “720p”. Keep screen share window sizes moderate, so that text can be easily read by others in the meeting and on the recording. Sharing a full-screen at 1920×1080 or higher resolution will yield unreadable results.
  21. When the meeting is done, Click Stop Broadcast.
  22. Back in the Youtube Video manager, paste in the email addresses of those with whom the recording should be shared.
  23. Don’t trust Google/YouTube to maintain privacy settings over the long term – leave the recording there until it has outlived its usefulness (a week or so in a typical project, maybe longer in a slow-paced project) then delete it.

Ouch, a 22-step process. That is the price of using Hangouts On Air in for an atypical purpose. The payoffs:

  • HoA works well across all major platforms, including Windows, Mac, Linux, Android, Chromebook, and more. This is the hardest thing to replace, many other meeting tools don’t come close.
  • The recording is immediately available privately on YouTube, all transcoding and hosting is seamless and effortless.
  • Google / YouTube is infinitely scalable, for all practical purposes.
  • No cost, for either the tools or the hosting.
  • Part of software (Chrome) that most developers have already installed.

 

More CSS in JavaScript, this time with React

In September I mentioned a talk at Strange Loop 2014 where the speaker described a technique for writing CSS in the form of JavaScript which then executes to produce the actual CSS. This avoids a server-side build process, it knows more about the browser while operating, it avoids a HTTP round-trip, and has various other advantages. However, the tooling the speaker was talking about was closed source inside of the conference speaker’s product.

Today I encountered a presentation online by a React expert at Facebook, who uses React’s mapping from JavaScript to HTML+CSS, to accomplish many of the same things and more – using tools openly available.

If anyone knows of a audio or video recording of the talk, I would appreciate a link very much.

My own experiments with programmatic CSS also react, but behind ClojureScript, so I’m writing Clojure code which turns into CSS. It is not as mature as what is described in the slides above, but it adds yet another layer of abstraction in the form of a higher-level language.

Task Based User Interfaces

Here at Oasis Digital, the bulk of our work is on complex business data systems. These projects sometimes involve a so-called task-based user interface. Briefly, this is an interface where the operations available to the user are presented in terms of the problem domain, rather than in terms of editing data. Other names for this idea include “task-focused user interface” and “inductive user interface”.

Origins

I was unable to determine the specific research/practice origins of task-based UI, but it is most commonly seen as arriving from three main directions. First, the inductive user interface guidelines published by Microsoft around 2001 lay out a detailed description and motivation. Second, the domain driven design (DDD) and command query responsibility separation (CQRS) communities often described task-based UI as suitable for use in front of the system built with those principles. Third, simply looking at mass-market software there are numerous examples.

CRUD

Task-based UI is the opposite of CRUD UI, a convenient foil. Many software systems have numerous features which are readily described as CRUD: create, read, update, delete. Some developers describe their work as primarily creating CRUD systems, with either pride or disdain. When analyzing a proposed feature or proposed software project, we sometimes evaluate the extent to which the project is “just CRUD” versus behavioral functionality. Brought to the user interface, CRUD typically means screen after screen in which users can make an entity of some kind, find an existing one, update one, or remove one. In other words, a minimal veneer over basic database operations.

Simple CRUD user interfaces have the advantage that they are generally easy to create, and amenable to common tooling. Many development environments offer wizards or libraries to ease such creation, and this dates back to at least early 1990s, and probably much farther than that.

Therefore, CRUD has a lot of appeal when first creating a new application. Unfortunately, a system built primarily around CRUD tends to make behavior beyond minor validation unduly difficult to implement. If you find yourself squeezing business logic into an “on change” or “on click” event handler somewhere, you are probably experiencing this difficulty. As systems grow in complexity this bad fit can consume vast amounts of time and money.

There is a way out, and that is a task-based user interface, one which presents the user with options and actions which fit the problem domain of the software, rather than those which appear to manipulate data in trivial ways.

Change of Address Example

A common example to explain task-based UI is a change of address operation in a system which has subscribers, members, or some other class of people to whom things might be mailed etc. The CRUD approach to change of address is simple: the user searches for the appropriate user record, views that record, moves the cursor to the address fields, types over those values, and clicks “save”. Very convenient, very easy to program.

Unfortunately, down the line if there is nontrivial behavior in the system, it can be extremely difficult to determine what such an edit means. Was the address corrected because it had been mis-entered in the past? Was the ZIP Code changed because the post office changed the ZIP code assigned to that physical location? Or does this edit represent the person moving to a different place of residence? If the latter, how might that affect them in terms of the problem domain?

To avoid this, a task-based user interface would not only present address fields which can be edited. Rather, the user would see information about a person (including their address) then have options (buttons or whatever else is suitable in the visual UI guidelines at hand) with names like “correct mis-entered address”, “subscriber moved to another residence”, etc. Such explicit actions make it possible to capture the underlying domain-level meaning, rather than just edits to data fields. A downstream system receiving this information could then respond appropriately.

Choose Your Words Wisely

Task-based user interface is therefore to a considerable extent about words: the words which describe actions the user can take. If a system merely uses a task-based user interface on top of a CRUD-centric back-end implementation, then the words can at least be chosen well in the user interface. If the system uses a domain driven approach internally, then some of the well-chosen words in the user interface may become part of the ubiquitous language used throughout the implementation.

I encourage developers to consider a task-based approach even if the underlying system is not particularly domain driven.

Add, Edit, Delete, +, –

Speaking of words, having built numerous user interfaces, I very often still “default” to wire framing with button labels like “add” and “delete”. Such things are fine for an early initial wireframe, but task-based design principles suggest reconsidering whether a more specific set of operations is suitable.

An example came up at work today with a list of employees, and the initial proposal was a “delete” button next to each one. But one does not merely delete an employee: at even the most heartless of companies there will be quite a lot more process involved in removing an employee from a list of employees. A system which manages the employees then, should probably have some sort of process flow around that removal, and it should use words other than “delete”.

A Final Quip

If the user wanted Excel, they would use Excel. If they are using an application which is instead specific to a problem domain, then it should have features, both internally and at the user interface level, relevant to that problem domain.

Links

http://en.wikipedia.org/wiki/Task-focused_interface
http://msdn.microsoft.com/en-us/library/ms997506.aspx
http://codebetter.com/iancooper/2011/07/15/why-crud-might-be-what-they-want-but-may-not-be-what-they-need/
https://cqrs.wordpress.com/documents/task-based-ui/
http://stackoverflow.com/questions/12255874/what-is-an-example-of-a-task-based-ui
http://codebetter.com/gregyoung/2010/02/16/cqrs-task-based-uis-event-sourcing-agh/

FlightJS, an event-centric JavaScript library/framework

Are events your favorite part of AngularJS?
Look at FlightJS instead.

Angular’s Event System

At Oasis Digital, we use AngularJS for most of our client-side “SPA” web development. AngularJS is well suited for data and form centric enterprise web applications we most often work on; I’ll write more about why we chose AngularJS another time.

As we teach our Angular Boot Camp class, we spend time on the AngularJS event system. For those who haven’t looked at it, AngularJS’s event system operates at a higher, more abstract level then DOM events – AngularJS events propagate up-and-down AngularJS scopes rather than up-and-down the DOM directly. We typically recommend it only for narrow cases where some bit of information should be transmitted and responded to broadly across the application; it avoids the computational cost of numerous watches.

In both these classes and our development work, we sometimes meet developers who are very excited by the AngularJS event system, and endeavor to create an event-based application with it. We must then unfortunately give the following disappointing advice:

If you are looking to build a mostly event-based system, AngularJS is probably not the right tool for you. There are a lot of merits to events, but the event-centric approach is not the AngularJS way. If you’re going to build primarily with events, you are wasting much of the AngularJS ecosystem, which is primarily about scopes, data binding, directives to enhance HTML with technology and domain specific add-ons, and so on.

DOM Events Find a Home

But that is not to say events are bad. Events are great. Don’t lose hope. There is a home for you: Twitter’s FlightJS.

FlightJS is 100% event centric and DOM-centric; it embraces the browser DOM with minimal abstraction. FlightJS is tiny – according to its website “Flight is only ~5K minified and gzipped. It’s built upon jQuery.” FlightJS fits in well with JavaScript ecosystem; because it adds so many fewer features than one of the big frameworks, there is little to get in your way of using it with any other common tool. Based on a quick look at its mailing list and GitHub repo, is getting a small amount of traction, though perhaps much less so than the big frameworks.

Here at Oasis Digital, we are not switching to FlightJS, and we don’t force an event centric approach on our AngularJS work, in which we aim to stay squarely in the mainstream of AngularJS practice. But if something comes up where events are the right solution, we know where to look, and now you do too.