Transcript
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.
And kind of getting back to that idea - I said, you might
have an idea about a 2.0 of your program - or maybe
you think of a great new feature after you've got