Quote: If you cannot measure it…

May 11, 2011

If you cannot measure it, you cannot improve it. Lord Kelvin


Best Practice: Foundations

May 3, 2011

When I became a full-time developer I determined to learn what constitutes best-practice in my profession and to learn to apply it to my practice. Thus far, it has been an interesting and largely enjoyable journey.

Of course, I’ve made some fundamental mistakes on the way. One source of error has been difficulty in determining what constitutes best practice in the context of the projects I’m working on. Clearly, best practice in any endevour must be determined by your overall purpose. Today, I came across an article by Eric Lippert that sums up our purpose as well as anything I’ve come across up to this point:

The purpose of code is to create value by solving a business problem.

Best practice, then, is that which most effectively enables us to add business value. Not all code adds value in the same way, so best practice will vary between projects.

In the same article, Lippert identifies 3 areas in which code displays fitness for purpose:

  1. Good code is code which “works correctly according to its specification to actually solve the stated problem”
  2. Good code “communicates its meaning to the reader who needs to understand its operation”
  3. Good code “allows for relatively low-cost modification to solve new problems as the business environment changes”

The relative importance of these 3 areas can vary between projects. A quick throw-away script that is used by a single develpoper needs to be functional but less emphasis can be placed on modification and readability. On the other hand, an application like Microsoft Word will be worked on by many developers and maintained through numerous development cycles. As such, readability and maintainability need to be emphasised as much as correct fuctionality.


SQL Server: Disable All Constraints

May 3, 2011

This post has been moved to Yagni.net.


Book Summary: Practices of an Agile Developer

April 27, 2011

Review

Note: This page is an ongoing project…

Below is my summary of “Practices of an Agile Developer: Working in the Real World” by Venkat Subramaniam and Andy Hunt. In my view this is a 4-star book, well worth reading in its entirety.

Aside from introductory and closing chapters, each chapter of the book describes one of 45 practices that are important in achieving an Agile development environment (one reviewer suggested it be renamed, “45 Habits of Highly Effective Developers”)

The thing I like most about the book is the emotional awareness of the authors. They recognise that development is as much an emotional experience as it is a technical one, and that communicating good practice needs to address the readers’ emotional needs as well as their practical ones. This applies to both the presentation and content of each chapter. As a result, I felt good about reading this book, and I feel good about trying out the espoused practices.

Presentation

The language, typography and layout make it an easy read.

The subdivision of the book into 45 practices means that:

  • It can be read in digestible chunks
  • It is possible to dip-in
  • It makes a good reference book

Content

The chapters on each of the practices includes:

  • A practice number and title, for easy reference.
  • An explicit statement of the reasons why we might resist the practice described (the Devil’s temptation)
  • A discussion that explains the rational behind the practice and how to apply it practically, typically backed up by real-world examples
  • A summary of the key message of the chapter (the Angel’s advice)
  • The emotional outcome of following the practices described (What it Feels Like). This encourages emotional buy-in.
  • Notes on how not maintain perspective (“Keeping Your Balance”)

Beginning Agility

Work for Outcome (Page 12) – PoAD#P1

Temptation

Prioritise finding the culprit over resolving the problem

Problem

  • Reactive and defensive people are unproductive
  • Assigning blame can make the situation worse

Context

  • It is rare that one person is entirely to blame
  • Everyone makes mistakes (unless they take no risks)
  • A person’s misunderstanding / ignorance/mistake often reveals an area for team development

Attitude

Outcome is more important than taking credit / apportioning blame

Blame doesn’t fix bugs

Solution

Offer to help.

Be part of the solution, not part of the problem

Don’t argue about it, fix it.

Outcomes

  • Safe to admit ignorance
  • Mistakes are learning opportunities
  • Teamwork

Balance

  • Remove bad apples from the bunch
  • Remove yourself from a bad team

Thoughts

  • Credit-whoring can be just as bad as apportioning blame
  • Both the fear of and actuality of blame / credit whoring is damaging productivity

Quick Fixes Become Quicksand (Page 15) – PoAD#P2

