Basics+Habits: Building Your Software Projects To Last

Session 212 WWDC 2012

All software projects start somewhere and evolve through the accumulation of your effort, changes in technology, bug fixing, and the addition of features you could not have foreseen when the project began. This session discusses this process and provides you with ideas which can help you build your software projects to last.

Good morning everyone.

Thank you for coming.

So. This is session 212. Basics + Habits.

Building your software projects to last.

I am Ken Kocienda and again, thank you for coming.

So, I think, right, when you think about building a great project, I mean, it means for us, for this audience, it means building a great application.

Right? That's why you're at WWDC.

You're an app developer and you want to make great apps.

And if you are successful in making an app it means that your app is probably going to change. You're gonna be shipping updates to app as new features, new OS releases come out There gonna be bugfixes, updates, you know, all of these kinds of things.

So success means, your software is going to change.

And you probably know that radical changes rarely work.

If you take the example from biology there only in evolution, most mutations kill the organism right, you have a radical change, it doesn't work.

The same holds true for software So, incremental change is better.

Last year, how many of you saw my "Easy-to-change code" talk, last year perhaps?

Oh, there are a couple of hands...

Security, those are the people.

You probably wanna leave.

They're crazy enough to come to my talk to years in a row.

But no, thank you, thank you for coming again.

But for those of you who weren't here last year with the easy-to-change code talk, I talked about this mental change idea last year, but in getting some of your feedback I realized there were some problems with some of the things that I said.

Like: I talked about notifications.

I said in one part of the talk: "Notifications are good, because the promoto loose coupling.

between different parts of your system and that's a good thing.

But in another part of the talk I said, half jokingly that notifications are bad, because they're just glorified GOTOstatements. So kind of seems that both of these can't be right.

But hang on, there's more, right?

I also talked in my session about hygiene, alright?

The best writing is rewriting, quoting there E.B. White, a great writer. But then also said don't trhow away old code, right? You just want to incrementally change software to sort of bring new features to it or change it, and this kind of seems again both of those cant be right. It's paradox you wind up with this: Too many cooks spoil the broth, but many hands make light work.

Right? Again: Things don't seem to make sense when you say them both at the same time.

But, of course, they do I think in all of these cases, if you say one of these things in the right context, right?

Those tatements don't exist in a vacuum When they, do, yeah, you can wind up with nonsense. But if you've got the context if you know how to match one of these things it can make sense.

and so this talk is really the context, i think, for that incremental change that I talked about last year, fills in more of the detail. you can kind of understand, perhaps even go out on iTunes and look at last years talk this year and sort of have our own little time travel.

Right, it's the context of incremental change.

Basics + Habits. What does that mean?

Basics: When I basics, it's the fundamental choices that you make at the start of a project.

You kind of make this whole serie of choices about what your project's gonna what your idea is, what software to use, all of these kinds of things. All those mental choices you make at the beginning of a project.

And then Habits are the things that you do every day after that.

Building on the basics and then you actually go and do all the work, invest all of the time and effort to actually make the projec come to life.

And so basics plus habits, hopefully, you;ll see I've got some ideas today about how this will create this context that then you can add in your incremental change, some of your ideas from last years talk.

And eventyally, riught, wind up with a framework that will help you to make your software project successful and last a long time.

I've got 6 basics that i'd like to talk about today i;ll go through them, the first one being define you physics and chemistry so physics and chemistry, i like this little analogy.

you think about this in terms of software, again, it's an analogy, it's physics are the fundamental laws of your project of your software world that you create in your software.

and then chemistry are the way that things can mix together. i'll be using this analogy quite a bit.

and here's the first example. when I think about kind of a very basic, kind of block diagram, a generic one, physics are the blue boxes.

they're kind of the basic, kind of elements of your system.

particularly when you look at them from the outside its the basic phyics, the real sort of unchangable nuggets in your system. at least the fundamental; nuggest.

