Michael J.A. Clark
Michael Clark is a professional software developer who creates high-quality products for startups in Cambridge, UK. Skills: C#, Java, PHP, XHTML, AS3, CSS, ML.

Sections

Contact details

Email
mjac@mjac.co.uk
Skype
mjacdotuk
Twitter
mjacuk

Articles tagged coding

Android Design Guidelines

The Android Design Guidelines from Google are common goals for all Android apps across every device.

Android devices

Enchant me

  • Delight user in surprising ways
  • Real objects better than buttons or menus
  • Provide sensible, beautiful defaults, but consider fun personalisation
  • Get to know user choices, place them in easy reach once learnt

Simplify my life

  • Simple phrases and short words - 30 character limit
  • First two words of phrase should contain taste of important info
  • Avoid repetition of terms in a phrase
  • Use casual conversational language
  • Pictures get attention and more efficient for explanations
  • Act rather than ask user, too many choices off-putting - but let user undo
  • Break info into digestible chunks - only what they need when they need
  • Make places in app distinctive, user should always know where they are
  • Use transitions to show relationships between screens
  • Feedback for ongoing tasks
  • Remember settings, personal touches, let people access their creations
  • Discern functional differences with visuals: look the same = act the same
  • Only interrupt user if it’s important

Make me amazing

  • Use visual patterns from other apps
  • Gentle error messages, try and give as little technical info as possible
  • Give feedback on actions, break complex tasks into simple ones
  • Make important actions fast and easy to perform from anywhere in app

Thanks for reading, please add your comments.

Lessons learnt from The Pragmatic Programmer

In October 2011 I read The Pragmatic Programmer: From Journeyman to Master by Andrew Hunt and David Thomas. This article is a summary of the major points I picked up.

Read this book if you are serious about software engineering. Some of the sections apply to other areas of life too: all skills are progressed with small continuous improvements -- the Kaizen principle -- and over time these improvements accumulate, resulting in proficiency then mastery.

Being a pragmatic programmer

The book idealizes the idea of the pragmatic programmer. These noble individuals are inquisitive, think critically and care about their craft (including adopting early). Instead of making excuses, they provide solutions to problems and take responsibility for mistakes.

Programming is an intellectual activity and the value of a programmer is based on their knowledge portfolio. The portfolio must be built and maintained with regular investment and diversification: read at least one technical book per quarter and learn a new programming language every year; learn more and emerging technologies.

If you want to be a pragmatic programmer, actively participate in local user groups for career opportunities, and always think critically about what you read and hear. Develop catalysing improvements and let teammates marvel and join in instead of communicating without action. Your signature should be an indicator of quality.

Communication is imperative

Communicating is an important part of a programmer's role and effective communication results in influential positions. When discussing anything, always listen first. Before beginning your communication, plan and refine your statement/ideas to have the optimum value for your target. This includes adjusting the style of delivery to suit their understanding. Choose the moment of communication wisely, understanding audience needs/priorities. If in doubt, ask about their preferred delivery style. To understand an audience, learn the WISDOM acrostic:

  • What do you want them to learn?
  • What is their interest in what you've got to say?
  • How sophisticated are they?
  • How much detail do they want?
  • Whom do you want to own the information?
  • How can you motivate them to listen to you?

Rapidly respond to all emails and voicemails, even if it has to be a simple reply or that you will get back to them later.

Tools for pragmatic programmers

Tools amplify talent: productivity soars when you use a single editor well and understand the command shell. Always use source code control and utilize it to produce automatic, repeatable product builds. Binary formats divorce data from meaning; text formats are resistant to obsolescence and can leverage most computing tools.

Knowing a text manipulation language like Perl is useful for active code generation (generating structural source code from schemas) and passive code generation (create new source files, save typing).

Pragmatic projects

Successful systems are those that meet user requirements, thus use users to help decide whether a system is good enough to ship. Gently exceed your users expectations and delight them. Fix or comment on broken code immediately to prevent the Broken Window trigger mechanism, where the first signs of neglect cause entropy and decay.

A requirement is a statement of something that needs to be accomplished. Document business policies away from the more generic requirement, as policies change frequently and may end up as metadata in the final application. Solve the business problem and don't just meet the stated requirements. Work with a user to think like a user. Good requirements documents remain abstract as the simplest statements represent the business need best. Requirements are need. Abstractions live longer than details.

Point out the cost of each new feature against the project schedule to the sponsors of the project. This provides an accurate picture of requirements growth Use a project glossary that contains the specific terms you use. When faced with an intractable problem enumerate all avenues, even though that seem daft. Some things are better done than described. With specifications there is a point of diminishing or negative returns as they become more detailed. Don't be a slave to formal methods because these generally require explanation to end users (UML). Understand the whole system instead of specializing.

