April 15, 2015

Nestable

In my post on preferring composition to inheritance, I talked about the powers of the Decorator Pattern for adding behavior to something that already exists. Really, the decorator pattern is a lot like inheritance, just better in almost every way:

Instead of calling super when you need to access the parent, you use self.wrappedThing.

You get to explicitly disallow which messages get through to the wrapped object, instead of them all magically getting through to the superclass. This is a bit more work, especially if you have a lot of messages, but “explicit is better than implicit”, as PEP 20 says.

With subclassing, each subclass is locked to one superclass. With decoration, you can inject anything, since you just pass it in to the initializer. This makes testing way easier, since you can wrap anything, including a mock.

With subclassing, you have to decide at instantiation time which class you want to use and which behavior you want to add. With decoration, you can wrap the object with new behavior at your leisure, even wrapping one object in two different ways to add different behaviors to the same object.

You can decorate a decorated object, and you can continue to nest as many times as you want. At run-time, you can decide if you want to leave any levels of this nesting chain out.

And that nesting is what I want to talk about this week. They’re a lot like Matryoshka dolls. One goes into the next, over and over. But software is weird, so you can nest something that is the exact same “size” as the last thing. In the physical world, each nesting object has to get bigger than the last one. But in the digital world, the footprint of each object (namely, its type) doesn’t have to get bigger when it wraps something. What do I mean?

Let’s take a look at an example from Yegor Bugayenko’s blog. He has an interface (just an @protocol in Java-land):

interface Text {
  String read();
}

And he creates a chain of nested decorators to add a bunch of behavior to a core object:

final Text text = new AllCapsText(
  new TrimmedText(
    new PrintableText(
      new TextInFile(new File("/tmp/a.txt"))
    )
  )
);
String content = text.read();

That core object is the text from a file, and, crucially, he’s able to add all that stuff without increasing the footprint of each nested object beyond the Text interface that he defined above. The added benefit here is that you don’t have to expose a bunch of methods on each layer. Just conform to the protocol, and you’re good to go.

I adopted this pattern for Instant Cocoa’s data sources. Data sources in Instant Cocoa represent a collection where elements are fetched with index paths. You can browse the code for Instant Data Source. Here’s a truncated version of the ICDataSource protocol.

@protocol ICDataSource <NSObject>

//...

@property (nonatomic, assign, readonly) NSUInteger numberOfSections;
- (NSUInteger)numberOfObjectsInSection:(NSUInteger)section;
- (id)objectAtIndexPath:(NSIndexPath *)indexPath;

//...

@end

From this protocol, we derive several concrete implementations. First, ICSimpleDataSource, which is initialized with an array and represents a data source with one section. We also have ICRemoteDataSource (and ICPaginatedDataSource), which is capable of asynchronously fetching a remote collection of objects, mapping them to your domain, and presenting them as a data source. These two data sources are simple and straightforward.

Where ICDataSource objects get interesting is how you can nest them. ICSectionedDataSource is initialized with an <ICDataSource>, and uses its contents (along with a sectioningKey) to present a new data source, with a section for each unique value of the sectioningKey. Because it takes a data source instead of a plain array, you can use either ICSimpleDataSource or ICRemoteDataSource (or any data source of your own choosing, such as one that is initialized with an NSFetchRequest and fetches Core Data objects).

Another example of nested data sources is ICMultiDataSource. ICMultiDataSource is initialized with an array of data sources, and each sub-data-source it holds becomes its own section. (There’s an option to preserve subsections.) Again, since everything is built on this one protocol, we can wrap any combination of other data sources, including any of the ones previously mentioned, or, of course, your own custom ones. And again, its type “footprint” is still only <ICDataSource>, no matter what sub-data-sources it’s composed of.

You could also imagine something like an SKShowMoreDataSource, which would present the first, say, 3 objects, and then an object that is a placeholder for a cell that says “Show more…”. When the user taps on that cell, you could extract the full data source and pass it to a new table view controller that would present the full list.

In its original conception,ICPaginatedDataSource was a subclass of ICRemoteDataSource, which was a subclass of ICSectionedDataSource, which was a subclass of ICSimpleDataSource. This architecture was so limiting: since the “footprint” of each object included the footprint of all the classes above, it was hard to test all the various options and configurations. Now, you can inject any custom data source you want at any level, and the provided utility classes will use them correctly. Since they now all present the same interface and only the behavior changes, testing them is easier and they’re far more flexible.

April 7, 2015

The Object Graph

During the Q and A of the Sandi Metz’s last talk from Ruby Conf, she said something interesting:

Polymorphism is fine as long as it’s shallow and narrow and at the edges of your object graph.

I’ve been turning this quote around in my head for a while, especially the phrase “edges of your object graph”. What is an object graph?

A graph is an object with nodes (or vertices), and links that connect those nodes together. Normally, those links are called “edges”, but we’re already using the word “edges”, and I don’t want to complicate the terminology.

So in your app’s world, you have a graph. Your app delegate is probably where it starts. It holds on to the window and the root view controller, which in turn hold on to a bunch of other stuff, and so on. Each of those connection points is one of the “links” in our object graph. static pointers that hold things like singletons can also be the start of graphs.

But a really good object graph looks more like a tree than a graph. When your object graphs looks like a tree, the data flow is much clearer, and it’s easier to understand. Each object only controls its children, and children can only be changed by themselves or by parents; no other parent from another branch can change them. You might have one big trunk in the middle (ideally, an app coordinator), leading out to smaller branches (child coordinators and child view controllers), and into smaller and smaller components, like your views, models, and the rest of your objects. An aside: this is why coordinators are so valuable: they break up dependencies between your view controllers. The branches of your object tree don’t touch.