and then the arrows are the chemistry, or the way these things combine, in this case like the Model-view-controller example, they combine in ways that ... in keeping that MVC pattern.

they combine in well-defined ways, right, to mae your software work in the way that it does.

so: the physics and the chemistry.

now, i mean this is such a basic idea, such a fundamental idea, about how software works, that i think there are other analogies that people use oftentimes.

like: nouns and verbs, where nouns are the abstractions and verbs are the way the things combine with each other. another, obviously very popular one, is objects and interfaces, it's the encapsulated bits and the exposed bits and the interfaces that you have to get at these exposed bits.

i still think that physics and chemistry though is the best analogy, and again, i'll be returning to this quite a few times during the rest of the talk.

and i do think that ultimately most coding is chemistry. you;re most often kind of using the interfaces that you create. i mean you create interfaces much less often than you use them.

and of courtse this chemistry is expressed in terms of those interfaces, in terms of those physics.

and so here now if we go back and look at a more concrete example of that diagram that i had before: this basically, very basically, describes the design for the ios keyboard text entry system, that I do a lot of work for. this was my design for the 1.0 keyboard. as you can see at the top i've got a keyboard controller, over then on the input manager side right that's where ive got the model and then there on this side i;ve got the user interface, keyboard layout, textfield... really it is kind of an mvc type pattern.

now, if i go in and add the arrows, i'd like you to look closely or perhaps if you can't see i'll describe the view side, the arrows are bidirectional. they go both ways.

yet on the model side, the arrows only go one way.

and this actually is kind of an important design idea.

again, at the beginning a basic decision about how the software system was going to work. i didnt want the dictionary to be calling back up to the controller.

nonono, the dictionary, the input manager system was called and returned a value. that's all that it did. it only came into the system when it was called, whereas, of course, the view system needed to respond to user touches, and of course needed to be updated as appropriate maybe when an autocorrection suggestion came in. and again here, the point is that this fundamental design was a basic decision that i made at the beginning of the project. and that i carried through through the rest of system. it wasnt liek this.

very specifically it wasnt like that where anything could call anything else.

of course it wouldn't be a show if it didnt have flames. so this is a much more kind of sensible basic design for an mvc system.

ok.

So the idea is I think, too, is I think you wanna strive for solid physics, again for those last example those big blue boxes, they were senisble. sensible design.

sensible big ideas for compoentns of the system and so you wanna strive for that solid physics at the beginning of your project and you don;t wan to be redefining the rules of your universe very lightly.

of course you can;t change gravity and the conservation of energy and these are the physics of the natural world are decided for us, but in your software you can change this just about as want.

But dont! with great power comes great resposibilyt, right?

You wanna kind of get your physics right at the start of your project if you can.

and perhaps maybe even the final way of talking about this is maybe a little bit more playful.

maybe something that makes writing softeware so attractive to all of us is that you can make it a sandbox that then you go and play with. again it is sort of like you have that good feeling about a god successful project which you have made light and and you enjoy improving it, making it better, and then of course, all of you are going to make great apps.

that go out to customers and you get great feedback from them. it feels good if you have a successful project like that.

So again: defining phsycs and chemistry, the first basic decision you need to make.

second: choosing the right technology.

make a technology choice for how you;re going to make your project work right at the beginning.

now, of cours,e in choosing technology: you're here at WWDC, it is kind of preaching to the choir. You already have chosen great technology: you've chosen Apple, you;ve chosen macos and ios, so congratulations, you're all awesame.

give yourself a round of applause.

you have also chosen this talk this morning, so thank you for that.

but now: more to the point, if you think about tools when you maybe gonna build a house, sometimes you need to go and grab a hammer, and that is an appropriate tool, and then you grab a wrench and that's an appropriate tool. but they;re not appropriate for all tasks; pretty obvious. the same is true for software.

we have got some great software on our paltforms.

