Archive for the 'Software Design' Category

Understanding PureMVC

I’m writing a bit of code using PureMVC, so I thought I would share this experience – gone all my merry way doing just that.

In this article, I’m covering basic separation principles. Then I’m introducing MVC. I describe PureMVC, explain what it’s about in fairly abstract terms, and try to help you figure out whether it’s worth your while.

If you’ve never seen PureMVC code, I’m afraid you’ll have to look elsewhere (especially if you’re into ‘code makes more sense than theory’).

First things first

MVC is a meta-pattern mainly used in developing applications and application components. MVC separates applications into three tiers: Model, View and Controller. The model is your data, the view represents your widgets or components, and the controller determines  how the model and view affect each other.

Separation

Like with many architectural patterns, separation is essential to MVC. There are many ways into which you might either need or wish to ‘separate’ application tiers:

  • Logistic separation: concurrent tiers may be deployed on different computers.
  • Physical separation: concurrent tiers may be separately bundled – you store the source code for each tier in different folders.
  • Logical separation: concurrent tiers can be compiled independantly from each other.
  • Runtime separation: at runtime, concurrent tiers reside and hold resources in separate areas of memory, and may run asynchronously
  • Socio-Professional separation: different people (or different companies) each write a part of the same application
  • Conceptual separation: concurrent tiers use concepts from different domains
  • Cybernetic separation: there is less communication across tiers than there is within any given application tier.

Depending on where you stand, you may have no choice – for example you may need to keep a database on a server and present information in a web browser – or you may simply wish to keep things separate in some way or other for the sake of clarity.

In the meantime, we’ve already agreed that MVC is mainly for writing applications. This surely implies that application tiers, however separate, need to communicate. It is useful to remember that, although you can achieve absolute separation in some respects (e.g., Physical) you can never (nor should you want to) achieve complete cybernetic or conceptual separation – all components within an application contribute towards the same purpose (business logic) and in order to do so, they will communicate – except to the extent that digital communications are replaced by human communication.

Maybe another, essential consideration is that separation is flexibility at a cost. Such cost will generally include additional design efforts as well as areduction in quality and/or efficiency. Also, you will incur this cost while you are writing and maintaining your application, not just while deciding how components should be separated.

MVC as a Meta-Pattern

MVC is a high level meta-pattern based on a special form of conceptual separation. The idea is that the ‘factual/transactional’ aspects of your application are held on one side, while the ‘visual/interactive’ aspects are held at another side. Another layer (Controller) mediates between the two.

You bet such a high level, conceptual degree of separation would be open to debate and interpretation – how about the age old debate between form and content? For this reason, and because there are least 6 other ways to separate your applications, MVC is not a software  pattern, just a meta-pattern.

This means that you’ll likely run in trouble if you just ‘try to use it’ without a little more design and preparation.

This also means that there are many ways  to define an ‘instance’ of MVC. Such instances include both strategies and frameworks; PureMVC is an MVC framework – on this note, don’t expect PureMVC to resolve all your problems – depending on what you are trying to do, PureMVC will either be supportive, or unsupportive.

What is PureMVC?

PureMVC is two things:

  • A flexible, comprehensive framework ported across several languages.
  • An open source software product, developed, supported and documented and promoted by a company.

From the above, there are immediate consequences:

  1. Flexibility means that PureMVC can be supportive and unsupportive in a variety of ways – Supportive because it can be tailored to some of your needs; unsupportive because not all the design effort involved in defining a framework has been done for you, and you’ll get hurt if you don’t finish the job.
  2. Comprehensive means that PureMVC covers, at framework level, most of the aspects involved in instanciating the MVC meta-pattern. This means that development using PureMVC is less error prone (than if it relied on more conventions) and results in code that often lacks concision and elegance.
  3. Because PureMVC has been designed to be portable, it relies on a low common denominator between several languages. For this reason, it is probably a good investment if you’re navigating between languages and somehow despicable in consideration of facilities offered by specific languages.
  4. Because PureMVC is actively promoted by a profit driven organization, it is hyped and tends to make promises that it doesn’t always fulfill. Business orientation may also be the reason why the PureMVC documentation combines sophisticated, obfuscated terminology with lengthy, uninformative explanations. So far, this may have proved to be a fair marketing choice, because PureMVC seems increasingly successful – which in the end benefits all its users.
  5. Because PureMVC is open source, you can modify it in some ways and make it more suited to your needs if you really have to.

