23
Mar 13

Achievement unlocked: iOS Programming – The Big Nerd Ranch Guide 3rd Edition

Achievement unlocked: Despite being a busy father of three and having a day job I pour a lot of energy into, I finally managed to spend countless nights to work through @AaronHillegass’ and @joeconwaybnr’s excellent “iOS – The Big Nerd Ranch Guide 3rd Edition” (and the countless challenges presented therein). I attribute this to a) my generous intake of Monster Energy drinks late at night and b) the compelling way the material is presented.

The book is at it’s best when the authors take the reader through a series of chapters developing what at least remotely resembles a real-life application introducing new concepts along the way, like MapKit, UITableViews, UISplitViewControllers, UIGestureRecognizers or accessing Web services.

I especially appreciated the bottom-up approach of not using template applications to get up-to-speed quickly but starting from scratch instead which helps tremendously practicing basics over and over again.

The weaker parts of the book are those not dealing with “real-life applications” like the chapters on Core Graphics and Core Animation. Although those explain the technology in reasonable detail, they lack the motivation and “connection” of how to use those technology in a “useful” application.

A very minor complaint – The naming of variables is not very consistent across different chapters, I suggest either sticking with abbreviations or going with fully spelled variable names. (*)

But who am I to complain, I barely managed to cough up the hours every night to actually work through the book.

I learned a ton. Strongly recommended.

Off to creating my first iPhone app (you read it here first)…

(*) Run & hide, a nit-picker ;-)


15
Mar 13

Developing a Vectorworks 2013 Plug-in, TDD-style – Updated Epilogue

The code

I have updated the project files for my series “Developing a Vectorworks 2011 Plug-in, TDD-style”.

Please download the Xcode 4.6 / Visual Studio 2010 project files (haven’t tested it explicitly, but should work with Visual Studio 2012, too) for use with Vectorworks 2013 including all the sources here – SimpleCabinet2013.zip. The folder SimpleCabinet2013 should be dropped into Vectorworks 2013 SDK’s Sources folder, like this:

Please note that the projects assume that the folder hierarchy is set up like this.

The project features two targets, a testing target named “CppUnitLite2″ and the plug-in module shared library target, which outputs to /Applications/Vectorworks2013/Plug-ins. You will notice that all classes plus tests are contained in ExtObject.cpp. I’m doing this for small spikes – in real life, I would put each class in a separate file, no code in the header file etc.

The code drop features additional tests, refactorings and more usage of VWFC in SimpleCabinetCreator.

There’s also a Vectorworks document with a Simple Cabinet object included for your convenience.

Episodes


15
Feb 13

Uncle Bob Martin @ Objektforum Karlsruhe

On Feb 6, Robert C. Martin (“Uncle Bob”) gave a talk on “Automated Acceptance Testing: Expressing Requirements as Tests” @ ObjektForum Karlsruhe.

A few statements I found worthwhile for future reference:

  • Deployment is a business decision

  • Agile is not about getting more done, it’s about getting bad news early
  • Don’t let the tool dominate you
  • Not a lot of fixture code to write (to enable automated acceptance testing)
  • Test one thing only once

Here’s a thought which struck me while Uncle Bob waxed eloquently about Fitnesse and showed the DSL he created for testing Fitnesse:

A textual representation of a program’s or component’s output is the major prerequisite for automated acceptance testability. If you struggle with automated acceptance tests – as we do (CAD system with rich user interactions and complex objects being generated, dealing with complex object lifetime issues – “this can’t be tested automatically”) – focus on generating a simple textual representation of the results & interactions etc. This is the foundation of automated acceptance testability. It will be way easier to think about automated acceptance testing once you have this foundation in place.

Thanks to Robert for giving an energized talk despite being attacked by a flu virus and to andrena objects ag for organizing the ObjektForum event series.


09
Nov 12

Ersteres ist wahrscheinlich, letzteres aber nicht auszuschließen.

