<< Chapter < Page Chapter >> Page >

" Frameworks thus emphasizes design reuse over code resuse...Reuse on this level leads to an inversion of control between the application and the software on which it's based. When you use a toolkit (or a conventional subroutine library software for that matter), you write the main body of the application and call the code you want to reuse. When you use a framework, you reuse the main body and write the code it calls.... "

The linear recursive structure ( IList ) coupled with the visitors as shown in the above is one of the simplest, non-trivial, and practical examples of frameworks.  It has the characteristic of "inversion of control" described in the quote. It illustrates the so-called Hollywood Programming Principle: Don't call me, I will call you. Imagine the IList union sitting in a library. 

The above list framework dictates the design of all algorithms operating on the list structure:

  • All algorithms must be some concrete implementation of IListAlgo .
    • Algorithms that require the construction of empty and/or non-empty lists, must do so via some abstract list factory, IListFactory .
  • In order to apply an algorithm to a list, one must ask a list to "execute" that algorithm, giving it the required input parameter.

When we write an algorithm on an IList  in conformance with its visitor interface, we are writing code for the IList to call and not the other way around. By adhering to the IList framework's protocol, all algorithms on the IList can be developed much more quickly. And because they all have similar structures, they are much easier to "maintain". The IList  framework puts polymorphism to use in a very effective (and elegant!) way to reduce flow control and code complexity.

We do not know anything about how the above list framework is implemented, yet we have been able to write quite a few algorithms and test them for correctness.   In order to obtain concrete lists and test an algorithm, we call on a concrete IListFactory , called CompositeListFactory , to manufacture empty and non-empty lists.  We do not know how this factory creates those list objects, but we trust that it does the right thing and produces the appropriate list objects for us to use.  And so far, it seems like it's doing its job, giving us all the lists we need.  

 

5. bootstrapping along

Let's take a look back at what we've done with a list so far:

  1. Created an invariant list interface with two variant concrete subclasses (Composite pattern) where any algorithms on the list where implemented as methods of the interface and subclasses (Interpreter pattern)
  2. Extracted the variant algorithms as visitors leaving behind an invariant "execute" method. Accessor methods for first and rest installed. The entire list structure now becomes invariant.
  3. Abstracted the creation of a list into an invariant factory interface with variant concrete subclass factories.
  4. Separated the list framework into an invariant hierarchy of interfaces and a variant implementation which was hidden inside of a variant factory class.

Is there something systematic going on here?

Notice that at every stage in our development of our current list framework, we have applied the same abstraction principles to the then current system to advance it to the next stage. Specifically, we have identified and separated the variant and invariant pieces of the system and defined abstract representations whenever needed.

This really tells us about some general characteristics of software development:

  • Software development is an iterative process. You never get the right answer the first time and you have to slowly "evolve" your code closer and closer to what you want.
  • Every time you change your code you learn something more and/or new about your system and/or problem. This is because every new formulation of your solution represents a new way, a new view as it were, on the problem and this new view highlights aspects you hadn't considered before.
  • The revision process is driven along by a repetitive application of the abstract decomposition techniques such as separating the variant and invariant.

Are we done with our list refinements? Will we ever be "done"? What do the above characteristics say about the way we should approach software development?

Also, now that we have managed to abstract structure, behavior and construction, is there anything left to abstract? Or is there one more piece to our abstraction puzzle (at least)?

Get Jobilize Job Search Mobile App in your pocket Now!

Get it on Google Play Download on the App Store Now




Source:  OpenStax, Principles of object-oriented programming. OpenStax CNX. May 10, 2013 Download for free at http://legacy.cnx.org/content/col10213/1.37
Google Play and the Google Play logo are trademarks of Google Inc.

Notification Switch

Would you like to follow the 'Principles of object-oriented programming' conversation and receive update notifications?

Ask