Temptation

Make a quick fix to code you don’t really understand

Problem

Clarity of code goes down

Accumulation of quick fixes become “quicksand”

You can’t possibly be agile with that kind of baggage

Attitude

Long term code clarity is more important than short-term fixes.

Solution

  • Get a good understanding of the overall architecture and design
  • Understand the code you modify
  • Avoid quick hacks
  • Invest in code clarity

Fix the problem, not the symptom

Tools

  • Don’t code in isolation (e.g. use code reviews)
  • Unit testing

Outcomes

  • Clean code
  • No areas of untouchable code
  • Developers have a general working knowledge of the code base

There are no dark corners in the project

Balance

  • You don’t need to become an expert at everything
  • Larger systems are rarely understood by one individual
  • If the code can’t be understood by the team, it is too hard to maintain – even for the original author

Thoughts

Quick fixes can be bad news in the short term, too. The project was a static data loader that threw an exception. I made a small change to a piece of code I didn’t fully understand. The consequence was the the data in the wrong version of the database was overwritten.

Criticize Ideas, Not People (Page 18) – PoAD#P3

Temptation

Making it about who is right rather than what is right.

Problem

Criticism:

  • Does nothing to enhance understanding
  • Suppresses innovation
  • Makes people unhappy

Context

  • Everyone has bad ideas
  • Nothing is perfect – there is only “better”
  • Bad ideas can stimulate good ones
  • Everyone starts somewhere
  • Compromises are inevitable

Attitude

Focus on the best solution, not the best person.

Criticize ideas, not people

Solution

  • Ask open questions to reveal flaws and solutions
  • Don’t be afraid of criticism
  • When you see a potential problem, realistically ask how often a problem actually occurs
  • Support the decision

Tools for Overcoming Indecision

  • Set a deadline
  • Argue for the opposite
  • Mediation

Outcomes

  • Freedom to explore ideas
  • Ideas can be rejected without hurt feelings
  • Imperfect ideas can be adopted without guilt

Balance

  • Make sure everyone agrees on what “best” means. Users and developers often disagree
  • Sometimes you have to accept the least worst solution

Damn the Torpedoes, Go Ahead (Page 23) – PoAD#P4

Temptation

Ignore important issues to avoid uncomfortable situations

Attitudes

Courage to do what is right

Solution

  • Be courageous
  • Communicate truth
  • Do the right thing

Admiral David Farragut:

Damn the torpedoes, full speed ahead!

Outcomes

  • Short-term discomfort
  • Relief, not dread
  • Festering problems addressed

Balance

  • If everyone else disagrees, you may be explaining it wrong – or just wrong
  • Impatience is not courage – take time to understand why things are the way they are

Feeding Agility

Keep Up with Change (Page 28) – PoAD#P5

Keep up with changing technology. You don’t have to become an expert at everything, but stay aware of where
the industry is headed, and plan your career and projects accordingly.

Invest in Your Team (Page 31) – PoAD#P6

Raise the bar for you and your team. Use brown-bag sessions to increase everyone’s knowledge and skills and help bring people together. Get the team excited about technologies or techniques that will benefit your project.

Know When to Unlearn (Page 34) – PoAD#P7

Learn the new; unlearn the old. When learning a new technology, unlearn any old habits that might hold you back.

Question Until You Understand (Page 37) – PoAD#P8

Keep asking Why. Don’t just accept what you’re told at face value. Keep questioning until you understand the root of
the issue.

Feel the Rhythm (Page 40) – PoAD#P9

Tackle tasks before they bunch up. It’s easier to tackle common recurring tasks when you maintain steady, repeatable intervals between events.

Delivering What Users Want

Let Customers Make Decisions (Page 45) – PoAD#P10

Let your customers decide. Developers, managers, or business analysts shouldn’t make business-critical decisions. Present details to business owners in a language they can understand, and let them make the decision.

Let Design Guide, Not Dictate (Page 48) – PoAD#P11

A good design is a map; let it evolve. Design points you in the right direction. It’s not the territory itself; it shouldn’t dictate the specific route. Don’t let the design (or the designer) hold you hostage.

