2009

July

    Maintainability/Changeability of a Software System

    Parnas writes:

    Programs like people, get old. We can't prevent aging, but we can understand its causes, take steps to limit its effects, temporarily reverse some of the damage it has caused, and prepare for the day when the software is no longer viable.

    He then lists two reasons why software ages:

    • Lack of movement: software ages if it is not frequently updated.
    • Ignorant surgery: Changes made by people who do not understand the original design gradually destroy the architecture.

    I think one of the things that I have noticed that caused decay in a software systems that I have seen was ignorant surgery. I have witnessed this and it can be incredibly frustrating. When you hire extremely talented people to develop the first release of a product then hand it off to maintenance developers who are not of the same skill set, the project is likely to deteriorate, no matter how excellent the original architecture was.

    It's frustrating when I look at a project that had solid roots and was developed extremely well, now covered in weeds and broken windows. Most of the work is done in the weeds and makes it incredibly hard to lay new foundation without pulling out all the weeds first.

    Sourced from Pattern Oriented Software Architecture: On Patterns and Pattern Languages

    A few months ago I finished reading Pattern Oriented Software Architecture Volume 1. This was an absolutely awesome book. Just about all the patterns in the book target stateful applications, which was just what I was looking for. Some of my favorite patterns were "Pipes and Filters", "Proxy", and "Command Processor".

    The book starts off with a great discussion on what a pattern is, what makes a pattern, and why they are useful. Then it goes through a catalog of patterns and offers examples for each. Then it goes on to discuss pattern systems, the patterns community and where patterns are going.

    Proxy

    The book broke down the proxy pattern in to several different types of proxies. They are:

    • Remote Proxy: Clients of remote components should be sheilded from network addresses and inter-process communication protocols.
    • Protection Proxy: Components must be protected from unauthorized access.
    • Cache Proxy: Multiple local clients can share results from remote components.
    • Synchronization Proxy: Multiple simultaneous accesses to a component must be synchronized.
    • Counting Proxy: Accidental deletion of components must be prevented or usage statistics collected.
    • Virtual Proxy: Processing or loading a component is costly, while partial information about the component may be sufficient.
    • Firewall Proxy: Local clients should be protected from the outside world.

    In the .NET realm the Castle Dynamic Proxy project makes it pretty darn easy to implement some of the different types of pattern proxies.

    The book described 2 major liabilities of the Proxy pattern. It is less efficient due to the indirection, and it can be overkill. Although the proxy pattern is very much like the decorator pattern the major difference between the two is their intent. The decorator adds functionality, and the proxy frees the original from very specific housekeeping code.

    Command Processor

    Separates the request for a services from its execution. A command processor component manages requests as separate objects, schedules their execution, and provides additional services such as the storing of request objects for later undo.

    Let's take a look at an asynchronous command processor that I wrote quite some time ago. AsynchronousCommandProcessor

    The way it works is that one thread is placing commands to execute in to a queue, and another thread is processing the commands waiting on the queue. This is useful for keeping the user interface thread responsive, and allows for scheduling long running background tasks.

    To see an example of an application using this technique check out my Mo Money application.

    If you develop Windows Forms or WPF based applications than I highly recommend that you pick up this book. It is excellent!

April

    I'm still surprised by just how many people still aren't using ReSharper. It's an amazing productivity adding for Microsoft Visual Studio.  Once you've spent the time learning a few keyboard shortcuts you will not go back to naked studio.

    There are few things that are more frustrating then jumping on a machine that doesn't have ReSharper installed, then trying to edit some .cs files.

    In an effort to prevent myself from ever having to jump on a pc that's still missing the glory of ReSharper, I decided to throw together a quick screen cast showcasing some of the features i enjoy.

    ReSharper Warm Fuzzies Screen cast

    If you haven't already. please, please give it a try (do it for me). It's a good addiction!

