Sunday 19 August 2012

Avoid ABSTRACT Classes!!!

Ahem... In business enterprise software. I will put forward the case that 95% of the time there is an alternative to a design involving abstract classes that will leave you with DRY, well-tested code and without the inherent risk that comes with inheritance. (That risk being a big jumbled spider web of parent-classes and subclasses that inevitable happens after x number of developers touch it.)

Back when I learned how to do OO in large codes bases.... Oh those 6 long years ago... I worked in London and was influenced by a few very awesome developers. We were doing C# and I remember this team where the leaders said 'No abstract classes.' And the code was beautiful. It might be said that we all just really cared. But, I have worked on very few teams where the majority of coders didn't care. We always care and strive for beautiful code. Anyway, today I find myself back in the US and working in the Java world, doing android development. And I find abstract class use everywhere. Everyone embracing it. And honestly, I see it lead to a tangled mess 95% of the time.

I see the appeal. You reduce duplication. If you were to use an interface instead of an abstract class, you would have several classes implementing the same interface but what about the common functionality. That's what an abstract class gets you. You can pop the common stuff in the abstract base class.

I rarely see a problematic situation at the time of initialing setting this up. It's normally beautiful. You say 'Yeah! Look at that beautiful inheritance. This is great. No duplication.' DRY, right?

The problem comes when you have to come along later and add a little functionality here or there. Often additional layers get added into the hierarchy and you sprinkle the common functionality where they belong. So maybe you started with 1 abstract class and 4 classes extending. You come along a month or 2 later and there's 1 base abstract class, two other abstract classes extending this and a slew of concrete classes extending any of these 3 abstract classes.

If this doesn't sound scary, maybe it's never happened to you. Let me just overview the pain I feel when working with this sort of thing is.

1. It's nightmare for a developer who's unfamiliar with the codebase. Who's overriding what? Who's implementing what? Who's responsibility is what?
2. It's hard to unit test. Who do you test? Really, you have to test all the concrete classes completely. This includes the functionality they implement themselves and the functionality they get from any of their parents. You could say.. well, write unit tests for the parents and then don't retest in the subclasses. The issue here is that you can't test that the subclass is specifically using the functionality from the parent through interaction based testing (mocking and stubbing). To be sure it's using the right code, you have to unit test the specific functionality for that code.. wherever it is. So, you either have duplicate tests or incomplete test coverage.
3. It's often highly brittle to change. This is because it's inevitable under tested and often not completed understood by those augmenting functionality.

I can't say that inheritance is never right. In fact it often feels right. And if you're working in a small team where you can discuss design frequently catch these things turning into issues... maybe it's worthwhile embracing it more. My feeling is that if you aren't working on a small team.. and/or you have even a minimal level of turnover among you're developers. This problem will almost certainly rear it's head.

What is the answer?? Let's turn back to the things taught by the gang of 4 and that super genius, Martin Fowler.  There must be some wisdom there! I'll dive into this next. I just want to reread a few chapters and articles first.


Thursday 9 August 2012

Android Fragments

I've been developing in Android for the last 5 months. Aside from the normal learning curve when learning a new technology, my team and I have found Android's fragments a bit of a headache. The android documentation is great. But there are a few things they don't explicitly mention that I really would have found useful to know or think about up front.

There are two options for using fragments, really. At least when looking at it from a high level. And I didn't realize the benefits or drawbacks of either of these... or the implications.

Option 1- Implement it and manage it yourself. 

This is what I did first. In this sense it's still a sort of miniature activity. 
There are a few ways you can do this.

  1. Define it as a fragment in the layout that your activity inflates.
  2. In doing this, you can inject it into your activity (if you're using roboguice) or pull it out into your activity as you would any other layout component to operate on it or delegate to it.
  3. Use the fragment manager to load the fragment in a FragmentTransaction and then load it into your layout based on some id (within a LinearLayout or something).
This would allow you to toggle the fragment for a given section of your activities layout.

The first way I went was a little of both of these. As it seemed to fit the bill and I didn't know any betting. I have since found that managing many fragments within an activity in the above fashion does not scale well. Also, the thing mentioned in the first option... where you can grab your fragment from the activity and delegate to it. That turns out to also be a mess. Ideally, you want your fragment to live in it's own little world. Without having to talk to it's activity or whoever is holding it.

Option 2 - Use Android components 

(i.e. ActionBar, Menus, etc..) 

What happened in my situation was that the number of fragments I needed on my screen was growing. There was more and more stuff going on and now I needed to manage the interactions myself. There was realization at some point that... 'Hey, those Android docs going on and on about the Android way of doing things... maybe they can help here!' So enter a few useful components.


Action bars and menus manage Fragments for you! You just hook into the behavior they provide and tell them which Fragment and when. It also allows for an experience your user is used to from other Android apps.

This is pretty much the code used in the Android API demos code. But you get the idea...

ActionBar

It's much easier to keep the Fragment separated from the Activity. Thus decoupling and simplifying. For more code I suggest to see the API demos. They're very useful.

Conclusion


As normal, it really depends on what you want to do. If you have a complex interaction between many different components on your screen, I really feel now that using the suggested Android approaches is easiest. If you just need one little fragment... going with the hook it up yourself approach may be best. But knowing that these are the two option paths may help in making the decision.