For Caleb's final release, we had a quick, short but really good release cycle. Despite losing Chandler and Kyle for two days during the middle, we got a Release Cycle done in one week. We implemented one feature, fixed a ton of bugs, folded some user feedback (the first!) and did some plumbing. This was our most successful cycle so far.
The feature we implemented was
- Allow users to upvote and downvote other user's localizations.
If you're familiar with reading features and creating Domain Models or Use Cases, you know that there are three really big parts to that. The users, the votes and the localizations. We already had the localizations; but we finally implemented the users domain model. I'm pleased that we didn't fall into the trap of focusing on users too much too early.
We also fixed ..a few.. bugs:
- Issue 61 ñ Not encoding strings correctly.
- Issue 54 ñ Sidebar Navigation Error
- Issue 51 ñ Welcome window should have a method to close?
- Issue 48 ñ Errors are not properly reported to users
- Issue 55 ñ Send Feedback not forgiving
- Issue 53 ñ Resource Bundles and Others on Sidebar do nothing
- Issue 60 ñ Canít tell which Resource Bundle is being edited.
- Issue 52 ñ New, Open, Save all do nothing
- Issue 50 ñ Multi-line disclaimer is editable
And we folded in some user feedback (this early?? Yes!):
- Issue 47 ñ .strings files are not parsed correctly
- Feedback form editable area is not set off
- Save As is difficult to get to
- Some of the bugs mentioned above
So, yeah, there was a lot done in a short week. We put some time into this sucker. And, I'm proud of it. Everything came together smoothly. We are really getting a handle on this framework and our architecture is really shaping up.
Speaking of architecture, we refactored it from a big ball of mud to a nice, structured, delegate-oriented MVC architecture. The controllers are actually layered, as well, based on function. Consult the following graph:
Here we can see our Controller architecture. The AppController also has a reference to MainView which is the window that you see at startup (and will continue to see.. we have a single window app). The BusinessLogicControllers have references to more specific views that go in the Content Area (see our definitions page on GitHub).
This architecture logically separates the controllers into a hierarchy that supports our application. Each controller has a delegate reference to the parent controller so that it can pass information up, if needed. Sometimes this goes to the AppController but not always. For example, a BusinessLogicController can tell the ContentViewController to transition using the TransitionManager.
Sometimes, though, we do need to pass it up to the AppController. For this, we create a message passing system the piggy-backs on the Objective-J message passing (less work for us! Yay!) and the AppController just passes those messages along to the appropriate locations.
Models are referenced by Controllers. We've been tossing around ideas to break this dependence but no good solution has evolved yet. We'll see where that heads.
For this release, we also implemented error handling (told you! Plumbing). None of us really had any good experience with this so we went with a system that handles errors in two different ways.
First, there are application-wide errors, such as database access errors, that are reported up to the AppController which will handle them. Then, there are local errors, such as invalid email addresses, that we handle locally to the specific business logic controller which displays an appropriate UI for that error.
This allows us to have a general error handling protocol and a granular user interface error handling protocol. The general error handling automatically reports to the server which allows the team to debug these unexpected errors. The granular error handling allows us to create a better experience for the users. For examples, users are presented with a pleasant UX message inline for invalid emails rather than annoying alert boxes.
We did a lot to improve the user experience for our project. When I say "we," I mean Chandler and Kyle did. They both worked on our user interface files and worked to resolve those issues. Chandler created the voting mechanism, the new splash window (which is sweet) and the new editing paradigm. Kyle worked on the new user login and registration windows.
We're getting better at this. This cycle was much smoother than the others. We even finished 6 hours early! I think we're getting the hang of this. Expect even more velocity increases in the near future.
I haven't spoken to Chandler or Kyle about this yet, but I think spending more time on the use cases, as a team, helped us define what we wanted for this release. With those goals in mind, we were able to move forward relatively independently (we also pair and work in the same room, though).
The best part is that we are, by no means, slinging code. Our architecture improves every day. We spend time refactoring and reading and understand each other's code. We are, in effect, producing a product that I'm going to be glad to hand off to Omni.
Here we go. Did we improve?
Number of Methods: 85 Number of Tests : 38 Tests per Method : .447 Number of Classes: 24 Methods per Class: 3.541
For tests per method (after removing view code--we'll not count that) we can see that it improved but it is still dangerously low. This is because I was too lazy to finish rewriting all of the tests for the Models. I'm working on it. I promise. It's getting better and we're practicing TDD so it should eventually get to >1. Hopefully next release.
For methods per class, it went up. Not a lot, but probably too much for my taste. I think this could be due to our heavy use of instance methods when they should be private methods in our controllers. If I remove that, it goes down to ~75 which is right at 3 methods/class. So, though this increase is alarming, we can easily fix that.
So, overall, we're getting better. We've got some work to do. But, let me tell ya, the architecture just feels right. So from a developer point of view, the hard part is over. Now we just have to design correctly on a business logic and domain logic scale (still difficult!).
That's all for now! Look for a screencast to show off our sweet UI.