March

    I recently finished reading.

    Deploying .NET Applications: Learning MSBuild and ClickOnce (Expert's Voice in .Net)

    I was interested in this book mainly to find an easier way to deploy ClickOnce applications via an automated build. Most of my build automation experience has been with Nant, so I figured learning MSBuild couldn't hurt.

    This book targets the Visual Studio 2005 time frame, so some of the things that it describes is out dated, mainly in regards to ClickCnce.

    There was a little coverage on mage.exe but not as much as I had liked. If you're looking for a book to get you into the world of Clickonce or MSBuild, this one's pretty good!

    Here are some of the things that I learned straight from the book.

    MSBuild

    Microsoft.Build.Framework and Microsoft.Build.Utilities contains some stuff to help you with your builds. There's an ITask interface and a Task base class that you can implement if you want to run some custom tasks from MSBuild.

    ClickOnce is driven by two XML-based manifest files called the deployment manifest and the application manifest.

    • Deployment manifest (.application) contains information specific to the deployment of the system.
    • Application manifest (.manifest) captures information specific to version of the system.

    ClickOnce Deployment

    The ClickOnce technology also has a programmatic interface that you can use to customize deployment and updates. For example, if you have a plug-in where the core of the application is deployed initially and then users are allowed to choose optional features (plug-ins) and have them installed on demand, the ClickOnce API can help.

    ClickOnce applications have to be deployed to a Web server, to a file server, and/or to removable media (such as CD/DVD). Moreover, you can deploy these applications in one of two modes: offline or online.

    For applications that require finer-grained control over doing updates, application authors can use the ClickOnce APIs to customize installation and updates.

    Code Access Security (CAS)

    • Permission: The authority to do something.
    • Permission set: A grouping of arbitrary permissions.
    • Origin based Evidence: Where your code comes from determines what permissions your code gets.
    • Content base evidence: Your code content is signed and has a publisher certificate, and that determines what permissions you get.
    • Code Group: Associates evidence with a permission set
    • Security Policy: Policies define a hierarchy of code groups.

    On-Demand Download

    ClickOnce offers a facility that called on-demand download. The idea is that you create groups of files and then use the ClickOnce APIs to download each group at runtime. The initial download is reduced to what is needs to be downloaded to run the application, and if a piece of functionality is not needed, it is not downloaded.

    You can get the path to the Data directory via:

    • AppDomain.CurrentDomain.GetData("DataDirectory");
    • ApplicationDeployment.CurrentDeployment.DataDirectory;
    • Application.LocalUserAppDataPath;

    In an attempt to further understand BDD, I chose to revise the code from my previous post after receiving some amazing advice from two people I regard highly (Scott & JP). I should state that this is my interpretation of that advice. This may or may not be the direction they were trying to guide me towards.

      public class when_prompted_to_save_changes_to_the_project : concerns_for<SaveChangesView>    
      {    
        context c = () => 
        { 
          presenter = an<ISaveChangesPresenter>(); 
        };    
    
        after_the_sut_has_been_created after = () =>    
        {    
            save_changes_window = sut;    
            save_changes_window.attach_to(presenter);    
        };    
         
        protected static ISaveChangesPresenter presenter;    
        protected static SaveChangesView save_changes_window;    
      }    
         
      public class when_the_save_button_is_pressed : when_prompted_to_save_changes_to_the_project    
      {    
        it should_save_the_current_project = () => 
        {
          presenter.was_told_to(x => x.save());    
        };
         
        because b = () => 
        {
          save_changes_window.save_button.control_is(x => x.OnClick( new  EventArgs()));    
        };
      }    
         
      public class when_the_cancel_button_is_pressed : when_prompted_to_save_changes_to_the_project    
      {    
        it should_not_continue_processing_the_previous_action = () => 
        {
          presenter.was_told_to(x => x.cancel());    
        };
         
        because b = () => 
        {
          save_changes_window.cancel_button.control_is(x => x.OnClick( new  EventArgs()));    
        };
      }    
         
      public class when_the_do_not_save_button_is_pressed : when_prompted_to_save_changes_to_the_project    
      {    
        it should_not_save_the_project = () => 
        {
          presenter.was_told_to(x => x.dont_save());    
        };
         
        because b = () => 
        {
          save_changes_window.do_not_save_button.control_is(x => x.OnClick( new  EventArgs()));    
        };
      }
    

    I hope this is slightly more soluble, then my previous post.

    In the last couple of weeks I had a chance to sprinkle some of JP's syntactic sugar, all over my projects. It's amazing how much more concise my units test have become. I've had a couple of issues where I was mocking out the behavior of some Win Forms controls, but for the most part it's been an awesome experience!

    I just wanted to take a moment to say Thank you JP! I am enjoying using your BDD (on steroids) extensions. If you haven't already you need to check it out here. NOW!

    Maaad, maaaad props Mr. JP!

       
    
      public class behaves_like_save_changes_view_bound_to_presenter : concerns_for<SaveChangesView>    
      {    
        context c = () => { presenter = an<ISaveChangesPresenter>(); };    
        because b = () => sut.attach_to(presenter);    
    
        static protected ISaveChangesPresenter presenter;    
      }    
        
      public class when_the_save_button_is_clicked : behaves_like_save_changes_view_bound_to_presenter    
      {
        it should_forward_the_call_to_the_presenter = () => presenter.was_told_to(x => x.save());    
    
        because b = () => EventTrigger.trigger_event<Events.ControlEvents>( new EventArgs()), sut.ux_save_button);
      }
        
      public class when_the_cancel_button_is_clicked : behaves_like_save_changes_view_bound_to_presenter    
      {    
        it should_forward_the_call_to_the_presenter = () => presenter.was_told_to(x => x.cancel());
    
        because b = () => EventTrigger.trigger_event<Events.ControlEvents>(x => x.OnClick(new EventArgs()),sut.ux_cancel_button);    
      }    
    
      public class when_the_do_not_save_button_is_clicked : behaves_like_save_changes_view_bound_to_presenter    
      {
        it should_forward_the_call_to_the_presenter = () => presenter.was_told_to(x => x.dont_save());
    
        because b = () => EventTrigger.trigger_event<Events.ControlEvents>( x => x.OnClick(new EventArgs()), sut.ux_do_not_save_button );
      }
    

    I recently finished reading...

    Data-Driven Services with Silverlight 2

    I have been wanting to get in to the world of WCF for some time now, but wasn't really sure how to get started. This book was good at explaining how to get into WCF quick and easy. The sample apps that the author goes through and provides are pretty cool which makes it more fun.

    The book explains how data binding in silverlight (which seems to be similar to how it works in WPF), how to pass objects across the wire using WCF. It explains what RESTful services means, and how to build them leveraging tools on the .NET stack.

    The sample apps include one that consumes Amazon's RESTful services, as well as a Twitter client called SilverTwit. There's lots of code to dig through, and try out for yourself.

    For anyone interesting in Silverlight or WCF, this is a good book to get you started.

    If you're looking for the sample code that comes with the book, you can find it here. http://examples.oreilly.com/9780596523091/

    I recently finished reading...

    Introducing NLP: Psychological Skills for Understanding and Influencing People

    I first heard about Neuro-linguistic programming (NLP) while I was reading The Game: Penetrating the Secret Society of Pickup Artists. I thought that it sounded like an interesting subject, because I spend a good deal of my time dealing with people and trying to learn new things. If you're interested in trying to become a better communicator or you are interested in trying to find out what your preferred way of learning is, this book will probably help!

    Below are some of the things that I learned straight from the book.

    The Four Stages of Learning

    1. Unconscious Incompetence
    2. Conscious Incompetence
    3. Conscious Competence
    4. Unconscious Competence

    If you always do what you've always done, you'll always get what you've got. If what you are doing is not working, do something else.

    Communication is so much more than the words we say. These form only a small part of our expressiveness as human beings. Research shows that in a presentation before a group of people, 55 per cent of the impact is determined by your body language - posture, gestures and eye contact - 38 per cent by your tone of voice, and only 7 per cent by the content of your presentation.

    We move our eyes in different directions in a systematic way depending on how we are thinking. Neurological studies have shown that eye movement both laterally and vertically seem to be associated with activating different parts of the brain.

    Movements and gestures will also tell you how a person is thinking. Many people will point to the sense organ that they are using internally: they will point to their ears while listening to sounds inside their head, point to the yes if visualizing, or to the abdomen if they are feeling something strongly. These signs will not tell you what a person is thinking about, only how he or she is thinking it. This is body language at a much more refined and subtle level than it is normally interpreted.

    Beliefs can be a matter of choice. You can drop beliefs that limit you and build beliefs that will make your life more fun and more successful. Positive beliefs allow you to find out what could be true and how capable you are. They are permissions to explore and play in the world of possibility.

    Towards people are energized by goals and rewards. Away people are motivated to avoid problems and punishment. Arguing which is best in general is futile.

    It is easy to recognize this pattern from a person's language. Does she talk about what she wants, achieves or gains? Or does she tell you about the situation she wants to avoid and the problems to steer clear of? Towards people are best employed in goal-getting. Away from people are excellent at finding errors and work well in a job like quality control. Art critics usually have a strong away orientation as many a performing artist can testify!

    A good teacher will be able to create an environment, so her students learn for themselves how to get the results.

    Learning to learn is the most important skill in education, and needs to be taught from reception class onwards. The educational system concentrates mostly on what is taught, the curriculum and omits the learning process. This has two consequences. First, many students have difficulty picking up the information. Secondly, even if they do learn it, it has little meaning for them, because it has been taken out of context.