Estimate to avoid surprises. The best estimate comes from someone who has already created a similar project. Create a model of the product, break it into components with parameters, and give each parameter a value. Record the estimates and compare them to measured values as the product is created. The schedule should be iterated with the code to provide the most accurate scheduling estimate. Take time with estimates instead of producing them off-the-top of your head.

Assumptions that are not based on well-established facts are the bane of all projects. Do not program by coincidence, document assumptions and test them. Don't let existing code dictate future code, be ready to refactor because the impact will be less than cost of not making the change. Refactor when there is duplication, nonorthogonal design, outdated knowledge, or to improve performance. It must be undertaken slowly, deliberately and carefully. Have good tests before you begin refactoring. Always take short deliberate steps.

Team orthogonality is inversely proportional to the number of people who have to be involved when discussing changes, separating responsibilities increases efficiency. There are no final decisions in software construction and team leaders that ignore this have their eyes forcibly opened when the future arrives. Organize teams around functionality not job functions.

Pragmatic software principles

The DRY principle (Don´t Repeat Yourself) states that every piece of knowledge in a system must have a single authoritative representation. Low-level comments violate this principle by duplicating the information held in the code. Taking short cuts makes for long delays. To reduce interdeveloper duplication have a technical and capable team leader with a clear design for the system, so that code can be reused.

Aim for orthogonal components. When components are orthogonal, their execution is independent, providing more combined functionality. Modules should be self-contained, independent and have a well-defined purpose. When creating classes, normalize data representations according to the business model and use accessor functions to decouple the internal class data from external calls. Singletons can lead to unnecessary linkage when they are used as global variables.

Put abstractions in code and details in configurations, outside the code base. Configuration files allow an application to be customized without recompilation, extremely important in critical live systems and useful when distributing the same core app to different clients (only changing metadata). Long running processes should have a method to dynamically reload metadata while running to prevent downtime.

Be careful about how many modules you interact with and how you came about interacting with them. The Law of Demeter prohibits accessing a third object's modules and reduces errors by reducing the response set size (direct function invocations). Instead of digging through a hierarchy, ask for what you need directly. Note that performance can sometimes be improved by coupling modules, sharing information about class internals.

Programming methods

Tracer bullets are partially functioning code modules that can be adjusted iteratively with feedback from users. They provide the client with early demonstrations and can be changed rapidly, being lightweight compared to a full (perhaps incorrect) implementation.

Prototypes are disposable modules that reduce the cost for correcting design mistakes by analyzing and exposing risk at the start of a project. Anything critical or difficult should be prototyped. Prototypes do not have to be correct, complete, robust or styled. With architectural prototypes, ensure that module responsibilities and collaborations are well defined and that coupling is minimized. Estimate the order of the algorithms and test these estimations against measured data from the prototype.

Domain languages can be used express business needs and allow programming close to the problem domain; this results in specialised code that is adaptable to changing business requirements. Domain languages can be compiled using existing tools like Yacc/Lex into C or another target language. Complex workflow requirements can be encoded in a rule-based (expert) system embedded in the application so it can be configured by writing rules instead of code.

Use automatic procedures like cron and makefiles. Web content should be generated automatically from information in the repository and published without human intervention. Teams with automated tests have a better chance of success.

Comments should discuss why something is done. Code is read more times than it is written, spend time writing clear commented code (sensible variable names). Always put a date on documentation so users can see when it is updated.

Concurrency and resources

Always design for concurrency. An important part of this is decoupling time and order dependencies. The hungry consumer model provides quick and dirt load balancing. Resources should always be allocated in the same order and freed in the opposite order to reduce the possibility for deadlock.

Events are used to signal changes about an object minimizing coupling with the other interested objects (thereby increasing reversibility). To prevent spamming use a publish/subscribe protocol. In MVC, models have no direct knowledge of views or controllers, views subscribe to changes in the model and logical events from the controller, and the controller controls the view and provides the model with new data. Always consider having a separate debugging view.

Blackboard solutions decouple objects completely: shared information is stored in a central place so that contributors and arrival order is irrelevant (based on tuples spaces). JavaSpaces are an example, supporting read/write/take/notify operations.

Pragmatic paranoia

Do not trust or expect yourself to write perfect software, you cannot. Debugging is just problem solving. When a bug occurs do not panic and prioritize on fixing the problem. The fault may be several steps removed. The best way to start fixing a bug is to make it reproducible; this also means that you know when it is fixed. Data visualization can reveal far more than simple data display and rubber ducking, explaining the problem to another individual, can cause the solution to become apparent. Usually the fault lies with your code not well tested 3rd party software. Once the bug is fixed, determine why it was not caught earlier.