OK, but what is it?

PureMVC is a ’5 tier 3 tier framework with a facade’:

  • Proxies are your model objects.
  • Mediators are your view objects.
  • Commands realise your controller as a collection of short lived, single responsibility classes (first good thing)
  • Components are platform level, view side delegates typically shipping as part of a UI toolkit (Swing, Flash components etc…) and independant from PureMVC.
  • Data objects are… …just data. They are also independant from PureMVC and originate either in your efforts at modelling your business domain or into an API provided by a third party. Data objects are, like proxies, part of your model.
  • The Facade is a kind of registry/communication interface between your model, view and controller.

Proxies, Mediators and Commands communicate in two ways:

  1. Notifications. These are (potentially) heavyweight messages holding untyped content transiting via the facade. Basically you wrap data into an instance of an IMessage interface, pass it to the facade it gets dispatched to other actors in your application. Then you unwrap your message, type content back (if you’re using a typed language) to whatever you expect it originally typed to, and do some processing. I dare hope you’re not thrilled.
  2. Function calls. You retrieve an actor from the facade (any actor) and invoke functions on it. If you’re using a typed language, you can use typed arguments (but you lose logical separation).

Now is a good time to visit the PureMVC website and fetch their pretty diagram.

OK, since you’re back I’ll point out right away that ’5 tier 3 tier’ should arouse suspicion. Let’s get sober and clarify this bit:

  • The model consists in Proxies and Data objects.
  • The view consists in Mediators and Components
  • Commands are mmh… just commands, and realise your controller.

Right, what’s going on here is additional separation, at a cost and with potential benefits. Some of the benefits go to the people that designed the framework; you maybe interested by the remaining benefits:

  • Since PureMVC aims at being comprehensive and portable, it provides interfaces and default implementations for proxies, mediators and commands. Providing default implementations atop existing library components would be difficult or impossible, although developers may do that on a case basis. So 5 tiers allows to provide a product that is more complete and thus appears more attractive.
  • Given that a lot of your  application level code is separated from language/platform/domain specific entities, your application is more portable. This means you can migrate it fairly easily to a different platform – this advantage is (to a limited extent) symmetric with the fact that the framework is easy to port across languages – but then, whereas it  is definitely a strength for the framework (as a product) to easily port across languages, how likely is it that we’ll want to port our application to another platform? How often does this converge with a genuine business concern?
  • It is probably the case that maintaining a level of separation between library/platform and application specific code increases clarity.

What are the benefits of PureMVC?

  • Commands – since I started writing commands, I stopped asking ‘whatever control might be’. Whenever you want an interaction between view and model, you instanciate a command, retrieve view and model actors (or fire notifications at them) and ‘do a job’. Once that is done your command gets garbaged collected. While this last bit, per se, may prohibit your using the framework as is (high rates of garbage collection may kill your application), it warrants that you won’t be holding references to data or view objects for longer than reason, or worse, storing information in controllers and nowhere else, which ‘sort of naturally’ happens if you don’t have commands. Commands also make it very clear, at project browser level, what is being done by your application – kind of silly but commands and IDEs, which aren’t great at presenting information visually and concisely, seem to fare well together.
  • 5 tier 3 tier. If…  (a)you’re writing an application on your own, (b)you know the platform well, (c)you won’t reuse your business model (‘data’), (d)have no intention to use concurrent UI presentations of your data and (e)aren’t planning on porting your application to several languages and platforms, then 5/3 isn’t for you. But as you can see that’s many conditions. 5/3, originally, really put me off. Practically, this currently saves me a lot of time and worry as I’m specifying the ’3 tier core’ (proxies, mediators, commands) of a medium size application, atop a platform I know little, using a language variant I have never used before.
  • Interfaces versus conventions. If you naturally lack discipline, are involved in teamwork and/or cannot enforce weaker conventions mechanically, interfaces warrant integrity at the cost of concision and elegance. This may slow you down (to jogging versus thrashing), irritate you and, overall define a day job versus programming fun. Mind that programming fun today might turn into a nightmare tomorrow.