Now, what did Sandi mean about the “edges of your object graph”? Let’s not use the word “edge”, since it’s overloaded in the context of graphs. Let’s use the word “boundaries”. She’s talking about the tiniest leaves of our tree. Polymorphic objects are okay by Sandi as long as they are only referred to, instead of doing any referring. And this makes a lot of sense! Polymorphic classes are dangerous because small changes in them ripple to all of their subclasses and users. By making sure your inheritance hierarchies stay small and well managed, you can contain that complexity. When you refer to other objects, you’re more fragile. If you’re only referred to, a stable interface is the only thing you need to keep from breaking anything else.

In addition to your object graph, you also have a dependency graph. Here, your nodes are classes instead of instances, and your links are #imports instead of object ownership. (You can use scripts to analyze your dependency graph.) Recently, I’ve been working on a new extension for the Genius app. And importing even a single model class into the extension project requires a cascading series of imports that eventually sucks most of the app’s classes into the extension. It would have been great to have very clearly defined boundaries, so that I could import a module of code (like, say, the entities, or the authentication module) without dragging a ton of unrelated code along. Like in the object graph, structuring my dependencies like a tree here would have been very helpful.

It makes me think that it would be great to have two types of objects, separated into layers.

One is the “independent” layer: objects in this layer have very few dependencies and just do simple stuff. It’s your business logic, implemented as entities, policies, value objects, etc. It’s also your views and view controllers, since those ideally touch very few other things. But these objects very simple, and they’re easily transferred from project to project. These are the “pure objects” of the world.

The other is the “dependent” layer: this glues this stuff together at a highly-abstracted level. It doesn’t contain very much code, and the code that it does contain is in the language of the domain. It hooks into the lower level through object ownership, and gets called through blocks, delegates, protocols, and other communication patterns. These are the “coordinators” of the world.

The idea is that you could totally change the coordinators and go from an iPad app to an iPhone app to an extension, without having to change the independent layer at all. You can make classes so small that they and all their friends can fit in your pocket.

It reminds me a lot of an idea that Gary Bernhardt developed (paywall), which is the “functional core”/“imperative shell” split. Andy Matuschak has been pushing for it in our own community. He reveres Swift’s structs because they’re “inert, isolated, and interchangeable”. Having something that can’t change out from under you is very valuable.

It’s also somewhat reminiscent of Uncle Bob’s entity-boundary-control architecture (text). When he writes code for a Rails app, none of his business logic is tied to the framework. Instead, he can move his domain logic to any other framework quite easily, instead of stuffing it all into an ActiveRecord::Base subclass and being coupled to Rails forever.

When considering the object graph and the dependency graph, fewer links are better. Fewer cycles are better. I’m hoping to write code in the future that minimizes those two things and is all the more portable for it.

March 26, 2015

Announcing Instant Cocoa

I've been working on a library for a little while now to make developing iPhone apps easier. The library adopts a number of the patterns that I've talked about here on my blog, and is meant to fill in a lot of the gaps left by Apple's frameworks. It's out today. You can find it at instantcocoa.io, and on Github. It's a very ambitious project, and there's still quite a bit of work left to do. But it's worth launching now and getting feedback from the community.

I'm still working on documentation, so expect to see some changes at instantcocoa.io/docs. I'm hoping to have the documentation ready in about 2 weeks.

I want to give a big thanks to Tyler Galpin for designing the site and the amazing icon.

Screen Shot 2015-03-26 at 11.20.41 AM

My hope is that this project can help us all make better iPhone apps. If you see anything you'd like to comment on, please feel free to make a Github issue so that we can fix it. It’s going to be a bright future!

March 2, 2015

Emergence

A crufty codebase is an experience every developer has had. From the outset, you plan for a beautiful architecture, elegant data flow, and simple code, but after years of bug fixes and feature additions, the codebase morphs into a husk of its former self, displeasing and tiresome to work on.

As you write your programs, you make sequential straightforward changes, like adding features or fixing bugs. Each individual change is, as you intended, good, but the combination is something that neither you nor anyone else on your team can be satisfied with. This concept has relatives in systems theory, philosophy, economics, and political theory. In this post, we’ll explore some of those theories and use them to evaluate our practice.

As a sort of fictional case study, we have Mike Hadlow’s The Lava Layer Anti-Pattern. In it, he describes a situation where each of four developers continue to modernize the data layer of an app. Through no fault of management or any of the developers, the final state of the code is fragmented and confusing, various modules in disagreement.

Broadly, this concept is known as emergence. Emergence describes a system whose high-level behavior is fundamentally different than its low-level components. Emergence can be seen in lots of fields, including (but certainly not limited to) biology, computer science, and traffic. Note that the theory of emergence doesn’t ascribe any value to the high-level behavior; neutral low-level actions can cause both positive or negative high-level outcomes. The cruft in our codebases comes from a series of changes that weren’t intended to have an effect on the overall structure of the program, but nevertheless do.

There are two theories in economics that are useful for analyzing codebases. First, broken window theory. The broken window theory suggests that fixing little things like broken windows or graffiti reduces the incidence of more serious crimes, like muggings. There are broken windows in your codebase, and you can fix them them pretty easily. Increasing consistency will make future committers more reticent to make unsightly and changes. Use tools like clang-format to clean up whitespace and make code conform to standards, reducing needless comments in your code reviews.

The second economic theory that’s notable here is the Tragedy of the Commons. The Tragedy of the Commons refers to a simple idea: in a situation where a group shares a common resource, individuals can exploit that shared resource, enjoying the gains personally, and distributing the costs communally. It’s pretty easy to see how this applies to environmental issues, like pollution or overfishing.

The prototypical example is a group of ranchers that share a plot of land for their cows. As each rancher considers adding another cow to their herd, she evaluates the potential upside and downside. Upside: one more cow, which means more milk/beef/hide; downside: overgrazing of the shared land, for which the costs of repairing will be shared among all the ranchers. This is also known as an externality.