Design and deployment

Design by contact verifies that is a program is correct, that it does no more and no less than it claims. It also forces requirements to the forefront. Each contract contains preconditions, postconditions and class invariants. The latter two are guaranteed if the preconditions are obeyed. Attempt to write lazy code, code that has strict preconditions and return the minimum possible. Assertions can partially implement contracts in languages without native support. Crash early at the site of the problem.

Errors should always be on the side of not processing a transaction instead of duplicating it, err on the side of the consumer. Always have a default case, because the impossible can happen. The code is no longer viable if the impossible just happened so it must be terminated.

Always leave error checking (assertions) turned on. Use exceptions for exceptional problems.

Testing

Build testing into the software from the beginning then test each piece of the project independently, then together. Unit testing should attempt to ensure that a given unit honors its contract. When you design a module or even a single routine you should design both its contract and the code to test that contract. Accessible test code not only provides an invaluable example of code use, but also a means to test regressions and validate future changes.

Develop a standard testing harness for the project. Test early, often and automatically.

Unit testing verifies individual modules. Integration testing shows major subsystems interact successfully. Regression tests compare current output with previous (known) values. Use real world and synthetic data to test and stress boundary conditions. Saboteurs can be used to test testing. Coverage analysis tools can determine the lines of code that are hit with tests. If a bug slips through the net, add a new test to trap it next time -- find bugs once.

Inspiring quotations

  • "It's easier to ask for forgiveness than it is to get permission" Grace Hopper
  • "An investment in knowledge always pays the best interest." Benjamin Franklin
  • "The limits of my language are the limits of my mind." Ludwig Wittgenstein
  • "Perfection is achieved, not when there is nothing more to add, but when there is nothing left to cut away." Antoine de Saint-Exupéry

In conclusion

The Pragmatic Programmer should be a constant figure on the bookshelf (buy from Amazon). This short summary does not do it justice. I hope you enjoy it as much as I have.

Thanks for reading, please add your comments.

Setting up Disqus Comments

Before now, I disagreed with comment systems and preferred direct contact through email. This naive approach resulted in little interaction from the web community. Comment systems only require 5 seconds of commitment, and users are more likely to return once this premature commitment has occurred.

So which comment system to use? Drafting my own is not an option (Don’t Repeat Yourself). Comment systems have been implemented thousands of times before.

Two possible web solutions

  1. Disqus integrates with Facebook/Twitter and is used by Wired magazine. Known for deep social integration.

  2. Intense Debate targets blogging platforms like WordPress, Blogger, Tumblr. Previously used with the Cambridge Tab Wordpress platform.

Choice for the first prototype

I chose Disqus because of three key reasons:

  1. Clean administrative interface
  2. Installation requires a single JavaScript snippet per article page
  3. Support for permalinks and unique article IDs

Thanks for reading, please add your comments.

Useful resources for Flex AS3

I recently spent a summer creating Adobe Flash applications for Kickstart Digital using the Flex framework. Back in my teenage years I spent a lot of time creating pseudo-agencies with flashy adverts (Flash 4/5/MX). It has progressed incredibly since then.

AS3 is a respectable, highly featured language. Flash is capable and still has a place in development. I cannot imagine developing for it without Adobe Flash Builder 4. Until a widely adopted Javascript/Canvas IDE is developed, Flash will have a place delivering rich media on the web.

Starting out

Essential resources include the Spark components and complete list of Flex 4 classes. Learning how to handle exceptions is essential as much of development time is spent testing. Bugs are inevitable after all.

These resources should be bookmarked before embarking on a Flex adventure. It is important to use the latest Spark components such as s:BitmapImage instead of older mx:Image components. Some tutorials can now be improved using Spark components.

The program can attach events to the UI lifecycle. Common attachment attributes include preInitialize, initialize, creationComplete and applicationComplete. I use initialise the most, placing the handler before dimensions are calculated but after all child components have been initialised first.

Layouts

By default spark groups position children using absolute coordinates. Other layouts can be assigned using the spark layout element:

<s:Group>
    <s:layout>
        <s:HorizontalLayout />
    <s:layout>
</s:Group>

Prefer to use inbuilt element abbreviations. A large amount of interfaces can be created using just these three component containers.

<s:HGroup />
<s:VGroup />
<s:TileGroup />

Each group can have a default alignment for child components. Gap is the name for spacing in Spark components as is an extremely useful attribute.

Data structures