What are the drawbacks of PureMVC?

  • Untyped notification content. Providing a fully fledged ‘catch-all’ observer pattern implementation comes at a heavy cost. Event specific notification semantics (as provided by listener interfaces) are a nice to have. Typing rules maintainable applications versus wild mandragoras; casting is a pain.
    The boiler plate involved in registering listeners and writing notification interfaces makes me cringe every time, wishing I weren’t using a mainstream object language, and so forth but… I like to implement notification methods that deliver me explicit, typed arguments instead of a single, blackboxed instance. If you’re APIs are customer facing, I’d rather advise you don’t throw these notifications at them.
  • Broadcast messages.  I hear that PureMVC notifications are channelled, but can’t really see the benefits. Increased flexibility versus reduced maintainability is integral to broadcast systems, and whether you want to use broadcast, unicast or a mix of both is a decision that should affect your choice of a framework
  • Asynchronous control. If your application is ‘mostly modeless’ or you can’t afford multi-threading anyway, you’ll have to live with a lot of book-keeping.
    Multi-threaded or not, most UI frameworks nowadays are event driven (enforcing modal controllers against and event driven UI framework is a special skill). The problem isn’t there. The problem is that we tend to store transient data into semi permanent controllers. So yes, commands are safe, but they do require re-thinking control.
  • Singleton facade. Unless you’re writing applications too small to consider feature oriented modularity (not the common case) you’ll have to either (a)unravel the mysteries of Multiton PureMVC or (b)find a workaround (there are some) or (c)experiment with a crowded broadcast messaging context (please don’t).

Is it worth it?

That depends mostly on the professional context you are evolving into, and a little bit on your programming experience:

  • If you’re not doing a lot of team work and can demonstrate some discipline, maybe you just don’t need a framework – especially not a low common denominator framework at the language level. This is because frameworks tend to kill concision and elegance and you can instanciate the MVC meta-pattern using conventions.
  • In my office, we chose PureMVC in part because we felt it would warrant increased code integrity (PureMVC is a framework and we are a 20 strong team with a lot of thrashing and no TDD), in part because we came to like 5/3, and in part because our guys are enthusiastic about the framework – plus it’s fairly popular in our waters, so it’s good for professional development.
  • At home – at OOgtech – I won’t stand lack of concision and elegance. Putting the emphasis on feature separation versus layering is proving to support a very fast development/release cycle, while PureMVC  not only emphasizes layering, but also demotes modularity in its singleton implementation.
  • Let’s face it – writing a separation framework requires expertise, not time or staff resources. The best framework, from a technical point of view, is probably an adaptation of something that already exists. So if you’re not worried about fostering the professional development of your employees and you’re after high productivity versus fads, PureMVC will just be one of several choices – and the best choice may often involve developing your own framework.

Summary

PureMVC is a well structured MVC framework. It boasts a couple of serious advantages – 5/3 tier structure, excellent separation using commands. It may not be the best choice if you’re after a very fast development/release cycle and could have benefited templated, typed notifications versus a catch-all observer pattern implementation.
This framework is commendable for small to large applications involving few modules and many loosely coupled interactions across a small number of interactors.

PureMVC may seduce developers looking for an MVC instance available across several languages and (as a front end developer) may look good on your CV (at least for now). While it may be too heavy for novice developers to learn, it is fairly integer and I would recommend it to developers with prior, untutored experience in instanciating the MVC meta-pattern.