Think of your codebase as the commons: multiple people working in the same space. When working on a story or a ticket, you can take out technical debt at any point. Technical debt is formed when code is written suboptimally to optimize some other value, usually time. Especially on a team, taking a shortcut and finishing your work more quickly will make you look good in front of your teammates or your manager. Since someone has to pay back that debt, so you’re incentivized to throw your teammates or even a future version of yourself under the bus.

And it doesn’t even require ill intentions. Emergence can happen even when you have no designs either way. Have you ever reviewed a pull request that looked great in diff form, but when browsing the code later, it became obvious that the fix was unsound? It’s certainly happened to me. It’s possible (and sometimes even easy!) to accidentally write pull requests in such a way that they look good on Github, but closer examination of the fix’s surroundings reveals that it solves the problem in the wrong place or in the wrong way. This is most obvious with duplication. A diff can’t tell you if you’ve rewritten code that already exists in the codebase, and that can be a really simple way of building up technical debt, having code fall out of sync, and leaving holes for bugs to hide in.

Meditations on Moloch is an awesome blog post generalizing this concept to society, capitalism, and ideology. In it, the author quotes a short passage from the Principia Discordia, a conversation between a human and a goddess, which sums it up nicely.

”I am filled with fear and tormented with terrible visions of pain. Everywhere people are hurting one another, the planet is rampant with injustices, whole societies plunder groups of their own people, mothers imprison sons, children perish while brothers war. O, woe."

WHAT IS THE MATTER WITH THAT, IF IT IS WHAT YOU WANT TO DO?

"But nobody wants it! Everybody hates it."

OH. WELL, THEN STOP.

But how do we stop? Emergent behavior acts like entropy: reversing it takes work and, more importantly, coordination.

There are no real secrets here. A crufty codebase demands attention, and it won’t fix itself. Code will need to be refactored over time. For a team, coordination mostly happens at the code review level. This doesn’t just mean checking for style, but checking, at a very rigorous level, for flaws, duplication, confusing code, and spots that will otherwise cause problems in the future. Code review makes sure the team is synchronized.

For teams of one, solving your problem involves holistic attention to your codebase. No one else is around to catch your mistakes, so you have to put a lot of deliberation into it. On the other hand, there’s no one else to muck it up after you fix it.

But the best solution is just to never get yourself into the problem. Mike Hadlow suggests generally waiting for more maturity in the technologies that you introduce. He also seems to recommend waiting until you can replace a component wholesale instead of piecemeal.

This is your craft, and building good software is your primary job. Write code that doesn’t need documentation; barring that, write documentation. Write tests. Don’t write comments, but use good naming and method extraction to obviate them. With attention and coordination, you can make your codebase enjoyable to work in again.

February 23, 2015

Consistency is a Virtue

Last week, I talked about doing things on the right level. In some ways, that post is a plea for consistency. In the world of programming, consistency is a worthwhile ambition. Here, Brent Simmons requests some sanity when it comes to dot-notation versus bracketed message sending.

Let’s talk about a couple of languages. Smalltalk and Ruby are very similar languages, the latter rooted in the former. Smalltalk gets consistency right, to a fault. Everything is an Object, including numbers, booleans, and the idea of nothingness. Do you want Swift-esque enumerations? Use polymorphism. Everything is an Object. There’s one type of nil, compared to Objective-C’s four (nil, Nil, NULL, and NSNull). Smalltalk values consistency so much that it throws user expectations out the window. Remember how I mentioned Smalltalk is consistent to a fault? In Smalltalk operators (like + or *) are just methods that are defined on objects. However, messages have precedence from left to right, so 3 + 4 * 5 evaluates to 35, as though your code read 3.plus(4).times(5), instead of adhering to normal mathematical order-of-operations, as you might expect. (Seems like Alan Kay can invent OO, but can’t get OoO right!)

Ruby also has this Everything is an Object concept, with one object for nil, etc. But in Ruby, purity gives way to pragmatism, and operators like * have a higher precedence than operators like +. However, closures, simple in Smalltalk, are made complex in Ruby. There are three types of closures in Ruby: block, Procs, and Lambdas. The differences between them are unimportant and enumerated elsewhere. With three types of closures, knowing when to use which becomes an exercise in expertise rather than ease. It’s not immediately clear when you should use each or what the performance ramifications are. The stewards of Ruby let implementation details get in the way of the “user interface” of their language. Developers don’t care which closures can’t go in arrays and they don’t want to have to think about what the return keyword binds to — they just want to write code. Keep it simple for them.

Objective-C, like Ruby, is also based in Smalltalkian roots. In trying to make Objective-C more performant, however, compromises were made, and the designers used primitives to represent concepts like truth, falsity, and numbers. These primitives, since they aren’t objects, can’t go into native collections like arrays and dictionaries and must be “boxed-up” in a special class. That class, NSNumber, has no facility for manipulating the numbers therein, which leaves the developer constantly boxing and unboxing numbers to use them. Swift smoothes over this particular issue by treating integers and other numbers as structs, which retain the performance characteristics of primitives, can be stored in collections, and can be messaged.

And consistency trickles down from languages into standard library design. Apple does a great job with consistency in API design. Long, precise method names make it extremely specific what types you need to pass in, what type you’ll get, and what the function does. Apple even provides a WWDC talk about how to design your APIs.

Contrast with this PHP’s standard library. rtrim, strlen and str_replace are all functions that operate on strings, but they all have differing prefixes. (It turns out that this is because PHP’s first function lookup was based on the length of the function name, so functions needed names that were as varied as possible. The height of absurdity.) Compare these function names to the related Foundation method names. Here, consistency gives programmers a super power — the ability to guess what the function should be called — and autocomplete can take it from there.

