Sunday, April 24, 2005

Models, process and Zachman

John Daniels ran an interesting workshop on models and perspectives. I'm pretty familiar with the source material for this, namely Syntropy. However, John went on to talk about how you move from model to model and what the motivation for a model maybe.





Intent/PerspectiveConceptualS/W SpecificiationS/W Implementation
Sketch 123
Blueprint 456
Program 789

We ended up with a table like the one above, where intention is orthogonal to the model perspective. John Daniel proposes that you can characterise a method by the cells it populates either fully or partially. e.g. XP is a 3,9 method or, as someone joked, a 9,9,9,9,9.... method ;-) I thinks this is not only an interesting way of thinking about methods but also a good way to look at enterprise frameworks such as Zachman. If we consider Zachman we can map the rows to perspectives. Columns however are tougher since they indicate content (Who, What, Where, When, How, Why). If we leave intent as it is in the above table we can map content as a 3rd dimension. This gives a cube that can be used to characterise architectural processes. In the cube, each cell can contain partial or complete coverage for 0 or more of the content prescribed in the Zachman columns.

SPA 2005 Note - MDA

Whilst at SPA 2005 I met someone from a previous company I worked at. Apparently they have been using MDA to great effect. They have a UML model of their aspect of the business. This model is annotated with OCL (defined by the analysts). The OCL documents the models constraints[1]. They generate XSD and Java off this model, the XSD defining the structure and the Java expressing the constraints. I'm interested in MDA and its applicability to the company I work at for some time, it was good to note that other practically orientated organisations were starting to use it.

They are using the following tooling (with XML as the export language from the UML modeling tool to the stuff below).

http://lci.cs.ubbcluj.ro/ocle/
http://xmlbeans.apache.org/
----
[1] Convergence - feels like OWL could work as well.

SPA 2005 Note - Outsourcing

The workshop went through the standard set of problems that arise as a result of distributed teams. An interesting split emerged between those who were establishing distributed teams and those who had established teams. The latter were more concerned with maintaining a consistent vision and architecture having got the practices sorted out to some extent.

There was some debate about models for ensuring a standard architecture. Those backed by successful experiences were:

  • Seed team - having a small team produce the load bearing walls and I0 and then move each member of the team to one of the distributed locations to be 'keeper of the flame'. The 'keeper of the flame' then needs to hand off to a local member of the team once the appropriate degree of indoctrination has been performed.

  • Lead team - one development team owns the architecture and there is one chief architect where the authority lies. Expect some international travel.

  • Black boxing - have off shore teams building to a specification, treat them like a 3rd party vendor, don't care about their process or architecture, just make sure the tests pass.

  • Beach head - approx 80% off shore, 20% home base.


There was debate about whether distributed teams should work on the same codebase or whether distributed teams works better in a component based environment. People were using a mixture.

I made the point fairly strongly that the model to be used depends on what is to be built. If it is technological activities such as transformations for integration then Black boxing works. If it's business level functionality then one of the other models is more appropriate. I'm also more in favour of Seed team and Beach head for business apps.

Clearly there is room for guidance here and I believe the work myself and a colleague have been doing in this area may well yield some benefits over the coming year.

Minimalism and signs

In the workshop at SPA 2005 on beauty[1] I was thinking about clarity and minimalism. I value doing something one way. That is, if you are going to introduce a construct, you do it in a consistent manner. I think this is important because someone working on the code is building a model of the system in their mind and consistency helps. If, when they see a certain pattern of implementation, they can always map it to the same intent, they have less to learn than if the same thing is done in different ways in different places in the code.