PureMVC / F* Beauty and the Beast Primer

Right. That’s what I’m doing at my job at the moment.

PureMVC can be pretty useful in some cases, although I feel pretty sobre about it. In fact, trying to choose a framework for our next game engine has probably had a knock-on effect eventually leading to my proposing the F* meta-pattern and risking the ee-xml project on it.

You can read about F* on this blog. What you can’t read about yet is that F* seems to be working out pretty well. I derived an architecture from F* (CSFA, for compile safe feature architecture). I’ll explain that later – or sooner if somebody actually asks.

I need to defer explaining in detail a number of good and bad things about PureMVC. Frameworks aren’t really hard to explain – mind, it’s been pointed out to me rightly that the hard question is whether a framework will or will not promote good code in a team environment – but it’s not really something for the 1-2am timezone. Now here’s a few hints if you’re facing the same kind of choices. These hints are pretty general and probably go beyond PureMVC or F*.

  • PureMVC uses commands to realise it’s controller. A command is a disposable, objectified function that can access both model and view. This is by far the most obvious strength about the framework. Rather than desperately trying to keep data and view information out of the controller, we agree that control is volatile, which constrains view and model to integrity while empowering the control layer. But then, you don’t need PureMVC to use commands.
  • PureMVC has deliverables and business support. In other words, it is a product. The deliverables aren’t many and the authors are intent on hyping their work.
  • PureMVC is designed as a ubiquitous, lowest common denominator framework. If you love your language; if you love typing; if you love elegance, then you might not actually like PureMVC. I heard that porting PureMVC apps across languages is a breeze. No wonder. I hope not too many teams face the prospect of switching language halfway a project.
  • Separation can exist at different levels. In particular, separation at compile time doesn’t imply separation at runtime. It is relatively easy to use PureMVC in such a way that you end up with a lot of type-casting (runtime hazards) without actually separating application tiers (in other words, there is sometimes a strong incentive for importing types from one layer to another). You can do a jolly mess with PureMVC. Really.
  • PureMVC uses commands and a heavyweight notification scheme. This makes it extremely verbose. Verbosity means that your code has quite a bit of inertia. Inertia is bad.

This is why I need to take time to analyze and explain what design choices in creating a framework actually entail. PureMVC isn’t bad, but frankly speaking an OTS framework has little chances to be optimal for any given project, and I hope I can explain why.

If you can’t sleep, here’s a powerful mantra:

Type casting is bad.
Type casting is bad.
Type casting is bad.

….zzz

PureMVC notifications in AS3

A little reminder showing how to send notifications and either map them to commands or handlers

Send a notification

facade.sendNotification(Notifications.DO_THIS);

in Notifications, declare and define the DO_THIS constant:

public static const DO_THIS=”DoThis”;

Start a command whenever a notification is issued

To start a command on DO_THIS, bind your command to the notification in CommandMap:

target.registerCommand( Notifications.DO_THIS, DoThisCommand );

Get a proxy or mediator to handle a notification

To handle a notification on DO_THIS:

override public function handleNotification( msg: INotification ):void{
this["on"+msg.getName()]();
}

public function onDoThis(){
// whatever…
}

Retrieve a proxy or mediator (invoke this code from within a Command)

var foo:FooProxy = facade.retrieveProxy(FooProxy.NAME) as FooProxy;

var foo:FooMediator = facade.retrieveMediator(FooMediator.NAME) as FooMediator;

No worries, i’m not dropping you on F*. I’ll explain later…

Component vs. Story Driven Estimating – Scylla and Charybdis

Facts and figures

Using component driven estimating, I under-estimate by a times 4 factor; a proof of concept before contracting doesn’t help.
Using story driven estimating, I over-estimated two iterations by 30%.

Pragma

1. I estimated two iterations using story driven development.
2. I am experimenting with a new framework
3. I am targetting a business domain I know well.
4. I made sure to estimate very small stories on a short event horizon.

