Tim Harvey :: Blog

Icon

I help organizations who feel stuck

PPL: Day 14 – Classes Part 1

This is part of the Peer Pressure Learning 30 series. The introduction to the experiment post will make all things clear.

Whew, I almost forgot tonight! That would have been my first miss. Luckily, after toying with the Facebook API and FQL for a while, it dawned on me that I needed to finish reading the chapter on Classes (which I started this morning) and blog!

Today’s reading: pg 135 – pg 146

Having read a chunk of Code Complete, thinking about clean, concise classes isn’t entirely new. I was pleased to find that Uncle Bob isn’t fanatical about perfection, sometimes bending the rules on privacy:

For us, tests rule. If a test in the same package needs to call a function or access a variable, we’ll make it protected…

Nice, that had been bothering me for a month or two. It seems that my larger classes end up with a private method or two that I’d like to test. They’re tested by virtue of the public methods being tested, but a targeted test would help at times. I didn’t like the idea of making them public, so this strikes a nice balance.

As with functions, the author makes it clean that they should be small, and then you should go back and make them smaller still. But…he makes a great distinction: “with functions we measured size by counting physical lines. With classes we use a different measure. We count responsibilities“. Oh man, genius!

Fighting with Rails

I’m clearly still new to Rails and find that the conventions seem to fight against the larger OOP concepts at times. I’m sure that as I get more comfortable with the plumbing (and hell, Ruby itself) that I’ll find all this easier. I read the following a struggle to know how to make such nice-sounding organization a reality in a world of “fat models”:

At the same time, many developers fear that a large number of small, single-purpose classes makes it more difficult to understand the bigger picture. They are concerned that they must navigate from class to class in order to figure out how a larger piece of work gets accomplished.


However, a system with many small classes has no more moving parts that a system with a few large classes. There is just as much to learn in the system with a few large classes. So the question is: Do you want your tools organized into toolboxes with many small drawers each containing well-defined and well-labeled components? Or do you want a few drawers you toss everything into?

It’s crazy stuff. While I like the idea of small drawers, I suspect that I would end up creating a ton of tiny drawers that don’t have the requisite organization. Time will tell!

PPL: Day 13 – Unit Tests

This is part of the Peer Pressure Learning 30 series. Get a handle on this PPL thing with my introduction to the experiment.

It’s the weekend, so I’m back to the evening groove. The morning was relaxed and the whole family and I went to visit the Amish farm that we buy all our meat, eggs, and chicken from. But that’s another blog post.

Today’s posts is on unit tests. I’m trying not to be a snob as the Ruby community seems to really have testing nailed. Between Rspec and Cucumber, I’m in heaven. I have to remind myself that there’s a lot to learn from the Java community and especially about writing good tests.

Today’s reading: pg 121 – pg 134

Uncle Bob seems to nail me with every chapter. I have been, for the most part, a self-taught programmer. The programming courses I took in college were a joke that I dominated in my sleep, so I jumped over to a business degree so I could learn something I didn’t know. But therein lies the problem. Until now, I’ve never had a systematic approach to polishing my craft. This line from the text describes me to a T:

…in the mad rush to add testing to our discipline, many programmers have missed some of the more subtle, and important, points of writing good tests.

Some really good points come out of the chapter:

  • Test code should match the code quality of production code – I can relate here…test code changes all the time as the requirements change. If your tests are crap, you’ll pay for it every time you have to rewrite tests. Changing over to using Factories has been a perfect example. The tests stay DRY and have been much easier to maintain since the change. Uncle Bob (the author) correctly says: “Test code is just as important as production code.”
  • Tests give you courage – That’s a weird thing to say, and it’s definitely my interpretation of the text. But…it really is true. I have tremendous faith in the test suites I use in each of my apps. Because of the safety net they provide, I can rename large models, change big chunks of logic, or refactor sections of tricky code without fear. My tests tell me when I’m done! I couldn’t go back to a non-TDD (test driven development) language ever again (or one with sucky TDD tools). I really mean that. I’d be hard as hell.
  • One assert per test…probably – I like that Uncle Bob feels free to break the rules. While it’s a good goal to shoot for one assert per test, the added code and duplication may negate the benefit. I find that I frequently pair a record count assert with an assertion about what’s in the record. The better guideline is to test one behavior (the text says, “concept”) per test.