Justify Technology Use (Page 52) – PoAD#P12

Choose technology based on need. Determine your needs first, and then evaluate the use of technologies for those specific problems. Ask critical questions about the use of any technology, and answer them genuinely.

Keep It Releasable (Page 55) – PoAD#P13

Keep your project releasable at all times. Ensure that the project is always compilable, runnable, tested, and ready to deploy at a moment’s notice.

Integrate Early, Integrate Often (Page 58) – PoAD#P14

Integrate early, integrate often. Code integration is a major source of risk. To mitigate that risk, start integration early and continue to do it regularly.

Automate Deployment Early (Page 61) – PoAD#P15

Deploy your application automatically from the start. Use that deployment to install the application on arbitrary machines with different configurations to test dependencies. QA should test the deployment as well as your application.

Get Frequent Feedback Using Demos (Page 64) – PoAD#P16

Develop in plain sight. Keep your application in sight (and in the customers’ mind) during development. Bring customers together and proactively seek their feedback using demos every week or two.

Use Short Iterations, Release in Increments (Page 69) – PoAD#P17

Develop in increments. Release your product with minimal, yet usable, chunks of functionality. Within the development of each increment, use an iterative cycle of one to four weeks or so.

Fixed Prices Are Broken Promises (Page 73) – PoAD#P18

Estimate based on real work. Let the team actually work on the current project, with the current client, to get realistic estimates. Give the client control over their features and budget.

Agile Feedback

Put Angels on Your Shoulders (Page 78) – PoAD#P19

Use automated unit tests. Good unit tests warn you about problems immediately. Don’t make any design or code changes without solid unit tests in place.

Use It Before You Build It (Page 82) – PoAD#P20

Use it before you build it. Use Test Driven Development as a design tool. It will lead you to a more pragmatic and simpler design.

Different Makes a Difference (Page 87) – PoAD#P21

Different makes a difference. Run unit tests on each supported platform and environment combination, using continuous integration tools. Actively find problems before they find you.

Automate Acceptance Testing (Page 90) – PoAD#P22

Create tests for core business logic. Have your customers verify these tests in isolation, and exercise them automatically as part of your general test runs.

Measure Real Progress (Page 93) – PoAD#P23

Measure how much work is left. Don’t kid yourself — or your team — with irrelevant metrics. Measure the backlog of work to do.

Listen to Users (Page 96) – PoAD#P24

Every complaint holds a truth. Find the truth, and fix the real problem.

Agile Coding

Program Intently and Expressively (Page 100) – PoAD#P25

Write code to be clear, not clever. Express your intentions clearly to the reader of the code. Unreadable code isn’t clever.

Communicate in Code (Page 105) – PoAD#P26

Comment to communicate. Document code using wellchosen, meaningful names. Use comments to describe its purpose and constraints. Don’t use commenting as a substitute for good code.

Actively Evaluate Trade-Offs (Page 110) – PoAD#P27

Actively evaluate trade-offs. Consider performance, convenience, productivity, cost, and time to market. If performance is adequate, then focus on improving the other factors. Don’t complicate the design for the sake of perceived performance or elegance.

Code in Increments (Page 113) – PoAD#P28

Write code in short edit/build/test cycles. It’s better than coding for an extended period of time. You’ll create code that’s clearer, simpler, and easier to maintain.

Keep It Simple (Page 115) – PoAD#P29

Develop the simplest solution that works. Incorporate patterns, principles, and technology only if you have a compelling reason to use them.

Write Cohesive Code (Page 117) – PoAD#P30

Keep classes focused and components small. Avoid the temptation to build large classes or components or miscellaneous catchall classes.

Tell, Don’t Ask (Page 121) – PoAD#P31

Tell, don’t ask. Don’t take on another object’s or component’s job. Tell it what to do, and stick to your own job.

Substitute by Contract (Page 124) – PoAD#P32

Extend systems by substituting code. Add and enhance features by substituting classes that honor the interface contract. Delegation is almost always preferable to inheritance.