coredata is a good example. it is a great piece of software for if you;re developing and app and you got some objects in your system. at runtime you maybe wanna save the state of some of these objects, you m aybe wanna save the objects themselves. use coredata, sace them to a database, it is a great technology. it does that object relational mapping system. how many people are "yes, my name is xxx and i have made my own object mapping system. i have a problem". i have done that problem many times. coredata solves that problem. you dont have to do that yourself. it is a great technology choice if you're an app developer. But if you're building a web search engine and you're building a big server farm ithen probably core data is not the best choice, even though it is a great technology.

it;s not the great best choice for that particular task.

so i think the message here, aprticularly at WWDC is that if you;re new to our platforms, kind of new to ios, new to macos development: learn our frameworks!

know what;s available. go to the labs. find an apple engineer. if you;ve got an idea, see if we've got software already there for you to take advantage of.

learn our framework. know what's available and figure out how to best match what you need to do to the task you want to accomplish.

now sometimes even after you do that you find out everything that's avaialbe, everything that we've got, and it doesn't quite match what you want to do, sometimes then, but only from knowledge, you need to go outside the box.

and again, there is an example that I would like to tell you about: it's NSString in Foundation. Of course it's great for general purpose programming, but is it great for high-performance string handlign?

High performance when I need to do substrings lots na lots of comparisons, like again the example was the iphone keybaord.

when i was making the original autocorrection algorithm the first few tries that i made was basically brute-force.

searching the entire dictionary every time you typed a key.

logically, that's what is was doing, but it could do that, so i needed some kind of high performance string routines to make that actually perform well. and so what I wound up doing was developing my own custom c++ string class using a lot of stack-allocation, using the shrot string optimization, yeah, get a little bit of c++ geekness into every show.

not only that, yes, this shortstring optimization is now in libc++. the new c++ library that we're developong and making available as part of llvm which is really nice. we didnt have that back in 2005.

so: should you do this? probably not!

Only, you only make a choice to go outside of the box when you have determined that you really need to.

Because, again, what we are providing to you as part of our frameworks don't quite fit the bill.

Now, I will say, interestingly, that even though this seems like a sort of a low level optimization, was that premature optimization?

And I don't really think that it is. Again, I think because this is an optimization that has to do with physics, I could have changed the class out for another one with the same interface and it would have been alright.

I didn't really paint myself into a corner.

In other words, this was an optimization that was a technology choice, not an activity, not making sort of very very complicated algorithms that had a lot of interdependencies with each other - which then are much more difficult to undo if you decide it doesn't really quite work, or that you need to change them.

It was kind of optimization in terms of physics. It sometimes can be a little bit safer than optimizations in chemistry.

Again, the real share in this section is: Learn our frameworks.

Come to our labs, after the show, go to our developer forums, find an Apple engineer, learn what we have available.

So that's basic number 2.

Basic number 3 is "Build solid abstractions".

When you're thinking about your project upfront you kind of think about, again, maybe even basic chemistry building blocks that you want to use for your code.

And so I got an example. Here is a declaration of the dispatch_async call, aprt of the dispatch framework.

Of course, this is a really, really great part of our frameworks, because as it says "schedule the block for concurrent execution with the dispatch framework" Really neat technology. It makes writing concurrent code much easier to do.

So. Now that you know this... Right? You've read the man page, you;ve read the developer documentation...

And now you've got a piece of code like this where you've got a loop and you need to do expensive work with every object in an array and - ugh - you go and you profile and it's slow.

So you figure "I've got a couple of cores on this system I'll just go and fix it like that, right?

I'll do dispatch_async and do all this work on the background thread and it's just like "Wahoo!", right?

Ermm... No. Not "Wahoo!". Why is that not the right answer?

Now, I think, that what you've done, what that piece of code has done, is that gives you chemistry without physics.

You just sprinkle in a little dispatch_async... It's probably not the right thing to do. And again, this is why it is not the right thing to do: You've got chemistry without physics. Concurrent code is complex and I think when you introduce that into your program, you need suitable abstractions to build on, to make it come out right.