February

    I recently finished reading...

    Object Thinking by David West

    As usual I fold down pages that contain paragraphs that interest me... below are a few excerpts from the book that I enjoyed!

    "Better people" has been recognized as the most promising silver bullet for addressing the software crisis, and yet almost all of our energy has been spent on creating better tools, methods, and processes instead of better people?

    Imagine what a team of "better people" can accomplish. Now stop imaging, and start investing in fostering cultures that cultivate "better people" all working towards the same goal.

    An unspoken but just as widely held belief that really good developers were not to be trusted - they could not be "managed", they all seemed to be "flaky" to some degree, and they did not exhibit the loyalty to company and paycheck of "normal" employees. Really "good" developers tended to be "artists", and are was (is) not a good word in the context of software development.

    Those flaky artist types... *sigh* It's important to allow individuals do what they are good at, that's obviously something they like to do. It breeds innovation, and efficiency. When working in a team it's important to be respectful of one another's opinions and work together.

    Every once in a while someone on the team will have a crazy idea that just might slash the complexity of the whole system. If they have courage, they'll try it out. It will work (sometimes).

    It's important to have courage on any team. XP teams value courage. Without the courage to grow and challenge one another, your team will remain stagnant. By challenging one another you're showing one another respect by saying that "I want you to get better, and I expect you to want me to get better as well"!

    Object thinking is a "crazy idea" capable of increasing simplicity in software design - crazy in the sense that it does not conform to traditional thinking about software development, crazy in the sense that it revolts against the computer thinking employed by most software developers, and crazy in many of the same ways that XP is crazy.

    Trying to introduce object's into a culture that's firmly devoted to thinking in terms of data can seem like a crazy idea too. There is a time and place for everything, I'm sure objects aren't great for every system. A little bit of object "thinking" can help though, I'm sure.

    As a formalist, the computer scientist expects order and logic. The "goodness" of a program is directly proportional to the degree to which it can be formally described and formally manipulated. Proof - as in mathematical or logical proof - of correctness for a piece of software is an ultimate objective. All that is bad in software arises from deviations from formal descriptions that use precisely defined tokens and syntactic rules. Art has no place in a program. In fact, many formalists would take the extreme position: there is no such thing as art; art is nothing more than a formalism that has yet to be discovered and explicated.

    Art is something that I enjoy. One of the reasons that I was drawn to software was the creative aspects of it. I first thought of developing software as a form of art. It's great how Test Driven Development allows you to prove the correctness of a piece of software, but also enables you to refactor and be creative.

    An analogy to chess playing might illuminate the relationships among method categories. A beginning chess player follows rules and defined procedures (they are formalists), while a journeyman (informalist) relies on patterns and heuristics. A grandmaster has internalized and transcended the informal to become an aformal player.

    I'm currently reading a book on NLP, and it describes how experts do most of their work subconsciously, instead of consciously. It's like when you learn to drive a car (assuming you learned on a manual transmission). First you have a set of steps that you must follow, and repeat. Then you begin to follow patterns. (I used to look at my current speed to decide whether to shift gears.) Then you stop thinking about it, and you just drive.

    A human uses mechanical weights and machines in a gym to increase his innate capabilities - to make his own muscles strong and more reliable. Using a more cerebral metaphor (and one therefore more appropriate for object thinking), Kent Beck suggest using method and even XP practices as if they were etudes (musical exercises designed to help the musician internalize certain skills and techniques.)

    Time and Focus equates to discipline, according to me.  In order to excel at something you need to invest both time and focus to truly excel at it. There really is no secret to getting better.

    A common tendency for new object developers is to list as responsibilities things that an object must "know." An airplane must "know its current location." While this may be true, it can be misleading. It implies too much about how the object might be implemented because "knows" implies an instance variable. It's also quite possible that an object will know things (a private key for decryption, perhaps) that it will not be willing to share with others and that therefore will not be included in the interface for that object. Provide private key would not appear as a service, although the message privateKey might be in the object's protocol with the designation that it is a private message. Decrypt message, on the other hand, might be a listed responsibility. Always state your responsibilities in terms of a service, with an awareness of a possible client for that service.

    I know when I first started transitioning from procedural to object oriented programming, I thought mostly about where and how the data was going to stored, and how to get the data. "This auditor class needs to have a sorted list of audits"... Now it's a little more like "An auditor can submit an audit of a company to ..."

    This was a great read for anyone wanting to get into objects, or learn more about the history of objects. It was great to read about were a lot of present day ideas originated from.

Archive