Agile Debugging

Keep a Solutions Log (Page 129) – PoAD#P33

Maintain a log of problems and their solutions. Part of fixing a problem is retaining details of the solution so you can find and apply it later.

Warnings Are Really Errors (Page 132) – PoAD#P34

Treat warnings as errors. Checking in code with warnings is just as bad as checking in code with errors or code that fails its tests. No checked-in code should produce any warnings from the build tools.

Attack Problems in Isolation (Page 136) – PoAD#P35

Attack problems in isolation. Separate a problem area from its surroundings when working on it, especially in a large application.

Report All Exceptions (Page 139) – PoAD#P36

Handle or propagate all exceptions. Don’t suppress them, even temporarily. Write your code with the expectation that things will fail.

Provide Useful Error Messages (Page 141) – PoAD#P37

Present useful error messages. Provide an easy way to find the details of errors. Present as much supporting detail as you can about a problem when it occurs, but don’t bury the user with it.

Agile Collaboration

Schedule Regular Face Time (Page 148) – PoAD#P38

Use stand-up meetings. Stand-up meetings keep the team on the same page. Keep the meeting short, focused, and intense.

Architects Must Write Code (Page 152) – PoAD#P39

Good design evolves from active programmers. Real insight comes from active coding. Don’t use architects who don’t code—they can’t design without knowing the realities of your system.

Practice Collective Ownership (Page 155) – PoAD#P40

Emphasize collective ownership of code. Rotate developers across different modules and tasks in different areas of the system.

Be a Mentor (Page 157) – PoAD#P41

Be a mentor. There’s fun in sharing what you know—you gain as you give. You motivate others to achieve better results. You improve the overall competence of your team.

Allow People to Figure It Out (Page 160) – PoAD#P42

Give others a chance to solve problems. Point them in the right direction instead of handing them solutions. Everyone can learn something in the process.

Share Code Only When Ready (Page 162) – PoAD#P43

Share code only when ready. Never check in code that’s not ready for others. Deliberately checking in code that doesn’t compile or pass its unit tests should be considered
an act of criminal project negligence.

Review Code (Page 165) – PoAD#P44

Review all code. Code reviews are invaluable in improving the quality of the code and keeping the error rate low. If done correctly, reviews can be practical and effective. Review code after each task, using different developers.

Keep Others Informed (Page 168) – PoAD#P45

Temptation

Focus on getting the job done. If people want a status update, they’ll ask.

Problem

  • Trust diminishes
  • You won’t get help
  • Customers can’t re-prioritize
  • Interruptions for status updates

Attitude

Keep others informed

Solution

  • Tell people, don’t wait for them to ask
  • Deliver bad news early: don’t give people unpleasant surprises
  • Publish designs, cool ideas, research, status etc.

Stay head’s up, not head down

Tools

  • Email
  • Sticky notes
  • Phone calls
  • Status charts
  • Blog
  • Wiki
  • Daily stand-up

Outcomes

  • People don’t pester you for status updates

Balance

  • Know your audience, level appropriately
  • Don’t let communication efforts get in the way of work progress

Other Summaries and Reviews


Prince 2 Notes: Change

April 26, 2011

Issues and Changes

  • Change is inevitable

Projects need a systematic method for managing change

Change management is a continual activity

Issue: Deffinition

An issue is an event that was

  • not planned
  • requires management action

Issues can be raised by anyone

Types of Issues

  1. Off Specification (Off Spec): any product that is missing / not meeting agreed specification
  2. Request for Change (RfC): proposed change from baseline
  3. Problem / Concern (P/C): any other problem / concern / query / suggestion

Change Control

Systematic change control keeps project:

  • Responsive to change
  • Under control

Ensures change is

  • Authorised by appropriate authority
  • Considered in relation to baseline

Procedures ensure that issues and changes are:

  • Identified
  • Assessed
  • Approved / rejected
  • Implemented

Configuration Management

Products are versioned (i.e. kept in configuration management)