And it affects your own code as well. Let’s take an example, like view allocation. There are a lot of places where you can set up your subviews. You can do it in your UIViewController’s -loadView or -viewDidLoad, or you can do it in UIView’s -initWithFrame:, or in Interface Builder, or anywhere else (it’s just software, after all). My preference is a lazy initializer:

- (UITextField *)usernameField {
    if (!_usernameField) {
        UITextField *usernameField = [[UITextField alloc] init];
        usernameField.placeholder = @"Username or email";
        [self addSubview:usernameField];
        
        self.usernameField = usernameField;
    }
    return _usernameField;
}

Once allocation and configuration are always done in the same way, you no longer have to think about where it goes. New method, every time. You never have to think about where to find it, either. Command-click on the getter for the view, and you’re taken right to the place where the view is created and configured. Now, if we extract the line of code that sets the placeholder, we’re suddenly left with a method that relies only on the name and class of the property.

- (UITextField *)usernameField {
    if (!_usernameField) {
        UITextField *usernameField = [[UITextField alloc] init];
        [self configureUsernameField];
        [self addSubview:usernameField];
        
        self.usernameField = usernameField;
    }
    return _usernameField;
}

Is this ripe for metaprogramming? You’d better believe it. If we mark the usernameField property as @dynamic, we can catch it in +resolveInstanceMethod: and create and configure it dynamically:

@implementation SKView

+ (BOOL)resolveInstanceMethod:(SEL)sel {
    NSString *selectorName = NSStringFromSelector(sel);
    
    NSString *viewName = [self viewNameFromSelector:selectorName];
    Class viewClass = [self viewClassForPropertyNamed:viewName];
    SEL configurationSelector = [self configurationSelectorForViewNamed:viewName]; //-configure<ViewName>
    BOOL isSetter = [selectorName hasPrefix:@"set"];
    if (isSetter) {
        IMP implementation  = imp_implementationWithBlock((id) ^(SKView *self, UIView *newView) {
            return [self.views setObject:newView forKey:viewName];
        });
        class_addMethod(self, sel, implementation, "v@:@");
        return YES;
    } else {
        IMP implementation  = imp_implementationWithBlock((id) ^(SKView *self) {
            if ([self.views objectForKey:viewName]) {
                return [self.views objectForKey:viewName];
            }
            UIView *view = [[viewClass alloc] init];
            [self addSubview:view];
            [self.views setObject:view forKey:viewName];
            if ([self respondsToSelector:configurationSelector]) {
                [self performSelector:configurationSelector];
            }
            return (id)view;
        });
        class_addMethod(self, sel, implementation, "@@:");
        return YES;
    }
}

@end

Consistency isn’t just a facet of good code, it is good code.

(more…)

February 17, 2015

The Right Level

Doing things at the right level is very important for long-term, sustainable programming. One theme of this blog is how to beat Massive View Controller. Massive View Controller happens because you’re doing things on the wrong level. Things in the model layer, like values and enumerations, bubble “up” to the view controller, while organizational responsibilities, like coordination, bubble “down” to the view controller. The combined complexity of all this code makes the view controller become tangled with itself and impossible to grok.

What do I mean by “the right level”? Let’s dive in.

The Knight’s Template Method

If you have one thing, and you want to make another thing, using inheritance to solve that problem will always put you in a bind. I talked about sidestepping inheritance for share code in last week’s Prefer Composition to Inheritance. This week I’d like to talk about when the extenuating factors win out, and you have to use inheritance.

If you subclass from one thing to make another thing, you’re failing to keep things on the right level. To maintain order in your code, remember: you can’t have just one specialization. In this case, you have three things: the shared code, which goes in a superclass; and the two branches of differing code, which are the specialized subclasses.

This type of structure creates two levels. The top level, the superclass, contains the abstraction, the prototype for the concept; it shouldn’t be instantiated. The bottom level contains the concretion, the congealed form of the ideas; it can’t exist without the upper level. This is the Template Method pattern. It’s probably an anti-pattern. Nevertheless, when you have to do it, do it right.

Color-coded

All modern editors use color to signify meaning. Constants are one color, methods another, local variables a third. This highlighting is designed to help readers parse code more easily, by allowing the user to focus on chunks like literals or instance variables at once. One new way I’ve learned to use syntax highlighting is called the squint test, and it’s a litmus test for the clustering of code.

The squint test is simple: squint at your code, and make sure similar colors sit together. If they don’t, you might not be doing things on the right level. In its simplest form, it will compel you to move string literals to the top of a file. You can use it for much more, though. The squint test can also help you separate the semantic components of your class that are related. In this talk, Sandi Metz refactors the Gilded Rose kata, and when we squint at the product of her refactoring, it’s clear that the right-hand side of the slide is better separated and better factored.

N.B.: you’d be forgiven for thinking she needs to refactor this more. She does, and her final result is awesome. I highly recommend the talk. Even better, try the kata out before you watch the talk.

At C level

Objective-C is designed as a layer on top of C. It can do everything that C can do, and then some. You could ship an iOS app written entirely in C or C++ if you wanted. This interoperability has been a boon to developers, allowing them to use a vast array of libraries in their apps that were never intended for use in Objective-C.

However, it’s also provided confusion to developers writing code. Should this simple string transformation be in a category on NSString or a C function that takes one string parameter? A category incurs the cost of an objc_msgSend, but dipping down to the C level incurs a context switch for the reader of the code.

When I’m reading C code in an app, I wonder what dropping to C means, semantically. Does it mean that the code needed to be more performant or that the author was more comfortable writing C than Objective-C? What should I infer from the switch? Staying consistent and using one language prevents these questions from being asked; also, staying consistent in your basis for dropping down to C guides your reader into inferring more meaning from your code.