All in all, I feel pretty good about where I stand with test code. I definitely need to hone my comfort level with the tools I use, particularly to reduce duplication.

I’m totally pumped about tomorrows reading which begins a journey into the depths of classes and their proper composition.

If you’re ready to melt your brain on some wild code stuff, read Miles’ post on Factor, a crazy weird stack language that’s unlike anything you’ve even seen.

PPL: Day 12 – Boundaries

This is part of the Peer Pressure Learning 30 series. The introduction to the experiment post will make all things clear.

Today’s already been a fun day. Vince, my partner in crime at the office, and I got up early and started banging out a free web site for our building’s cafe. It’s a great little restaurant on the seventh floor that needs some help with a bit of marketing. Look for http://ErvsCafe.com/ soon.

I also had a blast this morning reading about software boundaries. It’s a pretty important topic when you begin considering larger systems.

Today’s reading: pg 113 – pg 120

The general idea is that we need to manage how our code interacts with software written by someone else, or that might change frequently. It’s really another look at coupling.

Rather than sprinkling code all through our app that uses a particular gem, we’re encouraged to write a wrapper class so that it’s less disruptive (sorry Jerry). That way, we can swap out an uploader / asset gem with something else and don’t have to rewrite large swaths of the application’s code. This comment about such classes sums it up best:

It is able to evolve with very little impact on the rest of the application

There’s a wonderful gem in this chapter. The section on exploring and learning boundaries offers some excellent advice on getting used to and beginning to integrate a new library.

One of my big takeaways was the authors encouragement to write tests that exercise the new library. It forces you to begin learning the library’s API and documents your understanding. It also acts as a safety net when the library updates. You’ll know immediately if some portion of the API you are familiar with changes. These are the kind of test, in my world, that I’d leave for the CI server to run once they’re in place. There’s no sense in running them regularly unless you’re working with changing out that library.

Looking for some more PPL goodness? Take a peek at Miles’ Day 10 post on Erlang!

PPL: Day 11 – Error handling

This is part of the Peer Pressure Learning 30 series. Read my my introduction to the experiment to learn more.

After two days on Objects and Data Structures, I felt like I was beginning to get a better handle on the concepts. I’m pumped about today’s topic as I’ve just been pondering how to handle bad inputs (to libraries) and thinking about alerting (to me) of recoverable error conditions.

Today’s reading: pg 103 – pg 112

This statement kicks off the chapter on the right foot for me, setting the stage:

Error handling is important, but if it obscures the logic, it’s wrong.

Nice. Definitely not playing around on this topic! This was particularly valuable as the discussion turned to null values in arguments and return values.

Two critical sections were particularly timely for me, titled “Don’t return null” and “Don’t pass null”. I had really been struggling with this and as a result, been adding .nil? checks all over my code. I just had a conversation about it yesterday and was at a loss about what to do.

Now, it’s funny because I failed to take several things into account:

  • Rails already has some great error handling, so if a null creeps in somewhere, the user gets a nice error message and Hoptoad helpfully kicks me in the mouth with a nice shiny stack trace.
  • While it’s definitely worth coding defensively, my code is the only code that calls the methods I’m worried about, so I can trap for bad user input long before it gets into the libraries.
  • Throwing exceptions is not a bad practice. I read a blog post talking about bad usage of exceptions to control program flow and have since stayed away from them. Dumb. In several cases, I’d been returning nil as a flag that something had gone wrong and allowed the caller to deal with it. That’s pretty lame. Thinking now, I realize that I could define some sensible exceptions and allow the caller to handle each differently depending on the situation.

Chances are good that most of my .nil? checks are pointless and only satisfy test cases that I created in rspec. Boo. Time to rip some stuff out because as they say, “No code is better than no code.”

So…all that to say, there’s some tremendous wisdom in what author Uncle Bob shares. He sums it up nicely by saying:

If you are tempted to return null from a method, consider throwing an exception or returning a special case object instead.

