Skip to content
March 27, 2008

My continuing love affair with ReSharper: Indicating Recursive Calls

I generally believe that comments should be about “why is this code doing this” instead of “what is this code doing” because if you feel you need comments to explain what your code is doing, it could probably be refactored to be more readable and/or intention revealing.

One exception that I’ve often made is for recursive calls. I generally write a comment indicating that the method is about to call itself and why. This may be left over from my first CS class at the University where I had some kind of mental block around recursion, I don’t know.

So, I was delighted to see ReSharper give a little visual indication of a recursive call in the margin.

Recursive Picture

This useful when doing recursion on purpose (this example was using reflection to populate test data into properties, I would recurse when a property was a complex type), but it’s even more useful if you do recursion on accident, as in this public property returning itself below.

 Bad Recursion

March 26, 2008

Guilt as a Code Smell

One of the best things about working for Velocity Partners is that I get a chance to do presentations/brown bag seminars for their other clients/prosepective clients. I like to think that as I’m a hands-on developer who actually works with this stuff every day, I have different credibility from the full time trainers/presenters/coaches/pundits.  Note: I don’t want to disparage the full-time trainers that I know and respect, their credibility comes from the fact that they were hands-on coders for a long time, and have more time to do the reading/research/writing that someone working on deadlines may or may not have.

I’m currently putting together a presentation on Refactoring, and how that relates to the other agile tools and techniques (where “agile” simply means “modern development practices that work”). While looking for examples, I’ve been re-reading Martin Fowler’s great Refactoring book.  One thing that struck me was the focus on “getting the inheritance hierarchy right” which, after living in the design patterns (favor composition over inheritance) realm for the last few years, felt kind of odd to me.

Meanwhile, in my “day job” I’ve been working on a well encapsulated, generics-based .NET client for a family of REST-y XML services.  After making one major component, I found that I had to make another major component that does much the same thing. So, I created a new abstract base class and made both my existing component and the new component concrete derived classes of the base class. As I needed functionality for the new class, I generalized it and moved it up to the abstract class (using the protected modifier, of course) so I could use it in the other derived class.

It was working pretty well. I had very little code duplication and ReSharper is particularly good at the “Pull Members Up” refactoring, but I was starting to feel a little guilt about not doing things in a “pattern oriented way”. Sure, you could never use the two concrete components interchangably, so there was a violation of LSP, but I can be cool with that. The abstract class didn’t have any public methods on it, so there’s no danger of someone trying to couple to its publically-exposed interface.

After, I figured out where my guilt was coming from. It’s a coupling/testability problem. As the concrete types are tightly coupled to their base types, I couldn’t ever substitute a different type to handle that functionality. This is particularly important as the base type was all about making external (HTTP) service calls, so it was impossible for me to test any of the types in isolation.

The solution: it’s pretty obvious, but I just moved the functionality of the abstract base class into a service class with an interface. Now my two components (formerly derived classes) just have an instance typed to that interface. I can test all three parts in isolation (Q: How do you test an abstract class in isolation? A: You can’t) and I can re-use the same functionality across additional components in the project, further reducing duplication.

So, what I’m saying is: take your guilt seriously. If you have a bad gut feel about a design, it might very well be bad.  It’s just like any of the code smells in the original Refactoring book. It doesn’t necessarily mean that there’s a problem, but it’s worth looking at.

But, at the same time, I’m not going to beat myself up over my interim design. It was a good, easy stepping stone to a more optimal design. This is the sort of thing that Scott Bain’s new book Emergent Design: The Evolutionary Nature of Professional Software Development is about. I’ve only skimmed it so far (I’m working on a new presentation, after all) but I know Scott, and I know his approach to the subject. From what I’ve read so far, it seems to be the right text for the professional programmer who wants to move beyond “just getting it working” to the level of “getting it working well”.  I wish that I could have read it years ago.

November 20, 2007

More on becoming a Java Developer

There’s an excellent SDET whom I worked with around a year ago who shares many of my software interests (Lean/Agile/TDD/Design Patterns, etc.) as well as some some non-software interests (photography, left-handedness).  Even though we haven’t been on the same project for a while, we sometimes get together to have design discussions. We’ve found it helpful for both of us to have an audience who is outside our immediate projects to give us honest feedback.  His test code is better than most people’s production code, and my production code is getting more and more testable.

Anyway, after one of these discussions, I mentioned that I was working with Spring, something that the development group uses extensively for Java projects, not as much with the C# projects.

“What, you’re working with Java now?” he asked.

“Yes, I’m becoming bilingual.” I said.

“That’s not bilingual, that’s ecumenical!

He has a point, many people have such a religious zeal around their choice of technology that it clouds their vision. Personally, I think that learning Java has done a lot to make me a better C# developer because the contrast stands out and I think to myself “why are things this way in this language?” and “wow, anonymous classes are pretty handy for endo-testing” and “while I miss the get/set property accessor syntax, I see and understand why Java folks don’t like it.”

November 3, 2007

College Botany and the Java Ecosystem

When I was a student at the University of Washington, vaguely interested in plant life, I decided to sign up for a botany class on top of an already busy schedule. “How hard could it be?” I thought, after all, I did very well in biology class in high school.

Big mistake.

Botany is hard, and not for the reasons you might expect. A first-year botany student learns more new words than a first-year foreign language student. Why is that? Because you have to learn all the different words to tell different parts of different kinds of plants apart. There’s a small amount of logically figuring stuff out (which I enjoy greatly) but it’s mostly rote memorization (which I enjoy not so much).