So. I think the way to do that is in terms of objects and interfaces. Define your work in terms of the job that you want done.

So here is this little trivial example. Let's maybe use a different example that's a little more real world, which is maybe a piece of an image app that generates thumbnails for larger images.

You see here, I've got a ThumbnailMaker interface that says make a thumbnail.

Then an Observer which gives me a hook to call back after a thumbnail is finished being made.

Here's a piece of code to do this: I've got my photo program which is itself a ThumbnailMakerObserver Maybe I've got this interface that perhaps some other part of my software calls.

to say "ok, i've got an image and I need a thumbnail for it".

I dispatch_async onto a background queue to the ThumbnailMaker object, which is, of course, defined on the bottom of the screen, to make a thumbnail and I pass myself in as the observer, right?

Now, of course, that code goes and runs. It makes the thumbnail - churn, churn, churn - does the work, makes the thumbnail, dispatches async back to the observer, back to the main program, says it is done. Ok.

Thumbnail available now, go and update the user interace.

Take the gray box and replace it with the thumbnail.

Very very simple.

But, I think you can see, that this is chemistry with physics.

There is design.

dispatch_async is an implementation detail of this larger picture.

which you could sketch on a board. You've have your big boxes now.

It's better. That's a much much better way to approach the problem. Again - kind of a trivial example - but I think it gets across a really important point.

Because, now, you're thinking about the software not in terms of thumbnails, not in terms of just dispatching as part of a loop... You've got sort of structure, a framework for your thinking.

You've got an interface that will hopefully stand the test of time.

And additionally, if you have to change your implementation, sometime in the future, to maybe server-generated thumbnails that are now shipping as images over a network. The thumbnail generated and then come back.

Probably that interface, that might actually work, Instead of dispatch_async, well, send the raw image, the full resolution image over the network and have a thumbnail generated for you.

I think that's a much much more solid abstraction.

Again, defining your work in terms of the job that you want done.

And I think that's basic number 3.

Number 4: Optimize for humans And I think this is something that is a good idea to always keep in mind as you're designing your project.

Particularly, if it is going to have a long life, that you're gonna be maintaining it. And you want to be kind to your future self today. So here is an example of that: A lot of times we use these data and wire formats in our programs... XML, JSON, plists, Google Protocol Buffers, what have you.

Here is an example of a little JSON structure that I might be getting. It is a coupon. It has an expiration date, a name and - hey - it's got a pitch, too: Get 25% off on your next purchase.

Now, you might that, well, I am gonna be receiving this over the network from some service or partner, perhaps I'm making the next great coupon app.

I might think that in my program then I receive that JSON over the network and that I'm gonna need some Objective-C code to deal with that coupon, and I'll just write it like this: I'll just have a getProperty, setProperty interface for the coupon, and that's how I'll pick apart the details.

I think, that's a bad idea.

Now you have chemistry trumping your physics.

Now you've got the fact that you are using JSON or one of these other wire formats making decisions about how your software is designed. You're not designing for yourself, you're designing it for this wire format.

And you wind up with a weird universe like that.

Instead of something like this you wind up with something like this!

You have over-emphasized how data is traveling from one place to another, rather than how you need to deal with it when it gets to your program.

And I think this is bad, because brain power is your scarcest resource. If you try to remember what property name was pitch inside of a dictionary? You don't don't want to be worried about that.

It's not CPU power or network bandwidth that is or will be the limiting factor in making your sofware.

It's brain power. You want to conserve that as much as you can So what can you do about this?

Instead of having an interface - a weak object interface - getProperty, setProperty...

I think you could do something like this: Instead where you've got methods that take JSON data in, create your object, can also vend the JSON data back out in case you need to send it back out to the network even after modifying it, and then give yourself a nice good strong object interface to work with.