What is happening (perhaps) is that the code authors are building a shared (and private) language of signs. Since signifiers are somewhat arbitrary and cultural specific it is certain that a team of people will come to the project with different sign systems. To ensure clarity of communication and a shallow learning curve, the team need first to use signs that the team have a shared common understanding of. Secondly, the team have to evolve their own sign system that all buy into. Finally, the authors need to make sure the same signifier is used to represent the same concept throughout the code. When authors don't do this, teams always complain of inconsistency. Worse still, team members may attribute their own concept to the signifier and make incorrect assumptions. This line of thought leads me to think that minimalism and clarity are concerned with creating a system with a minimum set of signs (at some level of abstraction) where one concept is not represented in the code by multiple signifiers. Furthermore, to ensure clarity, the signs should be understood by the team and by the community from which maintainers will be drawn. This in turn infers that the software becomes targetted at a specific design or implementation school of thought.

In conclusion, all things being equal, it makes sense for a team to use a sign they all understand. It maybe that the technology underlying the signified concept is the same, but if the team do not have an understanding of the signifier, confusion and defects await.

ACCU 2005 - Small Memory Patterns

This talk provided 3 patterns from Charles Wier and James Noble's patterns book on programming on small memory machines. The talk covered the following patterns; Memory Limit, Packed Data and Fixed Allocation. They were pretty straightforward:

  • MemoryLimit - limit the allocation of memory and fail requests over that limit. The contacts list in a phone is an example of this. Charles also talked about other strategies such as FIFO and LIFO that are often used to decide whether to accept a request but do so by throwing away an existing allocation.
  • Packed Data - bit packing data.
  • Fixed Allocation - allocating all the memory you need for an operation ahead of time. For example, 911 systems in the US have memory pre-allocated so that a 911 call will not fail due to an out of memory error.

These techniques are commonplace and well recognised. The talk then went on to discuss techniques the audience have used. These ranged from using multiple heaps to avoid heap fragmentation through to using negotiation between devices to ensure there was capacity to honour a request and if not to tell the requestor to ask for less. The summary is a good place to look for outlines of the wide variety of approaches found in the book.

When considering the applicability of this book it's worth noting that small memory systems are not only systems with a small amount of memory (like a watch of a phone) but also systems with large numbers of users where each concurrent request ends up having a small amount of memory.

Whilst listening to this I wondered what a book on patterns for programming in 'low power' environments would look like. A book on low power environments would contain patterns that optimise on clock cycles, that discusses off-loading computation to hardware and would probably be very useful to JavaScript programmers developing in IE. I've been pondering IE JavaScript patterns for a while and it seems like many of the approaches found in embedded systems development[1] have and can be applied to the IE environment. The reason for this is two-fold:

  1. Performance. There are many activities in IE that have unexpected and significant performance hits. The developer spends a lot of time optimising JavaScript web applications in IE when there are reasonable quantities of data on screen.

  2. Memory. IE, its' DOM and associated clutter consumes a substantial amount of memory. Developers have to minimise memory consumption to get a web app to perform.



----
[1] Of course, programming embedded systems now is not dissimilar to programming non-embedded systems 15-20 years ago.

ACCU - C++0x

At certain points in my career I've ended up doing alot of C++. Often I wrote a template code, many times in the generative style. I learnt a few lessons from doing this. Firstly, the error messages are terrible. The key reason for this is that the compiler needs all the code present to ensure that the parameter types passed in to the template support the operations that the template code relies on. Hence, the compiler (effectively) expands the code, and only when deep in the bowels of the template code does it report back 'hey, type T doesn't support T::value_type'. When it does that the error trace is enormous, and without a good understanding of the templated code it can be hard to make sense of the error. The second reason was the hoops you had to jump through to ensure that it was clear what type of T you wanted passed in to a template. This is where traits came in, verbose and clunky, but they did the trick, kind of.

All that is going to change - I'd say 'about to change' but the C++0x standard is now scheduled for 2009. C++0x is introducing some features to address the issues raised above, and others. Stroustrup spoke of these at ACCU 2005. Broadly speaking he targetted two areas. Firstly, auto and declspec relate to querying the type information.

e.g.
int doSomething () { };
auto value = doSomething (); // value is an int.

decltype returns a type, e.g. decltype(doSomething) is an int. Syntatically decltype is considered as a typedef name. This allows easy implementation of generic forwarding:

template <class T> auto forwader (T &t) -> decltype (doSomething(t)) {
return doSomething (t);
}

Secondly there is a lot of work being done on improving the checking when using templates, specifically around traits and a desire to seperate the template code from its definition. The traits idiom has been used in the past to:

  • Provide specialisations based on the characteristics of a type (i.e. it is a forward iterator).
  • Explicitly say 'this implementation only works with types with this characteristic'.

C++0x is introducing concepts. The form is yet to be agreed in detail, though there are a number of design ideas on the table. The general idea is that a concept is a set of predicates that assert facts about the sort of type that would work with a specific template. This means that a developer can say 'this template requires type T support ++, assignment, random access' etc. However, it goes further than this and allows new concept to be introduced to represent abstract notions that are specific to a domain, e.g. 'works for small types' or 'works for large types', where the definition of small and large is in the developers mind.

The code may look like this:

template <typeid X>
concept some_trait {
};
template<class T> someClass where {some_trait<T>} /* class def follows */

The {} after the where clause is a set of predicates requiring specific concepts be supported by the class T. Of course, we have to define how a concept is defined in terms of valid types and operations. This could be like this:

template <typeid X>
concept some_trait {
typename X::iterator;
X operator++(X);
};

So, this means the class argument to someClass must support the increment operator and have a type in its namespace named iterator.

Very useful indeed.

Further information is available on the open-std.org site and at J Siek's publications page.

ACCU - Model Driven Development

The outstanding thing about this talk was Frank Buschmann spending some time discussing the characteristics of the domains in which MDD worked and discussing thoughts about the costs/benefits. It is unusual in my experience to go to a technology talk where the context within which something should be applied is described so well, it made for a great talk. In summary Frank was saying that MDD could be cost effective in domains that had the following characteristics:
+ Closed.
+ Well understood.
+ Undergoing a low rate of change.
+ Had very clear borders, concepts were either in or out of the domain, there were no grey areas.

It looked like the effort required to build the MDD infrastructure (e.g. generators etc) was high and the cost could only be recouped if the infrastructure could be re-applied frequently without incurring more significant cost rev'ing the infrastructure.

Successful examples given related to situations where a product had many different variants that needed generating. These were often drawn from the automobile domain, where software is configured and assembled based on the target car, engine and associated gadgetry (e.g. aircon). Other domains used in the examples included technological areas such as error handling. An interesting side effect of this approach related to coupling. The models had components with low coupling but it was noted the output was often tightly coupled. Since the developers were operating at the model level this tight coupling wasn't important.

It felt like MDD was really tied to product line architectures and not so useful in a service company that works in many different domains and build many different (rather than similar) applications. Having said that, some service companies build a lot of web based CRUD/Workflow apps so there will be mileage there.

As an aside; several conversations were overheard of the form 'generated code isn't elegant, it's useless'. I'm not sure elegance is important. After all, do we care whether the assembler generated by compilers is elegant?. Generated code needs to be efficient, but unless a developer is expected to regularly interact with the generated code (e.g. editing/debugging), it doesn't have to have many other characteristics.

Monday, April 11, 2005

SPA 2005 Resources

Papers and slides

You can find project approaches and case studies at the BJSS website.

Monday, April 04, 2005

Falling Blue - Agnes Martin

Horizontal pencil lines perhaps half an inch apart are drawn to the edges of a border of bare canvas. In between the lines long horizontal strokes of dark blue are painted with a small brush from one side to the other. Each line starts, fades and continues as the brush ran out of paint and was then re-loaded. Whilst the painting exhibits minimalist attributes it hasn't been screen printed or otherwise mechanically produced. Each part has been meticulously painted or drawn. It reminded me of the engineering/craft debate in software. External observers view software as something constructed from hard edged parts. Graphical notations used emphasise the mechnistic nature through hard edge iconography. Compare that with the code itself, where each part has been individually crafted, each line tabbed in and placed in relation to the lines around it. In so many ways software felt like Falling Blue.