Preprocessor macros are similar. They have a ton of value in providing code generation and metaprogramming to more static languages, but they incur a context-switching cost as well. Worse still, macro code doesn’t get highlighted and there’s a bunch of slashes everywhere, making it hard to read. Do string literals need to go in a #define, or can they be class or instance methods in an Objective-C class?

In the latest version of the Genius app, we support annotating other websites. As you can imagine, this requires calling a lot of JavaScript from within Objective-C. All of this JavaScript is inside NSString literals, which, like preprocessor macros, have no syntax highlighting. To alleviate this as much as possible, the JavaScript is clustered together in the same object, and hidden behind a type-safe Objective-C interface. If you need to mess with the JavaScript, there’s one .m file to go to. No more grepping for stringByEvaluatingJavaScriptFromString:.

Staying on the right level helps keep your code legible to not only your teammates but also future versions of yourself.

Layer cake

Your app is composed of several layers: data storage, manipulation, presentation, and so on. The more clearly the layers are defined, the more obvious it is when code from one level bleeds over into another level. Unfortunately, we’re stuck with the ill-defined and meaningless name Controller, and we have to work with it. Presentation code might go into the controller at first. But as it gets more and more bulky, it can split into its own layer, like a cell undergoing mitosis. This new, well-defined layer should have less trouble keeping out-of-scope responsibilities out and keeping its role clear.

Wrapping up

These examples seek to show two things: 1. working at the wrong level makes your code more complex and hard to understand, and 2. working at the right level smoothes out your code and keeps it easy to maintain.

However, keeping your code neatly organized in these ways requires rigor. No amount of automated testing or static analysis will reveal that your code is poorly structured. Well-crafted programs come from the human element. Meticulous planning and code review help you critically analyze the code until it satisfies you.

February 9, 2015

Layout Abstractions

In the beginning, there was CGRectMake. It was hideous.

_badge.frame = CGRectMake((self.frame.size.width - (widthOfBadge))/2,
    imageViewSize + 5,
    widthOfBadge,
    sizeOfText.height);

Autoresizing masks sometimes helped, but they weren’t as flexible as their names suggested.

_imageView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;

(This is all real code. Instance variables have been changed to protect the innocent.)

As more programs were written, techniques were discovered to abstract away some of the mess. But it was still procedural C, and it was still kinda hard to read.

Then came Auto Layout. Auto Layout is slow, confusing, and verbose. But it’s declarative, and it solves a system of equations every time it lays out your code, which is just plain cool.

These are all layout abstractions, but none of them are great. What do we want out of a great layout abstraction?

  1. We want it to be code. Interface Builder is an impressive tool that gets more impressive with every release. But it’s fundamentally not as expressive as code, doesn’t play well with source control, and generates components that aren’t reusable (we can’t conditionally apply a layout to a view, for example).
  2. We want it to be fast. We’re dealing with primitive numbers here. There’s no reason calculations should take a long time.
  3. We want it to be simple. You should be able to glance at it and tell what the layout looks like. The code should be concise and straightforward.
  4. We want it to be expressive. You should be able to describe any layout with the abstraction.
  5. The abstraction should be very malleable. Easy things should be easy, and hard things should be possible.

Since no layout abstraction can satisfy all of these criteria, we’re making a trade-off with any solution that we pick. Auto Layout trades speed and simplicity for the ability to be expressed in Interface Builder. Anyone who’s tried to set up constraints in code knows how painful using even the visual format language can be. Libraries like CompactConstraint or Cartography can help with the verbosity of Auto Layout, but the point I want to press here is that Auto Layout isn’t the ultimate form of expressing layouts.

Even though Apple engineers have been subtly and not-so-subtly pushing us towards Auto Layout since it was released, and maybe one day we won’t be allowed to use anything but Auto Layout, computers are Turing-complete. You don’t have to wait for anyone: write your own future.

For me, the most natural way to think about it is that views should have a layout, the same way they have subviews. You could hot-swap this layout for lots of reasons: to perform an animation, present the same views on different devices, or A/B test different layouts. If your view is HTML markup, your layout object would be the CSS.

Maybe you like the rectangle-slicing CGRectDivide model of layout. What would that look like if it were an object, instead of a procedure? Can it be more than just C functions that are called sequentially? Does our RectDivider object have access to the class of its target view? Can it use names instead when applying rects to subviews, to reduce coupling?

Or maybe you like Java’s configurable Layout Managers. Layout Managers let you pick a strategy, like “fill”, or “stack”, or “grid”, and pass in a list of views which will have that layout strategy applied to them. Here’s an exploration of them in iOS, and here’s a library that approaches layout managers in a slightly different way.

Or maybe you like CSS’s flexbox. Flexbox is a new CSS display style that not all browsers have implemented yet. It lays out views in a row (either horizontal or vertical) and lets you assign which subviews have fixed width (or height), and which subviews should be stretched out to fill the view. You can imagine how powerful this can be when coupled with a scroll view.

What do I want? Sometimes I just want to write an object and have the layout engine just figure out what to do:

@implementation SKUserCellLayoutSpecification

- (CGFloat)imageViewDimension {
    return self.height;
}

- (CGSize)sizeForImageView {
    return CGSizeMake(self.imageViewDimension, self.imageViewDimension);
}

- (CGPoint)originForLabel {
    return CGPointMake(0, self.imageViewDimension);
}

- (CGFloat)widthForLabel {
    return self.width - self.imageViewDimension;
}

- (CGFloat)heightForLabel {
    return self.height;
}

@end

Maybe something this abstract could finally prevent us from having to write our layout code twice: once in -sizeThatFits: and once in -layoutSubviews.

But most of the time I just want to pick between them all. I want a protocol that every layout conforms to, and I want to be able to swap between them at will. Maybe some of the concrete implementations are backed with Auto Layout, and others with a layout manager. You’d finally be able to pick the right tool for the job. And that seems like a future worth writing.

Further exploration