* Note: A special case object would be one that looks and acts like the typically returned object. For example, Rails ActiveRecord #all method typically returns an enumerated list of model instances. When no records exist, it returns an empty array instead of nil. That plays nicely with a .each loop, saving us from trapping for nil.

PPL: Day 10 – Objects & Data Structures Part 2

This is part of the Peer Pressure Learning 30 series. You can read all about it.

Yesterday’s late morning led to a last-minute blog post. Thankfully, I read the text earlier in the day as it really warranted some consideration. Thankfully today, I’m back to the early groove.

Today’s reading: pg 99 – pg 102

The chapter’s concepts begin to take shape with the balance of the chapter read. While it’s really tough to see how it fits in with the rather opinionated Rails framework. I’d be rather interested in talking through concepts in this chapter as they relate to MVC.

The crux of the matter is the distinction between data structures (dumb classes that hold data) and objects (super-smart classes that operate on data structures). I quoted from the text yesterday, but really should have used this rewording of the Law of Demeter (a “well known heuristic”):

a module should not know about the inards of the objects in manipulates

That talks about objects, not data structures. The idea is that objects know very little about other objects in the system. They are allowed to chain through and know a ton about data structures, even if they’re chained several layers deep.

Ruby on Rails

So, what about Ruby on Rails? Clearly, the whole discussion is moot when you’re looking at a site/system with less than 5,000 lines of real code. It’s probably not large enough to worry about splitting into separate objects and data structures. Rails’ models hide enough functionality that a model can stay reasonably sized and satisfy the needs of a hybrid object / data structure. It’s a concern of balance, really. While a purist may demand that the smallest app utilize all the associated patterns and follow OOP to the T, I’m not in that camp. I’ve done enough consulting to realize that you have to balance cost (time) with the benefits (rather low in small projects).

A larger app begins to make the whole discussion rather interesting. I seriously have no answers on this side of the topic. If I’m taking the text properly, one would begin to make the models increasingly small, leaving validations and associations behind (and probably some of the callbacks). You’d then move more and more logic into library objects.

How the heck would that work? Hmm…I’m not really sure. I’ve done some work on having the model call a factory that instantiates the associated libraries, but I could also see some of that logic going into the controller. Putting it into the controller seems to be a great opportunity to duplicate code (not good). I think I like the idea of the model starting the process.

I’d love to hear from anyone with experience on really large, complex Rails projects. Talking through the concepts with someone experienced with 20-50k lines.

PPL: Day 9 – Objects and Data Structures Part 1

This is part of the Peer Pressure Learning 30 series. Take a peek at my introduction to the experiment Miles and I embarked on.

This was a tricky section to get through today. I’m long past the comfortable passages that I’ve read over in the past and into the more conceptual material. I think it will require some more thought and review to really think through properly.

Today’s reading: pg 93 – 98

I stopped a bit short, so there isn’t as much to cover today, but one clear message came through. Think really carefully about the methods you make public. If you go down the road of opening up the entire class, you dangerously couple classes together. Your like is much more difficult down the road when you need to change a class when you have no idea which methods are in use.

Instead, choose the bare minimum to expose and hide as much as possible. That way, you may easily gut and re-implement the entirety of the private methods while preserving the same interface.

I find that Rails makes this particularly tough. By default, every model exposes getters and setters for all attributes. That’s really great in the world I come from, building simple marketing focused sites with a bit of app thrown in for good measure (to drive a CMS, email form, or simple CRM).

When it comes to developing a serious app with tons of models, associated libraries, and complexity galore…it can become quite challenging to keep everything clean and concise. I find that I rarely think in terms of the API a class provides. I can juggle the whole system (barely) in my head, so all classes generally know about whatever I feel like.

I was really blown away by this statement (in the context of describing the Law of Demeter), and have no idea whether this would be possible for me:

A method should not invoke methods on objects that are returned by any of the allowed functions. In other words, talk to friends, not to strangers.

Wow…how does one do that? The answer (which I don’t fully grasp) has to do with the authors distinction between objects and data structures (one being full of behavior, and the latter being just a container for data). It’s a pretty wild and interesting concept. I’m fascinated to see how I can apply it in the Ruby on Rails world.