Manchmal liest Du Artikel von Software-Architekten, die auf 4 Seiten ausbreiten was man in 2 oder 3 Sätzen sagen könnte – entweder bin ich schlicht zu minderbemittelt, um der Relevanz & Sinnhaftigkeit der Diskussion zu folgen oder die Autoren haben völlig die Bodenhaftung verloren.

Ersteres ist wahrscheinlich, letzteres aber nicht auszuschließen.


06
Nov 12

Chaining Setters in C++ (Builder Pattern)

I have seen chaining of setters (in the context of builder pattern implementations) quite a few times in Java code recently, so I thought I jot down a quick C++ version for future reference (tried to get everything in one class for brevity purposes). No rocket science to be seen here, folks, but still a nice technique for creating objects (*):

class Pizza {

private:
	
	class PizzaProperties {
		
	private:
		
		PizzaProperties() : fSize(0), 
							fWithCheese(false), 
							fWithPepperoni(false),
							fWithBacon(false) {
		}
		
		int fSize;
		
		bool fWithCheese;
		bool fWithPepperoni;
		bool fWithBacon;
		
		friend class Pizza;
		friend class PizzaBuilder;
	};
	
	
public:
	
	class PizzaBuilder {
		
	public:
		
		PizzaBuilder(int size)  {
			fProperties.fSize = size;
		}
		
		PizzaBuilder& WithCheese() {
			fProperties.fWithCheese = true;
			return *this;
		}
		
		PizzaBuilder& WithPepperoni() {
			fProperties.fWithPepperoni = true;
			return *this;
		}
		
		PizzaBuilder& WithBacon() {
			fProperties.fWithBacon = true;
			return *this;
		}
		
		Pizza Build() {
			return Pizza(fProperties);
		}
		
	private:
		
		PizzaProperties fProperties;
	};
	
	
private:
	
	Pizza(const PizzaProperties& properties) : fProperties(properties) {
	}
	
	PizzaProperties fProperties;
};