There are a few places where I drew inspiration for this post, in order of age:

  • Colin T.A. Gray, who worked on MotionKit, a part of RubyMotion, uses Layout objects to push everything down from the view controller, not just for positioning views. Nevertheless, his library provides a cool (Ruby) DSL for adding constraints and fetching frames. He gave a talk on MotionKit in 2014, which you can find here (direct link to 13:47).
  • Facebook’s Paper uses two abstractions, Metrics and LayoutSpec. You can see more in their tech talk, Building Paper (direct link to 20:55). This is a pretty cool structure, and they separate calculation of their rects from their application, solving the -sizeThatFits:/-layoutSubviews problem. Their LayoutSpecs can also be defined in JSON, meaning their designers can write them and check them in, with no help from engineers.
  • Facebook’s React Native has a reimplementation of Flexbox for use in their Javascript app engine. You can find out more in the React Native Keynote (direct link to 13:07). While it’s probably designed for use only in their JS framework, it would be awesome if we could even apply it to arbitrary UIViews.
  • Josh Abernathy’s SwiftBox is an implementation of FlexBox for Swift.
February 2, 2015

Prefer Composition to Inheritance

There's a lot that I want to say about composition and inheritance, but Sandi Metz covered the basics better than I could have at the first Code Genius event. We don't have the rights to share the video, but she'll be giving the same talk at RailsConf this year. You should absolutely check it out when it goes up. I'll link to it here when it's posted. So, since she already covered why inheritance will fail you, I will explore a few techniques we can use to avoid it.

Interior Decorating

Let's imagine a new networking library. Network requests are defined by template objects that conform to a protocol:

@protocol SKRequestTemplate <NSObject>

@property (readonly) NSURL *baseURL;

@optional
@property (readonly) NSString *method;
@property (readonly) NSString *path;
@property (readonly) NSDictionary *parameters;
@property (readonly) NSDictionary *headers;

@end

With this design, we're given a lot of flexibilty in how we define our request templates, and we can rely on some other component to convert each template into an NSURLRequest, and that request can be fired by some other uninteresting machinery. To create the request, we need to grab each property from the template in turn.

//...
mutableURLRequest.HTTPMethod = [template method]
//...

When we go to use these templates however, we notice that we can't have any default behavior. Since it's using a protocol and not inheritance, we can't use the superclass to set the default method to GET. We can avoid this with a nil-coalescer:

//...
mutableURLRequest.HTTPMethod = [template method] ?: @"GET";
//...

We run this code and realize that we have an even bigger problem. If there's no implementation defined for -method, our template is going to blow up! We can do something ugly like:

//...
mutableURLRequest.HTTPMethod = [template respondsToSelector:@selector(method)] ? [template method] : @"GET";
//...

But this is inelegant and we wish we could just force our users to subclass something so that we can hide this behavior away. But don't fret! We have options outside of inheritance. To add behavior in a composition-friendly way, we use the Decorator pattern. Let's define something called a SafeTemplate:

@interface SKSafeRequestTemplate : NSObject

- (instancetype)initWithUnsafeTemplate:(id<SKRequestTemplate>)unsafeTemplate;

@property (nonatomic, readonly) id<SKRequestTemplate> unsafeTemplate;

@property (readonly) NSURL *baseURL;

@property (readonly) NSString *method;
@property (readonly) NSString *path;
@property (readonly) NSDictionary *parameters;
@property (readonly) NSDictionary *headers;

@end

We can now pass our "unsafeTemplate" into this object, and for each property, it wraps the execution in a check, and can return any default we choose:

- (NSString *)method {
    if ([self.unsafeTemplate respondsToSelector:@selector(method)]) {
        return [self.unsafeTemplate method];
    }
    return @"GET";
}

//...
URLRequest.HTTPMethod = [safeTemplate method];
//...

A particularly elegant note on this solution: the wrapper itself doesn't conform to SKRequestTemplate, even though its parameter does. This means that if we add a new method to the protocol and try to use it from the safe template, the compiler will groan at us. It must be defined on the safe template before we can use it, and we'll be reminded to add it there as well. Normally, with inheritance, your "contract" with the outside world includes all of your superclass's methods; with decoration, you only have to provide what you say you'll provide. Aaron Patterson documents a case where the rails/core team got bitten by this exact problem.

The Presenter pattern that I outline in 8 Patterns to Help You Destroy Massive View Controller is a more specific version of this technique. Value Objects are also really just a decorator around something like a string or a number.

And that's the Decorator pattern. It's very flexible, very useful, and a great weapon in the war on inheritance.

Strategery

One awesome thing that Sandi said is "There's no such thing as one specialization. If you’re specializing something, you have two things." This was a revelation for me.

Let's continue to work with our networking library. Using the data source pattern from 8 Patterns to Help You Destroy Massive View Controller, let's make an object called SKRemoteDataSource, which fetches a collection of objects from an API for display in table view.

@interface SKRemoteDataSource : NSObject <SKDataSource>

@property (nonatomic, weak) id<SKDataSourceDelegate> delegate;

@property (readonly) NSUInteger numberOfSections;
- (NSUInteger) numberOfObjectsInSection:(NSUInteger)section;
- (id) objectAtIndexPath:(NSIndexPath*)indexPath;

- (void)fetchData;

@property (nonatomic) NSURL *URL;
@property (nonatomic) NSDictionary *queryParameters;
@property (nonatomic) NSString *keyPath;

@end

This is a very useful class, but sometimes the remote objects are paginated. So we could subclass SKRemoteDataSource and make SKPaginatedDataSource. Hey, pagination is just a special case of a remote data source, right?

@interface SKPaginatedDataSource : SKRemoteDataSource

@property (nonatomic, readonly) NSInteger currentPage;
@property (nonatomic, readonly) NSInteger numberOfPages;
@property (nonatomic, readonly) BOOL hasMorePages;