Mechanism to track configuration:

  • Creation
  • Maintenance
  • Control

Configuration Item

Something subject to configuration management, such as:

  • A product
  • A component of a product
  • A set of products that form a release

Release

A set of products that are managed, tested and deployed as a unit

Management Products (Documents)

  • Configuration Management Strategy
  • Configuration Item Records
  • Product Status Accounts
  • Daily Log
  • Issue Register
  • Issue Reports

Configuration Management Strategy

Facilitates impact assessments (relationships between products)

Maintains product baselines

Based on corporate or programme strategy where these exist

Defines:

  • How:
    • Management procedure
    • Issue / Change control procedure
      • Identify
      • Propose
      • Decide
      • Implement
  • What: Tools and techniques
  • Why: Records and Reporting
  • When: Timing
  • Who: Roles and responsibilities

Defines levels:

  • Priority
  • Severity

e.g. MoSCoW

Change Authority

Who has responsibility at each severity level.eg. Project Board, PM, etc.

Change Budget

Funding for the costs of change

Managed by Change Authority

Limits can be specified for:

  • Costs of single change
  • Total spend on change in stage

Configuration Item Records

Include information on:

  • Status
  • Version
  • Variant
  • Relationships between items

Product Status Account

State of products

Daily Log

Records problems and concerns that can be handled by PM informally

Can be transferred to Issue Register if required

Issue Register

Contains information on issues managed formally

Monitored by PM regularly

Issue Report

Only required for formal issues, these include:

  • Description
  • Impact assessment
  • Recommendations

Configuration Management Procedure

Planning

  • Decide level of configuration management required
  • And how that level will be achieved

Identification

All components of products at level of control

Control

Ability to:

  • Approve products
  • Baseline products (old baselines are archived, not deleted)
  • Ensure changes are authorised by appropriate authorities

Products include:

  • Management products (inc documentation)
  • Specialist products

Status Accounting

Reporting on current and historical data re: product

Verification and Audit

Two purposes:

  • Comparing actual and authorised status of products.
  • Check procedures in Configuration Management Strategy are followed

Occur at end of stage and end of project

Issue and Change Control Procedure

Defined by IP process

Reviewed and updated during MSB process

Capture

  • Type of Issue – formal / informal
  • Determine severity / priority
  • Level of authority
  • Formal issues -> Issue Register
  • Issue Report created

Examine

  1. Impact of analysis cost
  2. Impact analysis on project objectives / business case / project risk profile
  3. Impact on supplier / user / business
  4. Update Issue Register / Issue Report

Propose

  1. Identify options
  2. Evaluate options
  3. Recommend options
  4. Risk
  5. Exception Report?

Decide

RfC

  • Approve
  • Reject
  • Request info
  • Defer
  • Escalate

Off-Spec

  • Grant Concession
  • Resolve
  • Defer
  • Request info
  • Escalate

Problem / concern

  • Provide guidance
  • Escalate

Implement

  • Take corrective action
  • Create an exception plan

Update issue register

Budget Options

Some changes impact budget

Illegitimate Options

Using Tolerance to fund Changes

Legitimate Options

Using Change Budget

Increase project cost

Reducing project scope


Best Practices: Variables

April 18, 2011

This post has been moved to Yagni.net.


Visual Studio Extension: Browse Current Project

March 30, 2011

I’ve just published my first Visual Studio Extension. It is a very simple one-command extension that allows you to view the contents of the folder that contains the current project in the Visual Studio Browser. At the moment, only Visual Studio 2010 is supported.

Instructions for Use

To view open the browser on the project’s folder, just click on the button in the Solution Explorer’s toolbar. The button is only visible when you have a solution loaded in Visual Studio.

The contents of the folder that contains the current project will be displayed in Visual Studio. That’s it!


Visual Studio Fonts and Colors: Version 2

March 28, 2011

Some time ago I wrote about my chosen colour scheme for Visual Studio.  I’ve updated it several times since, so I’ve uploaded the latest version to StudioStyles. It looks like this:

Unfortunately, StudioStyles doesn’t support all the styles for VB.Net, so you’ll have to tweak it a bit if you want VB.Net goodness.


SQL Server: Drop all Foreign Keys that Reference a Table

March 17, 2011

This post has moved to Yagni.net.

 


Design Pattern: Object Pool

February 7, 2011

Type

Creational Patterns

Name

Object Pool

AKA

Resource Pool

Motivation

Performance can be an important consideration for applications. In some scenarios, object creation is a costly step.

Intent

Avoids cost of initializing objects by maintaining a pool of pre-initialized objects that can be re-used.

Description of Benefits

Can offer a performance boost where:

  • object instantiation is expensive
  • instances of the class are frequently created
  • number of instances at any one time is small

Can make initialization time predictable where it would otherwise be unpredictable (e.g. when squiring resources over a network)

Known Uses

Instantiation of objects that represent:

  • database connections
  • socket connections
  • threads
  • large graphic objects

Real-World Illustrations

  • Shoe shelf at a bowling club
  • Car pooling
  • Library

Participants

Reusable: An object used by Client until they it is no longer required.

Client: Uses an instance of Reusable for a limited amount of time

ReusablePool: Manages the collection of Reusable objects by:

  • creating new instances of Reusable
  • supplying instances of Reusable to Clients

Typical methods induce:

  • getInstance: A static method that returns an instance of ReusablePool
  • aquireReusable:A method that returns an instance of Reusable
  • releaseReusable(Reusable):A method that returns a Reusable to the pool

Basic Implementation (Collaboration)

Object Creation

The Client is responsible for requesting the Reusable from the ReusablePool.

On receiving a request for an object, the ReusablePool will attempt to supply an suitable Reusable.

Object Use

The Client should be unaware that the Reusable can be shared with other Clients:  from the Client‘s point of view, the Reusable can be treated in exactly the same way as an object that has been created in any other way,the only difference being that it must return it to the ReusablePool once it has finished using it.

Object Release

The Client is responsible for returning Reusables to the ReusablePool once it is finished with.

Implementation Details

Resource Loading Strategy

Several strategies are available, for example:

  • Eager: A specified number of Reusables are created by the ReusablePool when the ReusablePool is instantiated.
  • Lazy: Reusables are not created by the ReusablePool until they are requested by the a Client. Once Reusables are released, they are immediately available for other Clients.
  • Hybrid: A specified number of Reusables are created eagerly, but additional Reusables are created lazily.
  • Lazy-Expanding: Creates resources lazily, but doesn’t re-use them until the ReusablePool reaches a certain size.
  • Eager-Expanding: Creates resources eagerly. Creates additional resources when available objects in the ReusablePool drops below a certain threshold.

Maximum Pool Size

Some implementations may set a maximum number of Reusables in the ReusablePool

Empty Pool

Various strategies can be adopted to handle the situation where a Client requests an instance from the pool, but none is currently available:

Prevent the situation by ensuring that the ReusablePool will always contain enough Reusables.

  • Fail to provide Reusable, and inform the Client that none is available
  • Create a new Reusable, thus increasing the size of the pool
  • Block until another thread to releases an object back into the pool
  • Forcible reclaim a Reusable from a low-priority Client

Synchronization

In a multi-threaded environment, careful consideration must be given to synchronisation of methods on the ResourcePool object.

Failed Release

If the Client fails to return a Reusable to the pool, then it will be unavailable to other Clients. To avoid this, the ResourcePool could implement an expiry time for Reusable:
if the Reusable has not actually been used for a certain length of time, it can be made available to other Clients.

Resource Eviction

In some situations, it may be undesirable to hold unused Reusables in the ReusablePool for long periods of time. In this case, it may be desirable to evict Reusables from the ReusablePool if they have not been requested by a Client for a specified length of time.

Recycling Methods

Some types of Reusables may need to be reset to a know state before they can be allocated to another Client. This is the responsibility of the ReusablePool.

Variants

  • Sub-pools
  • Mixed Pools

Relationship with Other Patterns

ReusablePool is often implemented as a Singleton.

References