So it’s quite convenient to build up different Pizza objects just by chaining the different “setters” – no need for default parameters, dealing with constructor bloat (# of parameters and # of constructors) etc. Plus, it’s quite efficient because the “setters” return a reference to a Pizza only, no memory allocation needed.


	Pizza largeMargheritaPizza = 
		Pizza::PizzaBuilder(30).WithCheese().Build();

	Pizza smallHotPizza = 
		Pizza::PizzaBuilder(20).WithCheese().WithPepperoni().Build();

(*) The code focusses on the chaining aspect of a builder pattern implementation – not the use of different builder objects for creation.


10
Oct 12

Regardless of what we discover…

The Retrospective Prime Directive:

Regardless of what we discover, we understand and truly believe that everyone did the best job they could, given what they knew at the time, their skills and abilities, the resources available, and the situation at hand.

What a great starting point for generating a safe environment during a sprint retrospective. A safe environment is important for a successful retrospective. However, starting with the prime directive will not generate a successful retrospective. Let me explain.

If I start thinking about the last sprint with the prime directive in mind, it is close to impossible for me to see how I could have done better. Because I did the best job I could – that’s what the prime directive said. If I’ve done the best job I could, what could be improved? Because my knowledge & skills are what they are, it sure is the situation at hand and the resources available which could be improved: The story wasn’t workable, the automated acceptance tests were sorely lacking, the build server failed all the time, the code was using this incomprehensible template stuff, the compiler was too slow, I had too many meetings, there are always conflicts when I try to commit my code, the APIs encountered are too complex, the product owner wasn’t available for questions 24/7, the unit tests run for ages and slowed me down, the Scrum Master didn’t moderate each and every meeting & discussion – etc. and so forth.

If you’re using the prime directive as a starting point, you’re framing your mind the wrong way.

What happened to individual responsibility, to laziness, to procrastination, to lacking technical skills, to a lack of practice, to inefficient use of my time, to a lack of knowledge, to stalling, to stepping up to the plate and saying “I have to do a better job and I need to do something about it”?

Why don’t we start with the Retrospective Prime Questions (you bet I made up this phrase 2min ago)?

  • What could I have done to make this sprint more successfully?
  • How could I have behaved differently?
  • What should I have done to help my teammate accomplish his task?
  • What could I have contributed to improve the process?
  • What do I have to learn in order prevent this from happening again?
  • What can I do to improve our environment?

Maybe we would come up with action items like this:

  • Mary will fix this §$%& build server. Joe will help her out, he’s a Jenkins wizard. They’ll get right to it on Tuesday morning.
  • Mark will help improving our unit tests performance – he has some great ideas on how to make that happen.
  • Erwin needs to use Skype to contact the product owner with questions instead of stalling. Our Scrum Master will help him by reminding us in the Daily Scrum that the product owner is on the road.
  • Joe needs to understand this %&$§ template stuff. He will sit down over the weekend for a few hours, read up on it and do some experiments. Jack said he will work with him over a beer next Wednesday night and help Joe getting his templates straight. Mary said she’ll join Joe & Jack, too as she’s unsure if she really got variadic templates. Our Scrum Master will make sure that there’s plenty of free beer available to make this a pleasant experience.
  • We will check the top stories on the product backlog regularly and see if they’re workable. I will start doing that tomorrow morning before the daily meeting. 10 minutes & a good coffee should be enough to do that.
  • Paul will update his code from the repository multiple times a day to avoid deadly conflicts. We’ll set up a kitchen timer for him as reminder.
  • Marvin needs to ask the Scrum Master to help out if his discussions spiral out of control. Erwin, who’s sitting next to Marvin will help with notifying the Scrum Master in time.
  • John knows a little bit about this Cucumber thing, he’ll sit down with the product owner next week to show him how to use it. This will bring us closer to automated acceptance tests.
  • Hans will ask our Scrum Master about recommendations on how to improve his verbal communication skills.

Disclaimer:

I’m neither a professional Scrum Master nor a Product Owner nor a Scrum expert. I’m just an ordinary software developer trying to deliver valuable, clean software. Most of the time, I’m failing. And it’s not because my environment is to blame or because there are impediments beyond my control. It is because I have to do a better job. And I want you to help me do that.

[Update]
Another take on this topic can be found at What’s wrong with the Retrospective Prime Directive?.
[/Update]

[Update]
My Scrum Master just sent me this link: NAIKAN. Looks like a worthwhile (Warning: German Language) exercise to encourage self-reflection.
[/Update]

[Update]
Very nice German language post on this very topic: Der Flügelschlag eines Schmetterlings.
[/Update]

[Update]
Great take on re-phrasing the Retrospective Prime Directive: Another Alternative To The Retrospective Prime Directive.


03
Oct 12

Angst, Mut, Verantwortung, Disziplin

Joseph Pelrine hat auf der Agile Bodensee einen schönen Satz gesagt (ich paraphrasiere aus dem Gedächtnis):

“Über Scrum zu reden oder Scrum zu lehren / coachen ist viel leichter als Scrum tatsächlich tagtäglich zu implementieren”.

Das Arbeiten im Scrum-Umfeld verlangt dem Entwickler einiges ab. Es bringt Ängste zutage, erfordert Mut, Verantwortung und Disziplin:

Angst

  • Angst nicht “ganz fertig” zu werden
  • Angst sich vor den anderen Teammitgliedern zu blamieren
  • Angst verantwortlich gemacht zu werden
  • Angst daß eigene Defizite sichtbar werden
  • Angst daß der Task mehr beeinhaltet als man absehen konnte
  • Angst die notwendige Technik nicht zu beherrschen
  • Angst nicht rechtzeitig nach Hause zu kommen

Mut

  • Mut auch komplexe und unbekannte Aufgabenstellungen anzugehen
  • Mut andere rechtzeitig um Hilfe zu bitten
  • Mut eigene Defizite einzugestehen
  • Mut Verantwortung zu übernehmen
  • Mut auch mal später nach Hause zu kommen
  • Mut Aufgaben auch nachträglich zu vereinfachen
  • Mut nicht dem Sprintziel dienliche Aufgaben beiseite zu schieben

Verantwortung

  • Verantwortung, sich fehlende Fähigkeiten anzueignen
  • Verantwortung für die Gruppe zu übernehmen
  • Verantwortung für eigene Fehler zu übernehmen
  • Verantwortung für das Produkt zu übernehmen
  • Verantwortung pünktlich zu erscheinen
  • Verantwortung Informationen klar, präzise und zeitgerecht zu vermitteln
  • Verantwortung sich über anstehende Aufgaben zu informieren

Disziplin

  • Disziplin den Test zuerst zu schreiben
  • Disziplin auch wenn es zeitlich eng wird sauberen Code zu schreiben
  • Disziplin immer wieder über das eigene Fortkommen transparent zu informieren
  • Disziplin auch die unangenehmen oder unpopulären Tätigkeiten zu erledigen
  • Disziplin komplexe Aufgabenstellungen in überschaubare Arbeitspakete zu zerteilen
  • Disziplin immer wieder rechtzeitig Hilfe einzuholen
  • Disziplin bei jeder Tätigkeit immer wieder das Sprintziel im Auge zu haben

26
Sep 12

Short recap of the Wrecking Ball tour’s 2012 German leg (yup, I’m very late)

(Should get this months old draft out there before the 2013 leg of the tour is upon us ;-)

Not sure if I qualify as a Bruce Springsteen “fan”. With fandom, I do associate hysterical screaming (and I’m far from it). “Mild stalking” is another characterization I associate with fandom. Most certainly, I’m not interested in the private life of neither Bruce Springsteen nor members of the E Street Band.

However, I do care deeply about the music. Everybody has a certain kind of music which deeply resonates with him or her. And Bruce Springsteen’s music deeply resonates with me.

Frankfurt was special as I took my wife and my two older daughters with me. We got seats on the right hand side quite far from the stage. The concert, however, became absolutely magical as Bruce & the E Street band clearly loosened up in the last quarter of the concert. Summertime Blues in the main set came unexpected, and the departure from the standard encores played on the tour so far with Cadillac Ranch, Sherry Darling & Glory Days made my day.

For Cologne, a slightly more intimate stadium than Frankfurt, I managed to get front of stage tickets. Unfortunately, I missed the pit roll calls by about 15minutes (shouldn’t have stopped for a bathroom break during the 2.5h drive to Cologne ;-) , but found a nice, relatively short queue in the shades. Met a few nice folks who provided me with priceless advice on how to convince my wife to do a few more Springsteen concerts (Hint: Trade shopping/sightseeing in Milan/Florence for spending the evening at Springsteen concerts). I got lucky and ended up maybe 12th “row” on the left side of the stage, with a great view of the fantastic performance and hard work Nils Lofgren is putting into the show.

For the Berlin trip (kindly sponsored by my aforementioned wife), I showed up early at the Berlin Olympic Stadium, got my number (171) and spent the day either queueing, showing up for the roll call or queueing & reading (Recommend classic car magazines). A worthwhile effort, as I got a great spot in the pit (about 5th row) on the right side of the stage right in front of Steven van Zandt. The big news was, of course, the opening song “When I leave Berlin” which was extensively rehearsed during the soundcheck and an absolutely beautiful rendition of “Save my Love”.

I didn’t expect the Wrecking Ball material to be a perfect fit for a stadium setting. Of course, I was wrong. It worked out great, lot’s of feedback from the audience.

Was it worthwhile? You bet. Rumors suggest that there might be a second european leg next year (Munich? Hamburg?) I’m very much looking forward to it, maybe “Racing in the Street” this time? I hope to put the free advice I got in Cologne to good use and try to get a few more 2013 concerts in Italy or Spain on my schedule.

Pro tip: Get a Mophie Juice Pack Plus for your iPhone if you intend to tweet the setlist. It’s $§&! ugly (the Mophie, not the setlist), but it will double your battery capacity during the show. And trust me, you’ll need it as you’re desperately trying to get your tweets through the congested ether at the venue.


24
Sep 12

Staring is not an efficient coding technique

The following quote from Buzz Andersen’s blog (which I highly recommend) caught my eye:

…full-time pairing can make the certain amount of “staring into space” time every programmer needs to get things right excruciatingly awkward.

I don’t want to dive into the pair programming discussion this time, I’ll leave this for another post. I would like to talk about staring. Staring on the code. Staring on a comment. Staring on a UML design sketch. Or, as Buzz puts it, staring into space. (*)

As far as I can tell (and I have done my fair share of staring over the years), staring is a software engineering technique where, for an extend period of time, the software developer refrains from any movement of his extremities, stops moving his eyeballs and focusses on a particular piece of code, while his CPU cores, umm, brain runs at 100% load trying to solve the problem at hand.

If we’re lucky, said developer appears to wake up from time to time, types a few characters, maybe adds a comment and resumes staring. If we’re less lucky, said developer will remain unresponsive for extended amounts of time and will make no measurable progress towards his goal.

I don’t dispute that “Staring” may be a technique to get things right, but I would like to go on the record that it’s an efficient technique to get things right. Day after day, I observe that developers “stare into space” or, even more inefficient, “stare on the code” in order to solve problems. However, I’ve never seen a problem getting solved by staring, I’ve only seen problems getting solved by adding or changing code.

Why is staring an inefficient technique, you may ask?

Staring is inefficient because it doesn’t employ a feedback loop. You are reasoning about the code with yourself. Nothing wrong with it, but there’s no one involved giving you feedback on your thoughts or challenging your assumptions – after all, it’s just you staring at the code.

If you catch yourself staring at code too often, make sure to get into the habit of doing something with the code instead:

  • Even if you don’t have automated tests (and you know you should, don’t you), you can do tiny, lowest-risk refactorings which help you deepen your understanding of the code just a tiny little bit. Rename a variable, a function, extract a few lines of code to a new method, write a comment (gasp), change the formatting to suit your style (quadruple gasp). You can always revert this changes after you understood what’s going on (you do use version control, don’t you?)
  • How about running the code in a debugger to get the additional feedback of variable / objects / state changes at runtime?
  • How about writing unit tests? Write a test, write a little bit of code, write some more code, see a test failing, change the code, write a test to test your assumptions about specific parts of the code. Do a change to the codebase to learn something? Do the tests still run? Great. They don’t? Looks like your assumptions were wrong. Trace back, take another route.

If you absolutely must “stare” at the code, I suggest to take a step back and “sleep on it” or to take a short walk. But those are techniques which should be reserved to occasions when you really got stuck and you’re trying to solve really hard problems. Guess what, most of the time the problems aren’t that hard. They may be challenging but they are quite solvable by taking tiny, reproducible (sometimes revertible) steps towards a solution.

Code is like clay. Make sure to mold it. Carefully. You’ll learn way more by molding the code, not by staring at it.

(*) Don’t want to get into discussing “staring on web-sites not at all related to the task at hand” either.


07
Sep 12

I sense a disturbance in the Atlassian force…

Great products are the foundation of a great company. Atlassian has great, rock-solid products (If I wouldn’t be a rather stern German, I would say these are absolutely fantastic products). They improve those products thoughtfully and continuously. We have been customers since 2006. Actually. we have been customers for so long that I find e-mails from a co-CEO answering dumb questions of mine during our JIRA evaluation.

JIRA 2/3

First, we purchased the JIRA Enterprise Edition and renewed our maintenance/update every year. Rock-solid product. Worked great. Atlassian kept improving it. Pretty steep pricing for us, but it had unlimited users which was important as we had a product with about 150+ customers reporting their feedback through JIRA.

JIRA 4 license change

Then, Atlassian introduced JIRA 4, and nixed the unlimited users Exterprise Edition. Changing to the user tier we needed would have doubled our yearly maintenance costs including the risk of running out of users again in the future. We didn’t do it but decided to stick with JIRA 3 for this particular project. We put all the other projects on a newly purchased JIRA 4 50 user license (about 15 active engineers (devs & support) and about 20 marketing/sales guys/gals which would mostly be read-only/comment-only – with a yearly maintenance/update fee which was absolutely worth it because Atlassian kept improving the product.

Greenhopper

After introducing Scrum a few years ago, we looked at Atlassian’s Greenhopper offering. As expected, a great product. However, we would have had to purchase a 50 user Greenhopper license to match our 50 user JIRA license – although we only have about 10 devs on our Scrum team. The rest of the users couldn’t care less about Greenhopper. Plus Greenhopper is quite steeply priced (about 50% of the base JIRA license) for both the product and the yearly maintenance. So the Greenhopper purchase never happened for us.

Confluence

Because JIRA was working so well for us (from a product point of view), we looked into Confluence. Another great product. We looked at the pricing and found there was no 50 user tier, just a 100 user tier. So we would basically have to pay for 50 users we didn’t intend to use in the foreseeable future. However, the product is – as mentioned before – a really great one, so we decided to go for it – of course including a yearly maintenance/update fee which was absolutely worth it because Atlassian kept improving the product.

Dropping MacOS

Probably about 1.5 years ago, out of the blue, MacOS (our platform for both JIRA & Confluence) was no longer supported as a production environment for both JIRA & Confluence – Mind you, I’m not disputing the decision, I was baffled because there was absolutely no mention of this rather important news (“We cease support for a major operating system platform”) on any of Atlassians developer blogs / website etc. So we’re running our JIRA / Confluence production systems on some unsupported operation system – but hey, it still works. Still rock solid. Still great products.

Team Calendar

Atlassian came out with a new plug-in for Confluence called Team Calendar, which – you know what’s coming – is actually quite a great product and would be a nice fit for us. However, we would have had to purchase a 100 user Team Calendar license to match our 100 user Confluence license – although we only have about 10 devs which would use Team Calendar (rest of the company is on Exchange/Outlook – let’s not go there). Plus Team Calendar is very steeply priced compared to the base Confluence license for both the product and the yearly maintenance. So the Team Calendar purchase never happened for us.

Confluence license change

Last night, I received a lengthy, nicely layed-out HTML e-mail titled “Upcoming Changes to Your Confluence Download License” in my inbox. The e-mail was talking eloquently about the latest Confluence 4.3 release and how great it was – agreed. Another solid release. It also mentioned prominently that I would be able to purchase yearly maintenance at the existing price for two years – although the licensing would change – and that there would be additional “Enterprise” licensing tiers. It talked about existing users being able to renew at existing prices or upgrade during a grace period, but no mention how the new licensing & pricing would affect existing customers. Connecting the dots, I decided to click through to the FAQ page get more details on this “license change”. On item 5 (of 13), I found that Atlassian intends to increase the cost of our yearly Confluence maintenance/update fee by a whopping 80%. Words fail me.

The message I receive

  • Atlassian tends to make unexpected, substantial licensing changes
  • The pricing of plug-ins seems somewhat off compared to the base product
  • The pricing of plug-ins is tied to the user tier of the base product
  • An 80% price increase for yearly maintenance / updates

From where I stand, all these moves are maximizing Atlassian’s profits at the expense of their users. I’m not sure how I can align this message with the set of values Atlassian is based on.

I conclude that there’s a substantial risk involved with being an Atlassian customer. It’s not the risk that you end up with a set of bad products. The products are great. Rather, it’s a business & financial risk and a lack of mid- and long term licensing cost predictability (both financial and feature set predictability). And no, a two year grandfathering period doesn’t change the message I receive.

P.S.: Dear @atlassian employees reading through this rant (I know you will): If there are any factual errors in my rant, please do not hesitate to contact me at hm dot kern at gmail dot com, via Twitter @hmkern99 and I will update this post right away.

[Update 1] I updated the section “Confluence license change” to more accurately reflect the content of the mail. Thanks for the feedback, Matt!