Wednesday, May 13, 2015

The True Value of Test First Development (TDD)

This week I was able to show someone the true benefits of test first, actually we are doing a form of Behavior Driven Development (BDD). With respect to one of the true values of writing test first though, its all the same. You may think the true benefits are defect free code, change with confidence, and isolation of modules. You'd be right of course that these are benefits, but there's more - design and efficiency. We stayed the course for a bit with respect to writing tests first, but at the pleadings of the mentee I decided to just bang out some code as an experiment. We talked about a design for the API function that we were designing and I went ahead and wrote the interface and implemented it. Then we circled around to the tests and began to change them to suit our new implementation...that's when the proof showed up in the pudding! It turns out that our design was not going to work out so well. We wasted time writing it and now we had to waste more time retrofitting the tests. The only thing to do was to start with the test, write the interface we needed, then redo the implementation. When we start at the end, we know how to go best.

Tuesday, May 12, 2015

Peopleware

I want to spend time to blog about a few things I learned today, but reading Peopleware (Tom DeMarco and Timothy Lister), a book about the follies of conventions of management in software and how to improve everything from performance to retention has got my attention these days. The main theme so far seems to be focused on workspace, however it touches on dress code and personality. It's all about how the corporate culture is crushing performance and throughput in software and similar fields where focus and innovation are keys to success and what changes need to happen to revolutionize the industry. It's been around awhile and is in its third edition. I've been recommending this book to everyone. I'll get around to all of the other great lessons learned in a few days time...

Friday, May 8, 2015

On SOC

Today, I mentored a coworker on Separation Of Concerns commonly SOC. We are working on a bit of a pet project that he has some cobbled together code for. Instead of working directly with that we are starting from scratch and building out the features one at a time.


One concern we encountered is that each user has their own collection of widgets that they do something with. Some users may have the same widgets among their collections of widgets, but the widgets themselves belong to no single user.


We broke out a completely bounded context of User Settings. Though some information may cross the boundary into the Widget World, the only thing that shall pass is immutable data. In this way we have user settings that involve widgets and any other number of concerns such as app theme, gadgets, notification settings, etc.


Given that we are taking this on as a learning experience, we decided that we would (in the style of Clean Code) hold off on deciding persistence. What we do have is an object that loads UserSettings and one that saves it. Why the separate objects? Actually we have separate contracts, that's the part I do care about. The implementation can be the same for now. What the read/write separation is a out is control. It costs little to separate them now for the possible migration of the implementation to services later. It may be a bit crufty, but I can live with it in this case.


More central to the tier of persistence, is the layer of UseCase informed logic. In our case we have different concerns for user settings. One is centered on widgets, another on gadgets, another on application look and feel. There could be others. Each of these will be separated into their own bounded contexts of sorts. We are using the term Manager to describe this layer.


So we have a Manager for each concern - widgets, gadgets, app settings, notifications, etc. Any given Manager could talk to any data access context (Resources). Say a user adds a widget to his/her list of widgets that they want to have a look at. The Manager consumes the User Settings resource - loads settings, adds widget id to user.widgets, calls resource to with save method passing UserSettings object to method. All details of saving are abstracted from the business logic by the resource. The resource could be saving to a file, an RMDB, a document store, or some newfangled thing. We can change that without affecting BL.


If we have an app setting like 'theme' we can follow the same practice. Add theme id to the UserSettings object, make a ThemeManager or add methods to the UserAppSettingsManager and call the same load and save methods in the UserSettingsResource. We may have that same manager talk to the AppSettingsResource to load specific details about the theme. Likewise, the WidgetManager would load widget data from the WidgetResource after loading the list of widgets for the user from the UserSettings resource.


This type of pattern allows separation of concerns in two dimensions - by topic and by layer. It allows us to structure a program in services or direct use of objects. There is a slight deviation from true OOP in that things can get a bit procedural or perhaps functional in style. However, given proper management of concerns this may not be detrimental.



Thursday, May 7, 2015

The Three Amigos

The Three Amigos refers to the lead developer, qa analyst, and business representative reviewing and elaborating the requirements. They should be taking the business requirements and turning them into real acceptance criteria. That acceptance criteria should then be used to drive testing at all levels.


Hopefully, the acceptance criteria is written in a way that can be directly translated into tests. One technique that can be used is to write the acceptance criteria using a Given-When-Then syntax. Given is the precondition, When is the action, Then is the result after the action is complete.


Mockups and screenshots are a great way to provide some high level detail about the change. Where it falls short is in really shaking out the details, providing specifics, and defining behaviors for edge cases.

What we do, and why we do it.

Generally speaking, we development teams will tend to have several "environments" that we deploy changes to before going live with a particular change set. An ideal minimum is four environments including databases, web servers, and other resources that apps interact with. Some resources might not be completely isolated if it adds no value.


First, we deploy to a pseudo-environment - local. Local is for integration testing our own work in isolation.