Premisses

1. Component models afford and encourage glossing over interactions.
2. Functional models afford glossing over unused components. Logical dependencies constrain functional models to minimally correct component models.

Hypothesis

Story/Case/Interaction/Feature driven estimating is overall more acccurate than component driven estimating.

This post didn’t start off with facts, figures, premisses or a hypothesis. It would appear that stories, broken down into small (<0.5 day) tasks, afford better estimating than component analysis – if you’re in no reading mood, that’s all you need to know. I’m off rambling.

OK. I used to estimate projects using component analysis. This is how it works:

  • Estimate each component as derived from requirements; do not include any correction factor.
  • Sum and multiply by 4.

Recently, I moved to story based estimating – this is what happened:

  • Broke down each story into 3 or 4 tasks. Each story was minimally small, representing an atomic value increment.
  • Estimated each task separately.
  • Summed and applied no correction factor (no prior iteration allowing to evaluate velocity).

It may be worth noting that story breakdowns are highly dependant on prior stories (if you shuffle your stories on the timeline, your story estimates are void, although your task estimates may still be accurate).

What happened?

Plato

My first encounter with object programming was an epiphany. Object modeling promised clarity, simplicity and re-use – so much so that I still find it difficult at times to come to terms with the conceptual overhead involved in teaching object programming versus scripting.

As essential models, objects promise clear, reusable encapsulations. Component driven estimating relies on high level separation and breaks into perspectives. From there, two attractions:

  • Object modeling must be comprehensive. Modelling objects, we are thinking about potential. Uses and interactions far beyond business logic. We are modeling ahead of business goals.
  • Object modeling must be pure. Modelling objects, we can’t afford letting arbitrary considerations taint our models.

I believed in objects long enough not to feel nostalgic. Don’t be fooled:

  • You’re not gonna need it (however many times you will pay for it). However you believe your objects will pass the test of time, comprehensive objects afford more than is required.
    A friend of mine will always order the same dish at every Asian restaurant we go (Thai, Chinese, Indian, … ). Choice means little more than overhead in finding what you really need once your objects enter the maintenance cycle.
  • No services. Platonic models don’t willingly endorse your business logic – If you try to reach the essence of your model, you will neglect your components (contr)actual uses and, like me, will reach meta-stasis, balancingcompleteobjects (just need to fill in the blanks…) against a self-sustainable tasklist (an endless list of use cases)(1)

80/20?

80% of functionality (yes… the 80% your customers won’t need) is provided by objects – Pure, comprehensive models that do not contribute to your business logic. Thinking, modeling and estimating objects, we’re not even covering the 20% functionality that we contracted for. Worse, that 20% will account for 75% of actual development and maintenance time given complex dependencies woven into ‘pure’ representations

Aristotle

Down to Elysian fields, story driven estimating doesn’t suggest we entirely relinquish either objects or component analysis. Accurately, stories require modeling shadows; stories cut across layered architectures, grudgingly yield pragmatic models and hold no romantic promises to posterity. However:

  • Stories require minimal object models. While essential (existentialist?) models do not require stories, stories require actors and props. For this reason, stories outline necessities driven by your business logic.
  • Stories require percolation. Integration is all to stories, while component analysis comes second.

F* places story modeling at the heart of software architecture, but I won’t ascribe a short term incidental success in estimating to experimenting with a new pattern (however superficially relevant).

I’ll write off over-estimating to a long standing habit of pessimism – a stigma of pre-romantic beliefs in hidden essences, quickly glimpsed while designing pure abstractions, quickly lost as contractual requirements take over, driving the patching, deconstruction, scarification and disintegration of domain objects into business logic.

I’ll be linking Scylla and Charybdis when I have a moment (finally, not an obvious choice but could do for a nice read and the imagery is a random treat).

(1)From a neo-platonician perspective, I even find it hard to shake off unease while writing notifications for model objects – but why do object languages like Java not provide modifiers for making states and behaviours observable? Observer patterns are cumbersome combined with strong typing; shouldn’t this stuff be implicit to implementations?.