- (void)fetchNextPage;

@end

While this seems reasonable, every change you make to the superclass will break the subclass. I can tell you this because I've written this exact code in this exact way before.

What I had was a bad version of the Template Method pattern. To implement the template method properly, you need to:

  1. create a superclass with all common behavior
  2. throw an exception from the superclass for all differing behavior
  3. and make your two subclasses (because you can never have one specialization!) and override the points of difference

Even properly implemented, however, the Template Method pattern is probably an anti-pattern. It's based on inheritance which will always strongly couple your components together. Fortunately, we have an alternative, which is based on composition.

We have two responsibilities here: downloading an array of items from an API, and presenting them as a data source. These two responsbilities have been tightly coupled together. Extracting the shared core will make simpler objects that can be used more often. When we wrap behavior in an object and inject it into other objects, it's known as the Strategy pattern.

The final solution was SKCollectionFetcher, which downloaded a collection of objects from an API. The paginated and regular remote data sources each had a collection fetcher, and the logic was no longer duplicated.

@interface SKCollectionFetcher : NSObject

@property (nonatomic, strong) NSURL *URL;
@property (nonatomic, strong) NSDictionary *queryParameters;
@property (nonatomic, strong) NSString *keyPath;

- (void)fetchCollectionWithSuccessBlock:(void (^)(NSArray *objects))successBlock failureBlock:(void (^)(NSError *error))failureBlock;
- (void)cancelCurrentFetch;

@end

@interface SKRemoteDataSource : NSObject <SKDataSource>

@property (nonatomic, weak) id<SKDataSourceDelegate> delegate;

@property (nonatomic, assign, readonly) NSUInteger numberOfSections;
- (NSUInteger) numberOfObjectsInSection:(NSUInteger)section;
- (id) objectAtIndexPath:(NSIndexPath*)indexPath;

- (void)fetchData;

@property (nonatomic, strong) SKCollectionFetcher *collectionFetcher;

@end

Since the data source and the collection fetcher are now separated, we can swap them out at will. In some cases, we'll need a slightly different collection fetcher, and that will work with our remote data source. In other cases, the reverse will be true, and we'll need a slightly different data source. For example, if we need relative pagination, which is based on timestamps, we can write a new data source while using the old collection fetcher. Writing code with composition makes this sort of flexibilty possible.

January 26, 2015

Categorical

-[NSString containsString:] was added in iOS 8. If you're writing a standard library, this seems like one of the most crucial components for string handling. And yet, it's been conspicuously absent since the early '90s, when NSString was created.

Apple gives you a function called -rangeOfString: whose functionality is a superset of this behavior. You can use a short snippet of code with -rangeOfString: in the place of -containsString::

if ([aString rangeOfString:searchString].location != NSNotFound) {
    //substring is found
} else {
    //substring is not present
}

Writing it this way is very tough to read, and code is read much more often than it is written. "The location of the searchString inside aString is not equal to 'not found'" is a tough thing to parse from code to English, especially because of the double negative.

Of course, you're currently screaming at me, "Just use a category!" And it's trivial to add this method to the NSString class. I can do it, and you can too.

- (BOOL)containsString:(NSString *)searchString {
    return [self rangeOfString:searchString].location != NSNotFound;
}

This is an unsatisfactory solution. There are three primary reasons why.

First, developers are lazy. If you search Github for rangeOfString, you will find pages and pages of open source repositories that use -rangeOfString almost exclusively in the place of -containsString:. Why didn't they just write the category for the message they needed? There's a lot of cognitive load to adding a file to your project. It also involves a context switch: instead of just writing the code you want in the place where you want it, you have to jump to a different place to add a different thing. The out-of-order nature of that kind of programming makes it very hard to do the right thing.

Secondly, category methods must either be prefixed — and ugly — or unprefixed — and go against Apple's best practices. Personally, I see prefixing as unnecessary. How many ways are there to write -containsString:? How many ways are there to write -firstObject? Nevertheless, I worry about method names -select: that could easily conflict (imagine a method that selects objects in a collection based on a block, like Ruby's Enumerable #select, or an IBAction routed through the responder chain, like -copy: or -selectAll:). The important thing here is that, whether or not I think prefixing is ugly, I also don’t like going against best practices. There isn’t really a way out of this trap. My code will be unsatisfactory either way.

Lastly, writing the method yourself in a category will always be less performant than the vendor's version. While I was writing my library Objective-Shorthand, I did some research in the runtime on -[NSArray reversedArray]. I found that even though it's not a public method, the SDK does actually respond to this message. It returns an __NSArrayReversed, which is ostensibly an class-clustered NSArray that accesses objects in reverse order. Most implementations of array reversing (including mine!) would call allObjects on the reverseObjectEnumerator, which creates a full copy of the array, the obvious and simple solution. Apple's implementation cleverly sidesteps this. You could imagine similar optimizations for other methods. Why this method isn't public, I don't know.

In using categories, the best we can do is bundle up all these obvious shortcomings into a single library, and use that one dependency. This is exactly what Objective-Shorthand attempts to do. And even in this "best" solution, we still have to import Objective-Shorthand everywhere we need it, or include it in the .pch file (which is probably an anti-pattern, since it makes your dependencies implicit).

There are other reasons as well why the bundling of all these categories together doesn't work. I did a quick proof-of-concept for a small state machine library a few weeks ago, and while Objective-Shorthand would have made my work a lot easier, I couldn't justify making other developers dependent on Objective-Shorthand, just to make my coding experience a little nicer.

So given these myriad reasons why categories aren't good enough, why will Apple not implement these methods? One common reasoning I've heard is that Apple's conservatism causes a reticence for API additions. Mattt Thompson asked an engineer at a WWDC lab why it took so long to add JSON support to the SDK:

Apple is a company with a long view of technology. It's really difficult to tell whether a technology like JSON is going to stick, or if it's just another fad. Apple once released a framework for PubSub, which despite not being widely known or used, still has to be supported for the foreseeable future. Each technology is a gamble of engineering resources.

This argument isn't very compelling! -containsString: isn't a new technology, nor is its usage in doubt. Our simple Github search from earlier shows that. Also, don't forget that this is the same vendor that added a dozen methods to NSString for manipulating paths. Conservative? Doubtful!

Other vendors have proven that it's possible to do this well. Ruby, for example, takes it to the other extreme: their Integer objects respond to methods like #odd?, #even? and even #gcd. Providing those methods in the standard library yields more readable code and it gives the vendor the opportunity to tweak and optimize them at later date, knowing that anyone who needs them will benefit from their optimizations.

All of the solutions available to developers — the unreadable -rangeOfString: dance, a utility object, small categories copied to each new project, or compiling them into one library like Objective-Shorthand — are insufficient.

In the same way that base types like Swift's Optional or JavaScript ES6's Promises must be built-in for proper adoption, these simple methods need to be available to all developers. Apple's proclivity towards leaving holes in their API forces developers into a bind. We must either write inexpressive, hard-to-read code, do needless work opening these classes back up, or leave a trail of dependencies in our wake.

January 20, 2015

The Coordinator

One of the biggest problems with the big view controllers is that they entangle your flow logic, view logic, and business logic.

When a table cell is selected, that delegate method typically looks like this:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    id object = [self.dataSource objectAtIndexPath:indexPath];
    SKDetailViewController *detailViewController = [[SKDetailViewController alloc] initWithDetailObject:object]
    [self.navigationController presentViewController:detailViewController animated:YES];
}

Three simple lines: get the object; create a view controller; present the view controller. In a simple app, this works great. Each view controller is probably used once, and in only one context. Coupling them together like this isn’t a dangerous proposition. As your app grows in complexity, however, the same view controller might get used in a new way or in a new place. Maybe it’s on the iPad. Maybe it’s in an extension. Maybe it’s a new flow for doing an old thing.

If the flow logic is encoded into the view controller itself, the view controller can’t be reused for its stunningly good looks without dragging all that flow code with it. Don’t forget, the view controller base class is prefixed with UI. It’s view object, and handling user flow is out of its scope.

In the code example above, the view controller knows how to create the next thing in the flow, and how to present it. In the third line of code, it tells its parent view controller what to do, which definitely seems backwards. And even worse, that flow code is distributed among multiple view controllers, each of which only knows how to perform the next step.

I used to think of the view controllers as the highest level thing in app, the things that know how to run the whole show. Lately, however, I’ve found many advantages to having the view controllers be bossed around by an even higher level object, one whose role is to marshal and manage all the view controllers in its purview.

I call these objects Coordinators, but I’ve also heard them called Directors. To really execute this pattern well, you need one high-level coordinator that directs the whole app (this is sometimes known as the Application Controller pattern). The app delegate holds on to the AppCoordinator. Every coordinator holds an array of its child coordinators. Especially if you have more than one, as in a tab bar app, each navigation controller gets its own coordinator, for directing its behavior and flow. Further child coordinators can be created for specific tasks like signing up or creating content. Each coordinator is spawned by its parent coordinator. As always, use this pattern early in the development process, so they’re useful even in single-step tasks, such as authentication.

The Coordinator is a PONSO, like all great objects. For something like Instagram’s photo creation flow, we could have a PhotoCreationCoordinator. The app coordinator could spawn a new one, and pass it the root view controller so that it could present the first view controller in the flow.

- (void)beginPhotoCreationProcess {
    PhotoCreationCoordinator *coordinator = [[PhotoCreationCoordinator alloc] initWithRootViewController:self.rootViewController delegate:self]
    [self.childCoordinators addObject:coordinator];
    [coordinator beginPhotoCreationProcess];
}

- (void)photoCreationCompletedSuccessfully:(PhotoCreationCoordinator *)coordinator {
    [self.childCoordinators removeObject:sessionCoordinator];
}

- (void)photoCreationCanceled:(PhotoCreationCoordinator *)coordinator {
    [self.childCoordinators removeObject:sessionCoordinator];
}

The coordinator’s -beginPhotoCreationProcess method can now create a new photo selection view controller and configure it as needed. The coordinator can conform to the photo selection view controller’s delegate so that it can be informed when it’s time to present the next step. None of the view controllers in the process need to know about any of the other view controllers. Each view controller is an island.

Business logic, like posting the photo, is wrapped up in its own object and can either be pushed up to the coordinator or pushed down to the model as appropriate. Either way, it comes out of the view controller. Moving it up is great because the coordinator is already acting as the glue between different parts of your code already.

The benefits to extracting the flow into a coordinator are myriad. View controllers now can focus on their goal of binding a model to a view. The can be reused more easily, such as in extensions or unbundled apps, without having complex conditionals to manage different contexts. A/B testing is as simple as creating a different coordinator object and using that to start the process. Flow logic now has a home, and things that have a home feel real nice.

View controller initialization is also extracted. This shouldn’t be overlooked. Initializing is always a more complex task than it seems, requiring lots of knowledge about classes and configuations, and we moved it to a better place where more informed decisions can be made.

Coordinator objects naturally fall into one of many disjoint states — in other words, especially for an iPhone app, only one screen is visible at any time. This makes them a ripe place to use state machines to manage all of the data in their custody.

Apple loves having the view controller be the center of the iOS world. This is obvious in the new UISplitViewController APIs in iOS 8, as well as Interface Builder components like storyboard segues. Unfortunately, a view controller-centric approach to app development isn’t scalable. The Coordinator is a great way to isolate your code into small, easily-replaced chunks, and another part of the solution to view controller malaise.