Dev is typically the first environment we deploy to. Sometimes its nightly or CI. Here we ensure that things are building once checked in and mingled with other code. We run automated tests here and perhaps have some gate process.


When its ready for testers to mash away at it, we promote to QA or TEST environment. Here is where our testers bang on the code to make sure it works and that we're delivering on our promises.


Once the release is ready to ship, we will move it to UAT/STAGE. This environment serves 2 purposes - it gives the stakeholders a place to have a look before go-live but more importantly, this is how we validate our deployment plan. We may have a number of changes that need to happen, but applied those in phases to QA. This is our chance to shake out any issues that we may encounter when deploying to a stable environment that matches prod.


Then we go live to PROD.


When something fails after we go live, we typically scramble wondering what happened. It passed QA so how does this not work in PROD!? When this has happened to me, it's often been a release that never went through that so important pre-live deployment. There are various excuses we have for skipping STAGE, all of them useless because we know better.


One excuse I've had is that we don't have a STAGE for this app. I could've used some foresight and built it. Or in the case where it would mean an extra license, I could stage in the DR environment where we do have a license.


Bottom line is that we need to deploy to STAGE so that we know we can deploy when we do go live, no more excuses.

Friday, April 24, 2015

Feature Solution Problem

Consider a feature that can be done in a few different ways. Solution 1 is estimated to take 8-weeks and is the gold plated version. Solution 2 is also estimated at 8-weeks and is the silver version. Solution 3 is estimated at 6-weeks and is the bronze version. Which option do you chose? Certainly not the silver since it takes the same time to produce gold right?


We don't have all the information to make an informed decision. We don't know what the initial costs are for each solution. We don't know the TCO (Total Cost of Ownership) for the long term. We don't know the risks.


Lets put up some more info:


Sol 1: Needs 6 human resources for a cost factor of 8.6. Requires licensing at a yoy cost factor of .2. Requires 2 new long-term commodities at a cost-factor of 3.3. Has a potential impact of other projects due to resource constraints.


Sol 2: Needs 4 human resources at a cost factor of 9. No licensing required. Requires 1 new commodity at a cost of 2.3. Has a potential impact on other projects.


Sol 3: Needs 4 human resources at a cost factor of 6. No licensing. No new commodities. No risk to other projects. Long term risks due to support, estimated at yoy cost of 1.1.


Which is the best option? Still, we haven't normalized the information. We don't know the long-term costs of 1 & 2. We don't know details of coat to other projects...something more to think about.

Good Requirements, Good Requirements, Good Requirements

The incantation of the title of this post will unfortunately not make good requirements appear out of nowhere. So what does? Teamwork!


Good requirements are all about communication. What is a software requirement/specification anyways but a communications from the consumer to the supplier? As in any form of communications, there must be an understanding between the senders and the receivers of the nomenclature.


Imagine someone called a contractor for an estimate to build a deck, but the consumer really meant a patio. Lets say Joe Consumer communicated the following whilst getting an estimate - "How much would it coat to build a big deck in my back-yard." What's the first thing that contractor would ask? How big...if Joe doesn't know the measurements he'd have to give an approximation. Not being very savvy of measurements because Joe never needed to and he didn't pay attention in the 4th grade, Joe says - "from the garden to the kitchen window and to the end of the third fencepost." Well, since this is a phone call, the contractor obviously doesn't have enough information to give even the remotest estimate. So, says the contractor - "I'll have to come out and take some measurements to give an estimate."


That is to say that the contractor has to take the time to drive to the site, get out some simple tools, measure, and likely draw up some rough sketches before she can have any remote idea of the costs. The information the contractor needs could be what kind of wood, how many stairs, benches, flower boxes, shape, coatings, height, etc... So goes the conversation...until the consumer and the contractor reach a point when they cannot communicate any further because things are getting really confusing and difficult.


Finally, the consumer grabs a magazine and shows the contractor a picture of a stone patio. Somehow it all makes sense at that point. The customer's frustration with the contractor's obsession with wood and the contractor's confusion about why the customer would want the deck at ground level are all abated. There is a clear communication.


The moral of the story is that a communication can and should take several forms. Ultimately what the contractor would likely do is draw a diagram with markings and notes and use that to build the patio. The contractor would include all the hidden parts that make the patio stable while perhaps referencing the picture for aesthetic touches.


In the end, it took a conversation about the details of the project to build the right thing. It's the same in software. If the consumer and builder of software are not talking about the same thing, details can become frustrating. This is why it is important for the askers and the builders to produce requirements/specifications together.


Addendum: Of course when the contractor gives the estimate, she says "I could do it for..." as they always do. Why do they say it this way? Let us pontificate...


Consider the following key elements - time, cost, and quality. The patio could be built for more cost and better quality. Could be built fast for the same price but lower quality. So, what are the driving factors in the estimate that was given? Just something to think about...