Peeking ahead a bit, it seems that some of the answers I need may come later in the chapter.

Feeling like all this code structure talk is mamby-pamby? I don’t blame you. Head over to Miles blog for his introduction to a language that will put hair on your chest: Closure.

PPL: Day 8 – Horizontal formatting

This is part of the Peer Pressure Learning 30 series. Go read my introduction to the experiment Miles and I embarked on.

Monday morning and I’m back on track. It’s barely 8:00am and I have my reading done.

Today’s reading: pg 85 – pg 92

This section on horizontal formatting really challenged some of my thoughts on code. As I said before, I’m a bit of a geek for formatting code a certain way. Uncle Bob (the author) isn’t as infatuated with the little “beauty” details as I sometimes am. I routinely line up assignment operators, hashrockets, or any other element that’s repeated on multiple lines. He points out some reasons not to do that, despite the visual appeal.

An example of my hyperactive horizontal alignment from the filtering Twitter Proxy I wrote:

A couple differences in his coding style that I want to ponder further:

  • You probably shouldn’t break indentation – When a block can be done on one line or indented over several, the author explains that he almost always (he of course, used Java) went back to the indented multi-line version. In the example below. the “return true” is the critical element, the thing that actually executes. That shouldn’t be hidden in the middle of the line. Rather, it’s indented and it’s scope is clearly shown. (Note: I did use the more Ruby-ish inline if statement. I felt that to be a reasonable breakage of standard indenting…but maybe it isn’t!)
  • Don’t necessarily line up similar elements – I find that I almost always line up like elements in named_scopes, routes, associations, etc. The author makes an interesting point that while you may be making the code more aesthetically pleasing, you can obscure relevant differences. The code becomes too easy to scan, allowing someone to miss critical elements of the code. The example below may be as stretch, but I could see someone missing the difference between the TRUE and FALSE. I guess one must weigh the value of showing how similar the two statements are with making their difference clear.

I’m interested to talk with my team about implementing some basic style guidelines. The text talks about a situation the author was in where they spend just 10 minutes making some decisions that affected the whole project. That tells me that it doesn’t have to be a long, drawn out affair.

What will get interesting for a web app project is that we have to integrate several different languages. I’m already finding that I have to tone down the amount of Ruby-specific stuff as we have to shift from Ruby to JS to HTML and each has its own common idioms. That’s what makes this fun!

PPL: Day 7 – Vertical formatting

This is part of the Peer Pressure Learning 30 series. The introduction to the experiment post will make all things clear.

Once again, the weekend has almost been my undoing. I may have to accept that the weekend requires doing PPL at night before bed with weekdays sticking to the morning routine.

Today’s reading: pg 75 – pg 84

Chapter 5 kicks off discussions of code formatting, a topic I really enjoy. I’m a complete freak for making sure my hashrockets line up, there’s no whitespace at the end of a line of code, etc. I’d like to say that it’s because I have some specific value on professionalism or neatness, but that would be a load of crap. For whatever reason, I spot little inconsistencies and they drive me nuts…it’s probably a bit OCD because I’m sure that I blindly skip over the stupid stuff I do that others hate.

Clean Code has kept the discussion rather focused on the utilitarian side. Steve Smith‘s talk at the Great Lakes Ruby Bash on “Designing Code” takes the whole concept in a direction I love.

The author gave some great suggestions about how to sort the methods within a class. I’ve always wondered about that as mine end up being a mish-mash, depending on when I added a method. He suggests that:

  • Methods are defined below the point where they’re first called
  • Like methods go together (they are logically or actually connected)

He also spends some time talking about proper whitespace, limiting files to a reasonable length (files over 500 lines may indicate a concept that’s too large for a single class), and keeping in mind that you’re in the business of communicating. I love this introduction to the chapter:

Code formatting is about communication, and communication is the professional developer’s first order of business. Perhaps you thought that “getting it working” was the first order of business for a professional developer. I hope by now, however, that this book has disabused you of that idea. The functionality that you create today has a good chance of changing in the next release, but the readability of your code will have a profound effect on all the changes that will ever be made. The coding style and readability set precedents that continue long after the original code has bee changed beyond recognition.