The F* meta-pattern

F***, I can’t find the code that froggles the wizzles.

If you have ever worked on a delivery team, you know how hard it can be to map the user perspective leading to bugs being raised to actual application code.

Feature architectures emphasize feature separation over layering, and may be especially suitable for front-end development and integration software.

Classic architectures emphasize layering over component separation. A paramount example is the MVC meta-pattern, where applications are divided into model, view and control layers, and a component hierarchy is designed across application layers. MVC has imposed itself in application development – so much so that a colleague recently suggested to me that MVC is no more than a simple warning – don’t shoot yourself in the head; in the meantime, MVC relies on an over-arching principle: separation. In software architecture, separation determines what you can, and cannot do. If MVC is good for writing applications, surely MVC will promote uses that are common to an application product’s life cycle. Granted, let’s review the situation:

  • MVC makes it easy to entirely re-implement a complete layer of your application: you could be re-writing your Swing UI in OpenGL, or re-use your data model using a web front-end. Or even reuse your view and model and create a new product following a different business logic – as encapsulated into your controller.
  • MVC lets you hire specialists to write the separate layers of your application – a GUI wizard may be writing the UI while an XML wizard develops the model.
  • Given an existing model, MVC could help you design new ways of interacting with this model.

Now, here’s a couple of things that an MVC architecture won’t help you with:

  • MVC won’t help you introduce new features in your application – since features typically cut across model, view and control, the more features you add, the more time it takes to integrate scattered elements of functionality within existing application layers.
  • MVC won’t help you fix bugs – while users and testers associate defects to application features – elements of perceived functionality – MVC separation promotes feature obfuscation (feature semantics differ across layers) and require iterating investigations across layers, typically starting from the UI.

I have never met a developer involved in replacing an application layer wholesale; further, while assigning specialists to writing separate application layers may ensure that each layer is well designed, this also increases the chances that layers do not interact correctly and will often lead to over-design and creeping featurism within each application layer – leading to unused potential. Separation? Yes. Layering?

Agile resolves some of the problems associated with layered architectures – in Agile, developers focus on delivering value by completing the user stories that express a customer’s actual needs. Pair programming and pair swapping also ensure that Agile developers are generalizing specialists. While developers still juggle between application layers on a daily basis, communication failures – both socially, within the team, and technically, within the product – are much reduced and bug counts dwindle. Agile teams may even be more able to process change requests reactively and effectively: a generalizing specialist will be able to investigate a solution across layers, where a team of specialists may be involved in investigating a bug or change request, with all the communication overheads that this may entail.

Features, then…

Where MVC stands for model, view and controller, the F* meta-pattern primarily resolves software architecture as a collection of features. In other words, instead of packaging your application using, view model and controller root packages, you create a new package for each feature, and commit to primarily developing each feature using a self contained source bundle. MVC does not forbid identifying features as an after-thought (see [ref]), it just makes it harder; similarly, F* does not specify that you should not separate view, model and controller – it does make it harder, however. Like Test Driven Development, F* represents a significant paradigm shift in the way we model and develop software. In short, F* determines increasingly strong requirements with regard to feature separation:

  1. (The source code for) any given feature should be physically separate from any other feature.
  2. Erasing source for a feature should not result in a broken build or a broken application.
  3. Erasing or disabling a feature should not result in other features (dependents) being disabled unless the dependencies are conceptually integer.
  4. A developer needs not access the source code for a feature in order to integrate with that feature.