For the last few years, I’ve been working in the C#/.NET ecosystem, where most of the day-to-day tools and technologies are pretty clearly defined and packaged by Microsoft. Sure, you need source control, nUnit, ReSharper, and CruiseControl, but that’s about it.

I’ve just finished my first week as a developer working on a Java project. My first impression: the entire ecosystem is huge. I’ve had to learn about a billion new words. Maven, Pom, Jmx, Spring, JBoss, JDK, ClassPath, VM Parameters, Jetty, TeamCity, beans, WARs, JARs, SARs, EE/SE/ME, etc. Well, maybe it’s not as many new words as I tried to learn in botany, but it felt like a lot to me this week.

But it has been good. The core languages between C# and Java are almost exactly the same, with the distinctions being really interesting. The Pragmatic Programmers suggest learning a new programming language every year, and I understand why. Even if I don’t keep at this whole Java thing long-term, I’ll come out of it a better C# developer.

Actually, this would make two new languages this year, if you’re willing to count scratch.

The best thing about this learning experience is that IntelliJ has the generally same keyboard shortcuts at Visual Studio with ReSharper (of course). When I saw that hitting ALT+F7 (find usages) on a setter method will show me the spot in the spring config xml where that value was set declaratively, I almost cried with joy.

October 3, 2007

More C# Partial Class Testing Strategies

I can’t take credit for this approach, and even if I could, I probably wouldn’t, because it makes me feel kind of icky.

Anyway, I recently heard about a legacy code testing strategy where you mark your class as “partial”, and in another file, you add whatever public properties/methods you need for your tests. You make the contents of the second (testable file) conditionally compiled (the classic #IF DEBUG) so the encapsulation is still there for any release builds.

It’s kind of like endo-testing, but you’re extending the class “sideways” instead of “downwards”.

Basically, it’s breaking encapsulation in a controlled way, and for the most part, I think it’s a bad idea if you’re working with a new design. If, however, you’re trying to get some meaningful coverage for your legacy code (which wasn’t designed for testability) it can be a good stop-gap in dealing with the legacy code refactoring catch-22: where you don’t want to make changes without tests, but you can’t make tests without making changes. 

Any strategy, such as this one, which allows you to get the first layer of tests down before further refactoring, should be embraced as a good thing.  If you find that you need to do this for any new/original classes, my guess is that your class is too big and needs to be decomposed further into more cohesive and testable classes.

September 25, 2007

Testability in Isolation: Not just for automated testing

One of the code qualities that I’ve been advocating is “Testability in Isolation”. I’ve expanded the name from the NetObjectives-blessed quality of just “Testability” because I find it more explicit and useful.  Everyone can say “sure, my code is testable, I test it all the time”, and be done with it. If you ask, “Can you test your business logic in isolation from your other layers” you get a more meaningful understanding of the quality of their code.

Usually, I discuss testability in the context of unit tests,  using the strict definition of unit tests: automated, developer-authored, testing one thing in isolation without external dependencies. I’ve found recently that testability in isolation is a virtue when doing manual testing too.

I’ve been working on a Windows Forms application recently, and I found myself drilling down to the same part of the UI over and over while I tweaked one of the user controls. I felt the feedback loop growing, so I created a separate winforms project which I called “Playground” and made a way to get to that particular control I was testing with just one click.

In the playground UI, I use the same test doubles for things like persistence that I use in my unit tests (I’ve got a really nice in-memory-db fake to replace my file-based persistence layer). When I need to, I have the test harness pre-load enough fake data to work with, so when I click the “one button”, it’s set up to exercise what I want it to exercise. Tightens my feedback loop and speeds me up immensely.

It’s weird to think that I haven’t done this explicitly before (although in some web apps, it’s easy to just jump directly to the right page). I’m sure that I’m going to do it again, especially when working with testers, it can give them a way to test just one interaction/user interface component by itself without feeling blocked because parts of the app aren’t ready yet.

August 31, 2007

Program Launcher/Auto-Updater

I remember the first desktop app that I developed for a client. All of my coding experience until that point had been as  a web developer. Sure, I had done QA and technical support for a  shrink-wrapped/installed program before, but I left that organization to take a web developer job.

Even though I hadn’t yet heard of Agile or Scrum, I had grown accustomed to the notion of frequent incremental releases of value. The web made that easy to do. You didn’t have to worry about installers or versioning, just push the bits out to the server and you were good.

So, the first thing I did for the client app was make a program launcher, so when you click on the icon to start the app, you don’t actually start the app itself, you start a little shell .exe that displayed a splash screen. It checked a web site for a newer version of the software. If there was one, it would pull it down, copy over the bits and then start it.

When the currently installed app was the same version as the app on the server, it would just launch the app directly. This process made startup take only a few seconds longer, and it gave me a chance to display the really cool-looking splash screen I created.

It had to be a distinct .exe because I couldn’t over-write the one that was running, obviously.

It worked like a charm, of course, and I could easily make updates to the client app as well as the server apps.  I never had to worry about supporting multiple versions of the software in production. The app was small enough, and the users all had LAN access, so that even on the days where you did have to download the new version, it always took less than a minute.

I remember thinking, at the time, “This is how all software is going to be in the future. A tiny little launcher app which will keep the main app in sync.”

If nothing else, this demonstrates my ability to predict the future, as I haven’t seen anyone else use this approach. On the Microsoft technology side, with .NET xcopy deployment, web services, and xml-based (vs. registry) configuration API, this should be easier than ever.

I wonder why this idea never took off. Is this like coding with fixed-width fonts where people are so stuck in the same way of doing things?

Follow

Get every new post delivered to your Inbox.