www.BrettDaniel.com

New Bass

I bought a bass guitar and it is awesome.

It is an Ibanez SR506. This model has six strings (an extra high and low string in addition to the normal four), a beautiful mahogany body, active electronics, and the most comfortable neck I have ever felt on a bass.

I started thinking about getting a bass after playing Josh's several times. He and I have been jamming about every other weekend with a drummer named Jason. Josh writes the songs and plays rhythm guitar; I play lead guitar and bass; and Jason plays bongos. We are still debating what to do about real drums and a singer. Bongos cannot replace a full drum set, and the singer we had— an opera major, no less— recently moved away. We have a good number of songs but definitely need to practice more before we move from the apartment to live shows.

I will always have my solo music whether I am in a band or not. That is the main reason I bought a bass. I can now record my bass tracks rather than having to write them out note-by-note to be played by my MIDI synthesizer. Tonight I threw together three short samples:

To record the bass, I upgraded my POD to include the bass expansion pack. The installation was interesting. I had to download a client program that ran on my computer and communicated with the POD via a USB cable. After I paid for the expansion pack, the client program downloaded the firmware from Line6's website and installed it on the POD. The bass amp models included in the expansion sound great, and I like being able to record both bass and guitar through one device, but I had to debate long and hard whether to spend a good chunk of money on what amounts to a software update. Unlike a physical console, I cannot resell the expansion if I decide to upgrade in the future.

Between the new equipment and the band, I expect I will have more music to post in the future.

Note: This is the second new purchase post in a week. One could almost get the impression that my grad student salary is more generous than it really is. I assure you that this is not the case.

New Desk

I briefly mentioned the small desk that came with my apartment. It did not take long for me to realize that it would not work for the several years I would expect to use it. The following terrible pictures captured from a video I sent to Dad and Sue when I moved in will illustrate the problems:

  • I had to remove the annoying shelves over the desk so my monitors would fit.
  • It had barely any space for my keyboard, much less paperwork.
  • I used my filing cabinet to make space for the mouse, but the metal would periodically interfere with the wireless signal.
  • It was crammed in the space between the wall and my bed.
  • It had no storage space to speak of.

I seriously considered building a loft with an attached desk. I drew beautiful scale diagrams and went home one weekend expecting to build it. After poring over the plans and much discussion, Dad and Sue convinced me to instead use a drafting table we had stored in the basement. They also suggested moving my "office" to the living room where I have more space. I am glad they were so persuasive because it was an excellent setup (and my bed got to remain on the floor).

But it still felt like a temporary solution.

During the discussion that weekend, Sue proposed that I take her large executive desk because, as she said, "it is a real piece of furniture that would look good in your living room." I felt the drawing table was a better choice, but her idea got me thinking about a "real piece of furniture". Over the next few weeks I casually browsed some of the online office furniture retailers.

I eventually found The Desk. It was large (66"x30"), it looked superb, and the price was excellent.

I ordered it several weeks ago, and it arrived on Monday in two 100-plus-pound packages. With the promise of beer, I recruited Josh, a friend in the human-computer interaction group, to help me carry them up the stairs to my apartment. I started assembly on Tuesday.

First I had to unpack everything.

The top and sides came together pretty quickly.

Next, I had to put together the main body and supports.

The connectors that held the boards together were pretty interesting. Here are some videos that show how two of them work:

I also thought the drawer joinery was very ingenious. The sides had an angled tongue that would lock into place when perpendicular to the front. The other end of the side slid into a T-shaped groove on the back. The bottom slid into another groove and was held in place by plastic clips and nails. [Pat. #6413007]

I felt like an assembly-line worker while putting together the drawers.

After screwing in the final drawer handle, I was ready to take apart the drafting table to make room for its replacement. Fortunately, the drafting table packs up nicely.

It took some straining to turn the desk over and slide it into place. Yesterday I reconnected all the computer equipment, and now I have a large, well-lit, good looking, and enjoyable workspace.

Software Shakespeare?

In yesterday's software engineering class, Professor Johnson, three other students, and I put on a play that illustrated several of the patterns described in chapter 14 of Domain-Driven Design. Not only was the play an interesting break from normal lectures, but it also illustrated especially well how the software implementation and business organization affect each other.

Professor Johnson played the software analyst who was trying to track down some problems in a large shipping application. Each student played a group leader responsible for a module in the system. I played the group leader responsible for the work order module. In each scene, Professor Johnson would "interview" the group leaders, asking how their modules worked and how they related to the rest of the system. The following lists the patterns described in the book and how they appeared in the play's software system.

Continuous Integration
In which all programmers within a software unit— or "bounded context", to use the book's terminology— work very closely to combine code and tests frequently during development. This pattern describes the approach used by all the teams in the play to some extent, but the team whose software had an extensive unit test suite and a well-defined bounded context exhibited continuous integration most strongly.
Shared Kernel
In which two or more bounded contexts rely on a core set of components. The two teams whose bounded contexts overlapped would have benefited greatly from following this pattern. Instead, they shared objects in an ad-hoc manner, which caused problems elsewhere in the system. Here, a change to the software organization would have probably prompted a corresponding change in the business organization.
Anticorruption Layer
In which a bounded context has an isolated layer that adapts an external bounded context to the domain model. Several teams exhibited this pattern. It naturally extends the Adapter and Façade design patterns from objects to architectures.
Customer/Supplier Development
In which a "downstream" bounded context in the customer role depends on the "upstream" bounded context in the supplier role and in which the supplier takes the customer's needs into account. In the play, one of the group leaders expressed disappointment that his team's change requests took a very long time for another group to implement. In this case, it would have been beneficial to formalize the business relationship to echo the customer/supplier relationship present in the software.
Conformist
In which one bounded context is completely dependent on and has little affect on another's implementation. The team whose software depended heavily on several external APIs exhibited this pattern.
Separate Ways
In which two bounded contexts are completely independent of one another. This pattern was not exhibited explicitly in the play, probably because it was exploring a highly-connected application. However, one can easily see the parallels between a business unit and software module. Certainly two business units with no interaction whatsoever cannot build software systems that depend on each other.

Like the extensive examples in the book, the play illustrated very well how software organization and business organization affect each other. The problems found in the software described in the play were largely due to problems present in the business organization. One team was making changes that conflicted with another team's assumptions about the domain model. Communication problems prevented the conflict from becoming explicit.

Domain-Driven Design

Note: I started writing this entry about a week and a half ago, but did not have a chance to finish and post it until today.

Last week I started reading Domain-Driven Design for my software engineering course. The book discusses common patterns that appear when designing and implementing domain models. Like other patterns books, it does not present any mindblowing new ideas, but instead catalogs common problems and their widely-accepted solutions.

Eric Evans, DDD's author, begins the first chapter by describing a very familiar process: he meets with the client's domain experts and based on their description of the problem, starts drawing boxes and arrows on a whiteboard. After several meetings and many revisions, a domain model starts to emerge. Evans calls this "knowledge crunching" and defines it as follows:

[Domain modelers] take a torrent of information and probe for the relevant trickle. They try one organizing idea after another, searching for the simple view that makes sense of the mass. Many models are tried and rejected or transformed. Success comes in an emerging set of abstract concepts that makes sense of all the detail. This distillation is a rigorous expression of the particular knowledge that has been found most relevant.

I have drawn all sorts of box-and-line diagrams on dozens of whiteboards, but one particular knowledge crunching session sticks in my mind. I was meeting with a domain expert early one workday. I knew very little about the area we needed to discuss, and he knew only how he wanted the user interface of the application to behave. Neither of us had a domain model in mind. After some discussion, I started drawing the UI screens on the whiteboard. The links between the boxes became user actions. With a handful of screens on the board, we were able to "find the nouns" that helped define the functional units of the domain model.

Part two of the book (chapters four through six) discuss the organization of the domain model. It seems that every programmer has his or her pet idea of what a "layered architecture" contains, and Eric Evans is no different. He has the "infrastructure layer" at the bottom, followed by the "domain layer", "application layer", and user interface. Most descriptions leave out the application layer, but it makes sense when one considers it the code used to drive the UI. That is, layers like the .NET code-behind or the Java code used to drive JSP pages.

When the application layer is too thick—that is, when it contains logic that should belong in the domain layer—it could become what Evans calls a "smart UI". This common anti-pattern is the UI analog of the transaction scripts mentioned in SAIP. I found it interesting that Evans emphasized that the Smart UI may be a valid design strategy for simple, one-off systems that do not need to scale. Evans seems to consider that a smart UI is the exclusive opposite of domain model-driven application. However, many real-world applications lie between the two extremes. It is possible—but obviously not ideal—to have a layered architecture in which a large chunk of domain logic has leaked into the application layer and UI. In this case, much of the development effort should focus on moving domain logic "down" into the appropriate domain objects.

The remainder of the section lists patterns used to organize the domain model. To me it read like a taxonomy of the types of objects that appear in a business system. I will not re-list all the patterns here, but there were some similarities to this short object taxonomy that I came across several months ago.

Hedgehogs and Fish

Yesterday night I put together my first complete new song in ages. I call it "Hedgehogs and Fish" because that is what came to mind when I saved the MP3. The song is all guitar except for the drum track. It is very laidback with an interesting chord progression. Enjoy.

Download "Hedgehogs and Fish" MP3

Architectural Mismatch

My software engineering class finished SAIP last week. In this post, I would like to explore some of the ideas presented in the second-to-last chapter entitled "Building Systems from Off-the-Shelf Components".

The chapter leaves the word "component" very loosely defined. In my mind, a component is a self-contained unit of reuse that provides functionality for a specific task. Contrast this to a general-purpose framework such as the Java Platform or the .NET Class Library that provides a great deal of fine-grain functionality in many areas. One would not include either of these as a "component" of a larger system, but they can be used to create components such as a PDF document creator, a custom network interface, or a GUI control, to name a few examples.

The chapter provides some very idealistic (read: unrealistic) methods for determining whether a component satisfies an application's requirements. The short answer to this question is "probably not". The book says, "components that were not developed internally for your system may not meet all of your requirements." (Empasis theirs) This echoes some of what I wrote in my previous post regarding why product line component reuse works well. I agree with Professor Johnson that the only way to know for sure if a component will work in a system is to actually use it in the system.

The chapter also very briefly discusses some strategies for combating this "architectural mismatch". The strategies the book lists are confusing and not particularly useful, so I will generalize the problem of architectural mismatch to the following list:

How to Write Good Software with Bad Components

Code for Replacement

As Professor Johnson said in class, "If you use a component… be prepared to get rid of it." The most common way to achieve this goal is to encapsulate a component in a custom interface. The component can be swapped out, but a well-designed interface can remain constant. Design Patterns calls this the "Adapter" pattern; SAIP calls it a "Wrapper".

Convert input and output

The data a component expects is almost always different from what a target architecture uses. In this case it is common to write converters as standalone modules or in conjunction with an adapter.

Use Multiple Components

If a particular component is missing functionality, it may be possible to find another component that provides it. In this case, one may want to use the Façade pattern to provide a simple interface to the set of components.

Expect the Component to Break

It is usually very difficult to determine the failure points of an OTS component. This is especially true for closed-source components or those with spotty documentation. It is also very difficult to rigorously test a component without having written it from the ground up. For these reasons, it is often a good idea to expect a component to break and provide a general mechanism with which to recover from a component failure.

Allow Omission

It may be possible to omit a component in certain circumstances. In this case, it makes sense to provide a means of removing components through some type of plug-in architecture, configuration setting, or conditional build. By removing a component completely, it can no longer be a possible point of failure.

Rewrite the component

Finally, if all other strategies fail, one may be left with no choice but to rewrite all or part of a component. This is often a valid choice since the true cost of using a component is always much much higher than its price tag. A component always has high learning cost, a higher chance of failure, and high integration cost. This is why companies are often willing to expend many man-hours writing a component that can be bought for a few hundred dollars.

I wrote this list off the top of my head, so please feel free to add your thoughts in the comments. I hope to get a chance to read some of the books that Professor Johnson mentioned dealing specifically with architectural mismatch. Component-based development is a common and increasingly important aspect of software development. Since bad components are also unfortunately common, I think tactics for combating architectural mismatch are a vital part of a programmer’s toolbox.