Given increasingly stringent requirements, F* boasts increasingly attractive benefits

  1. Developing a new feature requires little knowledge of existing features; further, existing features provide self-contained, integrated examples to any developer learning the code-base; further, developers can work in parallel with little risk of causing merge conflicts or stalling on another developer’s critical path. Surprisingly, we have a methodology suggestively capable of satisfying software managers brooding over Brooke’s Mythical Man Month.
  2. Features are developed better and faster. This will be especially true in an agile environment where developers complete Stories. Often, a single feature will match a unique story and keeping all the code for a story in the same place means that developers are more able to focus on completing the story and less likely to break code implementing another story.
  3. Maintaining existing features requires little analysis. Where all the code for a given feature is gathered within one or a few classes sitting in the same package, debugging and analyzing such code can be achieved in finite time, without the risk of meandering within a large code-base – in contrast, fixing bugs across complex, layered architectures evaluates to systematic investigations that only discipline, tenacity and perseverance can resolve.
  4. Given an appropriate infrastructure, decentralized projects can be conducted with reduced liabilities.
  5. Remote developers can contribute either commercial or non commercial value increments on an ad-hoc basis.

F* prerequisites

F* requires a paradigm shift in the way we develop our code; I am currently experimenting with the development of ee-xml, an open source XML editor. First, let’s cover a couple of prerequisites to developing using F* in front-end development:

  • F* requires a widget library. If this seems contradictory, consider the fact that MVC applications also require GUI libraries. Right or wrong, I tend to perceive the emergence of reusable GUI library components as an avatar of the MVC meta-pattern. I also believe that MVC fails to support application developers in inverse proportion of the size of a software company – the smaller a company, the least likely that company will be to benefit wholesale application layer re-writings. F* does not replace a GUI library, it requires (and benefits from) retrofitting view layer elements within features.
  • F* requires a simple data model encompassing your domain logic. If this seems contradictory, take the case of PureMVC. Value objects typically implement domain logic, while Proxies realise an application’s business logic. F* requires (and benefits from) retrofitting your business logic within features.

For ee-xml, I use the Swing library and an object oriented XML library.

Developing using F*

In a classic, layered architecture, code is designed and written from each component’s point of view. In F*, code is written from the feature’s point of view. To this extent, F*, like procedural programming, is easier to understand than patterns like MVC. Even though, F* is no less object oriented than MVC.

F* is a separation driven architecture. Features are written as self contained bundles of resources; notifications are used to integrate features by enforcing their conceptual dependencies. Here is a recipe for designing a feature:

  1. Consider your feature in isolation – granted that a feature may access shared resources, assume that you have already collected references to such resources. Resources are typically represented as fields within a feature class.
  2. Resolve the interaction entailed by the given feature.
  3. Register to receive notifications. in F*, notifications typically convey references to view and model objects. You receive and generate notifications because you wish to share resources with other features.
  4. Provide code instantiating all resources that your feature needs create.

In a simple example, we have a first feature dedicating to opening an application’s main window; a second feature is tasked with allowing the user to open an auxiliary window from an existing frame. In this case, we will analyze the second feature:

  1. We determine that our feature requires an existing frame and a menu, and will allow the user to select a menu item.
  2. Upon activation of the menu item, we create a new window and issue a notification.
  3. We register for receiving a notification when a new window is created. Discovering which notifications are available, and what these notifications mean, is best done at runtime assuming notification traces, but could also be done statically by referring to the list of available notifications.
  4. Upon receiving a reference to a newly created window, we need to ensure that such window will be equipped with a menu bar, menu and suitable menu item. We then register to receive an event when the menu item is selected.

I have chosen a simple example to clarify our recipe for writing a feature. In a real world context, a feature will typically map a user story and may be more complex. Within the development of ee-xml, opening a file represents a feature. This entails accessing I/O resources as well as creating fairly complex view elements.

Given the above example the typical life cycle of a typical application feature is as follows:

  1. The feature is instantiated by a registry. The registry maintains a list to all currently available features and will, in simple cases, instantiates all features on start-up. At this stage, the feature is neither initialized nor available.
  2. Upon instantiation, a feature registers to receive notifications. In front-end development notifications will often be issued to signal that a UI resource has been made available.
  3. Upon receiving a notification, a feature will initialize. The same feature may initialize several times (in the above example, the feature initializes every time a new window is created). Initialization consists in adding widgets or other UI components to the application and listening to events issued by such components.
  4. Upon processing the event(s) the feature is listening for, the interaction is resolved and further notifications may be issued.