Now you don't need to remember "is the pitch inside of some kind of dictionary?"

If it is or is not does not matter, you will have taken care of that - presumably - in the init method.

And now that property is just available for you to go to and use.

Now you can go and see - maybe you've gone away from this code for a few months - you can look at the header and see "what's a coupon?"

You don't need to kind of go "Do I have an example of this kind of coupon JSON data somewhere on disk?

You don't need to worry about that.

You've done the work to give yourself a good strong object interface. You've optimized for yourself. Not for serialization or the networking protocol.

And again, that's something that you bake into your project at the beginning, when you're making your fundamental interfaces and designing how your system works.

Optimize for yourself!

Next: Basic number 5.

Focus your development effort.

I think at the beginning of a project it is a good idea to ask yourself what you are trying to be great at You should have a good answer for that question.

Who is your audience? Who else in the world, once they find my app, is going to think "this is great"?

and why are they gonna think that it is great?

You wanna make sure you have answers for these questions.

And you wanna make sure that you're building that!

That you are actually delivering on that greatness that you are trying to achieve.

And I think that, of course, iOS and OS X give you great foundation to stand on, literally and figuratively, you know, Foundation, Framework, right?

Stand on our shoulders, build your great software, using our frameworks. Learn them.

Again. I am sounding like broken record, for those of you who are old enough to know what that is...

And it is kind of interesting, too. I mean it's a little digression. We wind up with a little recursive physics and chemistry. There are people, obviously, in Apple where UIKit is there little chemistry set. They're going to be developing UIKit deciding on what the chemistry and chemistry is.

For you that's just physics. UIKit is what it is.

It's not changeable by you. It's just part of the physical reality, the unchangable law of your universe if you are working on iOS.

And that is kind of interesting, too. You might want to do that in your own software.

Develop libraries that are then unchangeable by higher levels of code.

You might even want to do this for models - the model of your program - and then have user interface level level: One for iPhone, one for iPad, that treats that layer as sort of an unchangable physics. Kind of an interesting little idea.

Ok, now more concrete examples.

Which is sort of getting to the idea of that you want to focus on what makes your software novel and interesting,.

An example is: if you love the way that iOS device auto rotation works, don't spend time implementing that yourself.

You need to learn our frameworks and find out that UIViewController provides that for you.

Similarly, if you need database interaction, you want to save some of your app's runtime data in a database, learn about CoreData. Don't go invent your own object-relational mapping software.

If you need animation, learn CoreAnimation. It's the same thing.

If you need X, then you maybe not even quite sure, what that is.

What name to call it, because you don't if we have that in our frameworks, ask in the labs. That's why you're here this week; or the developer forums after. This week, since you're here, find an Apple engineer and ask your question.

Because in the end you want to be working on the thing that's gonna make or break your application.

That's what you want to be working on. That's where you want to be spending your time.

So focus your development effort right from the start.

And then lastly: You always want to be looking to the horizon a little bit.

What if you're successful? What if your app works?

And people love it? They're downloading it!

What if maybe you've got a little service that's attached to it where people can upload content, download content... Can you handle it?

What about performance? How much headroom do you have in your software for things like performance, or perhaps even for future features which you may be able to get in your 1.0, but you definitely want to get to for your 2.0.

So you really want to be building in a little bit of headroom, if you can, into your application.

But how to do that?

Another area to think about if you saw Andre's talk on Monday about Internationalization: There is a huge opportunity out there for you to ship your app all around the world.

If you localize it into the language spoken by those people in other countries.

We've got great support for internationalizing, localizing your application. Strings, dates, times, addresses, names, whatever...

You want to be thinking about using our software right from the beginning, so then when it comes to localize your kind of on the road.

You can kind of take advantage of our great localization features to ship your app all over the world. I really urge you to do that, it is a huge opportunity for you.

Apple, Inc. AAPL
1 Infinite Loop Cupertino CA 95014 US