Permalink
Switch branches/tags
Nothing to show
Commits on Nov 24, 2010
  1. We can be even clearer if we use Module::PluginFinder.

    This module abstracts away the idiom of searching for a class given
    some predicate. By using this our code is now more readable (it
    reads as clearly as it behaves).
    
    It's slightly odd that we have to pass $data twice, but reading the
    documentation shows that the first argument is the search key, and the
    second are constructor arguments.
    Oliver Charles committed Nov 24, 2010
  2. Now we are ready to remove the list of classes.

    This list of classes is meaning we have 2 places to extend, and this is
    no good. We can generate the list of clasess however, at runtime, by
    using Module::Pluggable. We tell Module::Pluggable to find all Flight::
    clasess, and we call understands and new on each of them.
    Oliver Charles committed Nov 24, 2010
  3. A pattern is emerging in the FlightFactory

    The understands/new pattern seems to be repeating for each subclass,
    so lets factory that out. We store all known classes in an array, and
    iterate over each class. If we find one that can understand the given
    data, then we instantiate. Otherwise, we die - as before.
    Oliver Charles committed Nov 24, 2010
  4. The first problem is that FlightFactory knows to much.

    Our factory doesn't need to know about what creates a specific type
    of flight, this is the responsibility of each Flight. So we move
    this logic to each Flight, and check in the factory with the new
    'understands' class method.
    
    All flights must specify how to understand data, so we require this
    method be implemented in our Flight role.
    Oliver Charles committed Nov 24, 2010
  5. Now we can write the first pass of the factory.

    Here I moved the construction code to a factory, and modified our
    example code to something that can be run. It does every thing we
    want, but it has some maintainence problems...
    Oliver Charles committed Nov 24, 2010
  6. Sketch out what we'd like to do, given our knowledge of input.

    We know the type of input we have available (the parameters for new,
    in this case) and we know what we'd like to do - so we write idealistic
    code. This doesn't run, but it gives us a good idea of what we'd like to
    implement.
    Oliver Charles committed Nov 24, 2010
  7. We begin be sketching out our requirements.

    In this case, we know that we need to have holiday flights and cargo
    flights, so we have created classes for both of them. It would be nice
    to treat them together, so we have a Flight role.
    
    I chose to use a role because it defines an abstraction - not an
    implementation. Of course, it can have methods, but we can never
    instantiate a role. This is perfect for us, and as you'll see later
    is great for specifying requirements on what a Flight is.
    Oliver Charles committed Nov 24, 2010