Ready to rock?

Back in 2000, I embarked on a long journey aiming at reducing the loss of momentum associated with layered architectures; I wrote several IDEs, eventually, lifting my limit from managing and maintaining just 50 to 3000 classes or more as a solo developer.

Any growing application entails an increase in physical and logical complexity; the Antegram IDE helped me reduce the perceived complexity of my applications. What Antegram achieves with the user interface, F* promises to achieve using adequate separation, and once again, I’m ready to rock, putting aside natural skepticism.

F* is a meta-pattern; it can be instantiated using several languages and implemented in various ways, following increasingly strict requirements, and providing increasingly strong benefits. I am currently finalising a compile safe F* framework in Java and writing the first open source F* application.

Don’t shoot yourself in the head.

Feature Architectures

How far can we go into the writing of an application without losing momentum?

As an application becomes richer, it typically becomes more complex. There are two aspects to this:

  • Logical complexity increases as a result of new functionality binding to existing functionality.
  • Physical complexity increases as a result of increased application size.

The result of increasing complexity is that developers find it increasingly challenging to add new features to an application. This complexity manifests itself in two ways:

  1. Your workspace is increasingly cluttered with irrelevant entities – entities that do not contribute to the feature you are developing
  2. Your code is increasingly dependant on existing elements of functionality.

Very large applications are typically broken down into modules. Modules reduce logical complexity by providing narrowing interfaces; physical complexity is reduced by keeping all the code for a given module separate from the code for other modules.

Feature architectures enforce micro-modularity:

  • Each feature typically maps a single value increment or story.
  • Features are abstracted from each other using channeled notifications.

Why design feature architectures?

Feature architectures are derived from story driven development. In agile, story driven development, developers collaborate towards the development of a given story cutting across the layers of a selected framework. Agile ensures that developers deliver value faster; in suitable contexts (assuming that value can be delivered incrementally), this maximises profitability while reducing the risk to produce large amounts of unused functionality.

Feature architectures take advantage of the separation between source spaces and runtime spaces to allow developing well formed (layered) runtime architectures while limiting linearly growing physical and logical complexity. This allows developers to focus on delivering atomic value increments without incurring mounting familiarization costs and splitting development across framework layers. Also, this may allow fairly large developer teams to collaborate without facing large communication costs.

In a nutshell, feature architectures and micro-modularity target value driven separation. In contrast, existing separation strategies and meta-patterns provide abstract roles that can be re-instantiated in a variety of contexts (the MVC meta-pattern is an example). This affords industry endorsement for high level design solutions. Beyond, classic separation models emphasize a component drive approach. While this means that component cores can be developed in parallel, this may result in glossing over communication interfaces between components.

Layered, component oriented architectures emphasize potential and structural integrity and are more suitable for long term investments and library development. Feature architectures emphasize value increments and may be ideal for writing application front ends:

  • Reusable data and view components are already available
  • Applications are feature rich, yet do not involve much complex code.
  • Value increments typically involve cutting across layered architectures.

Working using a feature architecture

Feature architectures require developers to package features separately. Each feature is developed as an integrated micro-module – if you are writing an application, a feature will probably bundle view, model and controller functionality.

  1. Each developer or pair are responsible for designing and implementing a feature derived from a user story.
  2. The core functionality involved in developing a feature is developed independently from other features.
  3. The source code related to a given feature is bundled within a separate package.
  4. Developers integrate their feature by implementing handlers for channeled notifications.
  5. Developers expose required resources by providing external notifications.
  6. All source code for a given feature may be removed without causing the application to break at compile time.

Mmh… this may not be the best introduction to feature architectures I could write. I’ll try to improve on that and will also provide an application template very soon.



Follow

Get every new post delivered to your Inbox.