AS3 has inbuilt Array, Object, Dictionary, Vector data structures. This page provides a brilliant overview. In addition there is a LinkedList implementation though I have not found a place to use it yet.

The Vector data structure is interesting because it is the only typed container. It was added to improve performance of high throughput game code using internal prediction (as each data item has fixed size).

var newVec:Vector.<int> = new Vector.<int>;
newVec.push(1);

Note the strange dot syntax, unlike Java or C++. Expect more of these generics in later versions of ActionScript.

The Dictionary object has many useful features. The operator in is useful for determining whether a key is in an associative array. A useful AS3 feature allows direct iteration over both keys and values:

for (var key:Object in dict) { }
for each (var value:Object in dict) { }

Arrays do not have a copy method. The best solution I have found is to use concat to create the new array.

Data structures have functional methods like Array.filter. Unfortunately the callback function is verbose.

function callback(item:*, index:int, array:Array):Boolean;

AS3 Data Structures For Game Developers is promising for data intensive applications.

Design patterns

Classes have strange behaviours. For instance you have to be careful how you call super. They have an additional internal modifier the common private/protected/public/static modifiers. This specifies that a property is visible within the same package (see more).

Singletons are often useful in AS3. Especially when performing multiple calls to a web service. Unfortunately private constructors are not supported by Adobe to preserve backwards compatibility with the ECMA specification.

Many people diagree with Singletons. See Why Singletons are Evil for a powerful argument against their use. I think they have a place in rapid web development, at the expense of component rigidity.

Text handling

Font embedding is required by most Flash application designs. It is not intuitive in Flash Builder 4. The first comment about this article works well. It details:

  1. Start a new flex app
  2. Go to design view
  3. Open the “Appearance” tab on the right
  4. In the font drop down list, you can choose browse to find your font files.

Word wrapping in Flex 4 is achieved by setting a width and changing the line break style:

<s:Label width="200" lineBreak="toFit" />

Scrolling

Scrolling is common in a large amount of applications that load data dynamically. Joeflash’s Enigmacopaedia has an excellent explanation of how to mask a group with a rounded rectangle. You can bind horizontalScrollPosition to the scrollbar value. Then when the scrollbar is modified the visible area of the scrollable group reflects the value change without additional code.

Top source for learning is the Adobe documentation on HSlider.

Skinning

Most media projects require complete skinning. Learning how to skin a scrollbar takes you most of the way towards creating a variety of custom skinned components.

Many components can be skinned simply by changing the source image of an internal bitmap. Skinning in Flash using XML Spark components reduces release size. Layering inbuilt shapes with strokes, fills and visual effects can easy emulate Photoshop designs of interface elements.

Mouse handling

Any descendant of the Sprite class (most UI components) has a buttonMode MXML attribute that shows the pointer cursor when the mouse hovers over the element. By default transparent sections in the element are ignored by the mouse. This is intuitive but can annoy users when half the pixels are not clickable. This mouseEnabledWhereTransparent property toggles this behaviour.

Thanks for reading, please add your comments.

Decentralised XML storage

Over the past couple of years I have been experimenting with an XML storage system for displaying articles. I first wrote about during my 2008 homepage refresh. The last couple of days have seen a major overhaul, converting from a centralised XML database to dispersed XML files that accompany each entry. The article directory is parsed and these XML files are collated and serialized by PHP.

Having a decentralised storage mechanism allows greater integration with the filesystem. It removes the need to update and overwrite the XML database after every change. Now a new article can be uploaded to a directory using FTP and automatically deployed on a cache refresh.

Example XML info file

The XML format allows content to be mapped to different output types. This webpage is delivered as XHTML so the convertor identifies PHP Markdown as a class library to achieve the mapping.

<?xml version="1.0" encoding="UTF-8"?>
<article>
    <title>Decentralised XML storage</title>
    <created>Sun, 15 Aug 2010 00:07:05 +0100</created>
    <modified>Sun, 15 Aug 2010 00:07:05 +0100</modified>
    <content format="markdown" src="decentralisedxmlstorage.mdml"/>
    <category>Writing-Development-Flux, Flux</category>
</article>

How to detect changes

In many computer systems a dirty bit is set to signify that modifications have taken place and the cache line should be refreshed. Deleting the cache is a simple solution, forcing the directories to be indexed. This is an appropriate solution for up to 1000 articles. Beyond these scales a more efficient solution would detect filesystem modification times. Is it sensible to trust system time? I would rather not go there.

Major modifications

The decentralisation is a major step towards a class library that can be used by other developers to deliver high quality content in less time. A single file management interface is the final stage before release.

Thanks for reading, please add your comments.

More articles on the next page