Good stuff.

PPL: Day 6 – Bad comments

This is part of the Peer Pressure Learning 30 series. Jump to my introduction to the experiment if you got here from Google or some other site.

This is my first weekend PPL day and it almost broke me! It’s been a heavy week, so I was barely able to fall out of bed. Even then, it was 30 minutes later than usual and the kids were already going full steam. So here I am at 10:53pm because I really care a ton about this stuff. Thank goodness I got a Kindle copy of Clean Code as the paper one is collecting dust on my desk this weekend.

As a brief aside, I got a ton out of Gary V’s talk from RailsConf. I listened to it three times today. His push to make sure you do what really means something to you resonates a ton with me. Go watch it!

Enough rambling!

Today’s reading: pg 59 – 74

The section shares a rather long list of bad comment habits and styles. I couldn’t begin to do them justice. My thought is to share a few of the mistakes I’ve found myself making of late. Having jumped into my first group project (I never coded on anything with more than one full-time developer), I quickly got accustomed to writing comments. I didn’t do it at first, but our team lead quickly pointed out the damage that my sparse commenting would eventually cause. Now, about 6 months in, I think I’ve gone too far. I’m finding that I include header blocks on almost every method, no matter how obvious it’s purpose:

The worst thing I do (and I find that I do it in conversation, emails, and IM) is getting crazy wordy in comments. I’m so enthusiastic to explain what’s going on, why we implemented things the way we did, etc. that I’ve written small novels is a couple sections of code. Worst of all, they’re so long that it would be difficult to tech edit them later to make sure it’s all still accurate! Arg!

My goal for this week will be to cut the redundant/obvious comments. I’ll also look to use shorter, simple language when describing concepts. And when I find something that’s sufficiently complex to seemingly require a short book…I’ll see what can be done to simplify things. Wish me luck!

Take a moment (or save it into Instapaper…the most wonderful too ever) to read Miles’ Day 5 post on Scala!

PPL: Day 5 – Good comments

This is part of the Peer Pressure Learning 30 series. Be sure to read my introduction to the experiment if this doesn’t make sense to you!

It’s Friday, and I’m a little apprehensive about PPL, heading into the weekend. I’ve made great progress this week, reading and blogging all week long. I need to keep the big mo going and stay on the wagon. Here’s my progress thus far (and yes, I counted the several days of ramp-up blogging…don’t judge me):

Today’s reading was on Comments. I made it through the first section on “Good comments”. I stopped my reading short before hitting the rather long “bad comments” heading.

Today’s reading: pg 53 – pg 59

If you’re a developer, I can’t recommend Clean Code enough. It’s been tremendous already. There were so many good points that jumped out to me, I don’t feel like I could do them justice by summarizing them. So instead, I want to quote some of my favorite lines:

  • If our programming languages were expressive enough, or if we had the talent to subtly wield those languages to express our intent, we would not need comments very much — perhaps not at all.
  • The proper use of comments is to compensate for our failure to express ourself in code. Note that I used the word failure. I meant it. Comments are always failures.
  • Why am I so down on comments? Because they lie. Not always, and not intentionally, but too often. The older a comment is, and the farther away it is from the code it describes, the more likely it is to be just plain wrong. The reason is simple. Programmers can’t realistically maintain them.
  • Truth can only be found in one place: the code.
  • Some comments are necessary or beneficial. Keep in mind, however, that the only truly good comment is the comment you found a way not to write.

I’m working on an OSS Twitter app that scores people’s level of annoying. I put together this code to cache a single user’s Twitter account details, only updating them (calling out to a slow API) every 24 hours. The #find_by_username runs the whole show. I love how crisp that method is now (it was a wreck 24 hours ago. The tests are all dirt simple now, it’s really great.

Coming on the heels of the previous chapter on writing small methods and this chapter on comments, I’m extremely proud of this class. It reads well and may not need any comments!

Here’s an earlier version (and if you can imagine…it was worse before this):

For more PPL fun, head over to Miles’ blog for his post on MongoDB.