Tag: Programming

  • In Defence of Static

    Picture of my app working after I fixed a bug... using extensive unit tests.
    Picture of my app working after I fixed a bug… using extensive unit tests.

    Maybe it’s my functional programming background, but I love static methods. Not everyone gets this, some people parrot the phrase “static methods are bad for testing” but don’t seem to understand what that means.

    Static methods are great for testing. Inputs in, outputs out, side effects – what side effects? What’s not to love?

    What they are bad for, is mocking. This is an entirely different problem.

    Note: here I’m using static to mean methods without side effects, which technically includes Objective-C methods that are denoted with a + (class methods). Turns out, these methods are not technically static, they take place on another object [detailed explanation]. Static methods in Objective-C should properly be C methods.

    Also, you can mock class methods, in OCMock by using: 

    id classMock = OCMClassMock([SomeClass class]);

    When and Where

    I’ve been doing a bunch of image processing work lately, and it looks like this:

    • Break image down into pieces.
    • Do stuff to it.
    • Put it back together.

    Each of those things individually are great for static methods. Take an image, break it down – do I have the requisite pieces? Put some pieces through this process, is the result right? Given some pieces, do we get an image with the right properties? Wonderful.

    I’ve spent hours (OK, days) writing tests for these things, because I was not an expert on image manipulation and in my opinion there is no better way to deeply understand code. I found and fixed a horrible bug. Next, I need to optimise, but my thorough test suite gives me confidence that I can do this refactoring without breaking things, and that I have a good API.

    But – I don’t want to deal with this elsewhere in my app. So I absolutely want this stuff to be mockable. So I use a very simple pattern:

    • Expose a class method that updates the object.
    • Have a static method that takes whatever information is necessary, and returns whatever needs to be updated.
    • Class method calls the static method with the requisite information, and updates itself accordingly.

    This becomes easy to test. My static method has tests that cover a full range of inputs and outputs. My class method just needs a single test to ascertain that stuff gets updated.

    When I’m mocking this object, I just mock the class method. The static one never gets called.

    Some people’s irrational loathing for static methods can cause problems in code review. If you don’t want to argue, two options:

    • Split the static methods out into a “MyClassHelper” object. For larger things I do this to be tidy.
    • Just don’t declare the methods as static, but use them as such following this pattern – I really don’t like having to do this. But I have done it.

    Other People’s Static Methods

    The main issue I run into with static methods, is that other people have used them – I find it is common in API design when classes shouldn’t be subclassed.

    In this case, I group things together logically in a wrapper. For example, in my current project I have a class that wraps various static things I need for handling images.

    Coverage vs Confidence

    I am a proponent of code coverage, and regularly use it to guide me to the places in my code base that need a bit more love and understanding. But it’s important to note that coverage doesn’t necessarily mean confidence.

    If you have a (say, static!) method that takes a test image and returns an array of length 9, and you verify at the end of it that the array is indeed of length 9, voila you have coverage. What you don’t have, however, is confidence. What are the 9 things?

    In part for this reason, I start small and work up incrementally. If I start writing a large test and get confused, I break it down and write a small one first. So in this case I might write 3 tests:

    1. The result has 9 things in it.
    2. The 9 things are correct.
    3. The completion block gets called.

    So if I break the test and 9 things are no longer produced, tests 1 and 2 will both fail. If I break it and 9 wrong things are produced, just test 2 will fail. If I accidentally delete the line that calls the completion block, just test 3 will fail.

    So when I break something, multiple tests will fail, and the simplest one that is failing will be where I go first to determine what I’ve done.

    The other thing about confidence, is that tests should break when you change stuff. The other thing I use to improve my code confidence is when I make a change that doesn’t result in failing tests and I think it should, I go and write some.

    TDD Wut?

    I don’t often do pure TDD, when testing UI code I expect it would be difficult to the point of not being worthwhile, or in some cases not even possible. Occasionally I TDD, if I’m trying to figure out how something should behave I will start with test cases. More commonly what I do is:

    1. Write the simplest thing.
    2. Write tests for it.
    3. Refine my code, optimise it etc.

    I used to employ this strategy a lot when I was writing lots of Guava. I adore functional programming, but a nested for loop is easier to read, understand and debug with print statements if necessary! Because at least initially, it’s nearly as likely that I have made a mistake in my test as in my code.

    TL;DR

    Static methods are great. Hide them away and they make testing easier, not harder.

     

    Thanks go to Martin, for reviewing a draft of this post.

  • The Entire Dev Team is Sick

    IMG_7022

    I’m working on an app right now. I’ve been working on it since I escaped my gilded cage, modulo distractions – consulting, travel, talks, writing. It’s fun, working on my idea, and thankfully I met a great designer so it’s not going to be Developer Art. And it’s cool. I’ve had a working demo for a while which people have seemed to like, and now just refining the UX and some horrible bug (relating, I think, to filetypes) remain.

    Of course that last 20% takes 80% of the time again. And I’d been making progress, knocking out all the small things, in between running around, but then I got 8 days to focus on it almost exclusively and discovered that past-Cate had left future-Cate, now present-Cate, a bunch of tedious and time-consuming things to do, and also that horrible file-type bug. And present-Cate understood what past-Cate had decided, but that was when being the entire dev team got a little lonely.

    It had been really nice, making all the decisions, not having to do code-reviews, or spend time justifying decisions I’d made, because someone else would have made a different choice. I believe in code-review as a process, but so much tech-bro-male-dominance gets played out in them. Some people (men, I find) seem to view it as a making you jump through the hoop, where the hoop is “how I would have done it” and deviations must be justified. “Suggestions”, which seem a lot like orders, which I would resent much less if they worked most, or even half, of the time.

    Naturally, it’s easier to live without code review on a platform I’m already pretty expert in, and I expect it will be harder when I move on to Android, where I haven’t already architected and led an app from first check in through to launch.

    Really, there are two things I find hard about being the entire dev team.

    Firstly, if I’m out for whatever reason – sick? The one day a week I force myself to take away from the computer? Meetings? A deadline for some other project? That’s it, nothing moves forward. It makes it easier to give up on progress that day, because it feels like it’s not going to move the needle anyway. On a team, if I took a day sick, I might still do code reviews for other people, or check in some little things, if I felt a bit better later in the day.

    Secondly, when deciding between two alternatives, like the one where the mocks have arrived and that library component won’t do quite what it needs to and should be ripped out and replaced with a custom one, I’m the only person with the context. I think the decision is pretty clear, but I need to talk myself into it and convince myself that I haven’t missed anything. There’s no-one else with that context to have that conversation with. Thankfully a friend with some context, who was nice enough to listen and tell me I was right, but I missed sitting next to someone and being like, argh, you saw these same mocks and you code reviewed that code already and now it needs to change and yes.

    I still have no-one to talk to about the filetype bug, but that’s OK. I’ll write more unit tests to understand it. And maybe start talking to myself. Or my plastic ducky.

     

  • #iOSDevUK: Jon Reid – Controlling Dependencies to Enable TDD

    My notes from John Reid‘s talk at iOSDevUK.

    digital wires
    Credit: DeviantArt / LoneWolfAssassin

    Barriers to TDD. Two primary:

    • Not knowing what it is. Rejecting it as silly without giving it a try. A good try, as there is a learning curve. It will slow you down at first. If you give up before the payoff then you will say “oh that was stupid”.
    • UI and Networking. On iOS most of what we do is UI and networking, rules out 90% of app, so not really useful.

    EBay Fashion app. All test driven.

    3 Types of Unit test:

    • Return value test
    • State test
    • Interaction test

    Patterns of testing. The Design Patterns book, the Gang of Four never intended it to be the beginning and end of design patterns.

    Not going to be rocket since. About getting through the barrier. Writing unit tests after if necessary, but ideally before.

    Return Value Test:

    • Arrange: set up object.
    • Act: Call method that returns a value.
    • Assert: Compare against expected value.

    With this alone, you should be able to get a very far distance. Onboarding engineers at Facebook, teach them not to be shy about extracting stand alone functions. Helps overcome that barrier.

    State test:

    • Arrange: Set up object.
    • Act: Call method.
    • Assert: Compare against expected value.

    Since interested in a side effect, just need an additional call to verify state. Should be able to write quite a few tests with these two techniques.

    Interaction Test:

    Don’t need to be isolated units. They can be connected, as long as they are fast. Check that the system under test (SUT) is communicating correctly to something else.

    Don’t want to talk to the real thing:

    • Takes too long.
    • Might not be there.
    • May not have everything (don’t want to use things up).
    • Might want to test the failure (normal end to end tests).

    Want a fake thing that the test can control. Need dependency injection, if the middle thing is creating the end thing, it’s hard to test.

    Dependency Injection:

    • Extract and Override.
    • Method injection.
    • Property injection.
    • Constructor injection.

    Difference between having a singleton, and a single way to access a singleton. E.g. NSUserDefaults. Don’t want to access it in this way.

    Extract and Override: read “Working Effectively with Legacy Code” (Amazon).

    TDD was working for me in a greenfield project, but how many of us get to stay in such a place?

    Seams

    Make a cut – subclass, override “userDefaults”, do what you want. Very powerful. Very effective with legacy code. Very dangerous. Like a drug. But will end up with the bane of testing code, fragile tests, because tests are coupled to implementation.

    For getting started, especially with legacy code – good technique.

    Method Injection

    Better for other things, like calling “[NSDate date]” – will cause havoc with tests. Can swizzle, or just pass in what time you want. Now you will have a method that does more, now it’s tied to any time, not the current time. Helpful as context for injected object is very small. When spans across method, probably want to hang on to it as a property.

    Test can inject the fake thing. But what about production code? Can end up with nil. Objective C will be like “whatever”.

    Create custom getter with lazy eval. If no value, get the default value.

    Inject in constructor – workhorse of dependency injection. Biggest benefit, makes everything explicit.

    Can be annoying to have everything explicit. Long chain of dependencies is a code smell – you have too many dependencies.

    Even then, you can simplify that, by using a Builder. Builder pattern creates the object you want according to however it is set. Set in any order, or not set and have it have defaults.

    Constructor injection is the main one.

    Ambient Context. Change something globally. Swizzling is an example of this. You can, sometimes helpful. But dangerous. Have to have your test restore the pre-test condition.

    Let’s learn some good things from other people in other disciplines. There are plenty of smart people who are not using Obj-C

    Interaction Test

    Types of Fakes: The Art of Unit Testing

    • Stub: Fake that provides a pre-canned answer.
    • Mock: Recording how it is called by the SUT, so that it can assert.
    • Difference is which way the test is pointing to make it’s assertion.

    Don’t need a DI framework in order to do DI as a concept.

    Mocking, if never mocked before don’t use OCMock or OCMockito at first. Use them eventually. Meanwhile, you can make your own fake. Subclass and override all methods. Test Driven iOS development, means don’t have to do that in Obj-C. Dynamic language, supports DuckTyping.

    Subclass NSObject. Put the method in. Use a simple property to record the number of calls. Have a fake return value (if unspecified is nil). Capture arguments.

    Interesting thing about doing by hand, answers question of “what do we do in swift”. No introspection available to us. Do it by hand, laborious, might cry a little bit, but nothing stopping us.

    Now we have a mock, use it. Start writing some tests.

  • #iOSDevUK: Marcus Zarra – Not Invented Here

    Saw woman texting with a T9 phone. Stopped, looked, made sure he saw what he really saw.

    Presenting from a phone. First presentation, used a projector. Amazing how far we have come.

    Generally known as an opinionated person. Don’t speak in wishy washy words, very boolean. Either believe or don’t believe. If not, just shut up.

    In career get feedback, “brash”, etc.

    One thing is claiming he has a dysfunction called “not invented here”. Yelled at for wanting to write things himself, not wanting to use other people’s solutions.

    Think it’s a problem, being egotistical. Thinking he’s better than everyone else.

    In own introspection. Am I really this evil person? Do I need to fix this? Realised no, really don’t. Positive side.

    Why he doesn’t like other people’s code. Why he doesn’t like 3rd party frameworks.

    Lot of reasons. One that it is not, code quality.

    Code quality is a complex subject, not going to put it on one side. Talk on it’s own, if could even fit in a talk.

    “All code sucks, eventually. All code suffers from bit rot, no matter what.”

    Three points:

    • Reinventing the wheel.
    • Becoming a better developer.
    • Code ownership and maintenance.

    Reinventing the Wheel

    As an engineer, write a lot of networking code, persistence code.

    Whenever start a new project, start from zero. Don’t have a cheat sheet, or a code snippet, or a template.

    Write it each time not because like torturing himself, because he knows can write it better. Smarter today than yesterday, especially than three months ago.

    Shouldn’t be reinventing the wheel, but iterating the wheel is something that we should be doing. That is what we are really doing when we do that code over again.

    Becoming a Better Developer

    “Any insufficiently understood technology is indistinguishable from magic.”

    Think something is hard, never bother to go out and look. By writing it yourself, disperse the magic. In it’s place you have code you understand.

    “Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it.”

    Code Ownership and Maintenance

    Even though write it today, no guarantee can read it tomorrow. A year from now it’s going to be complete garbage. When write it today, want to be able to read it in a month.

    • Risk management with Apple (they change things all the time).
    • 3rd party framework is like introducing to an unmonitored team member.
    • No guarantee of updates.
    • No guarantee of quality or direction.
    • Risk of App Store rejections.

    Happy Medium

    • There is good code out there.
    • Manage your risk: reward needs to justify the risk.
    • Consume the code, own the code, make it yours.
    • Learn the underlying technology before adopting a framework.
    • Stop inheriting other people’s problems.

    “You have a problem so you decide to make a framework. Now everybody has a problem”. @secboffin

     

  • Impostor Syndrome

    Windy day
    Credit: DeviantArt / ZoranPhoto

    I’ve rejected a number of posts for today, because I worry that whatever comes next will be taken in the context of this. Because today is a day where the schedule says, write about women, and I think, I should write something positive. And there is so little positive to say about women in tech. The data is bad. The numbers are going down. I got nothing.

    And then, I had a conversation with a fabulous woman about shoes. I’m at a tech conference right now, and I’d been feeling slightly out of place. Since I sat on the train and didn’t manage to make conversation. Compounded by walking up a hill in heels and getting left behind, which felt like something of a metaphor.

    And then we talked about shoes. Because to be honest, that is my metric for a good tech conference. I meet another woman and we have a conversation about something else entirely. And I talked to other people, had good conversations, made good connections.

    Had something of a heart to heart, in the way that you occasionally do as a blogger. When you discover someone and find that you have read some of their writing, and they have read some of yours. And this was notable for me, because I was having this conversation with a dude.

    Honestly my network is probably quite dude-lite, considering I work in the tech industry. I meet a lot, but I rarely have such open conversations with them.

    I said, thinking I was revealing a terrible secret, that I worry sometimes that I’m less good than I used to be. And he said he felt the same, but that he thought it was normal.

    Imagine, my dark secret, normal.

    In the tech industry, we talk a lot about the impostor syndrome. But almost as a matter of pride, like, wow, it’s so incredible that we, such clearly brilliant people, sometimes… question our brilliance. That surrounded by other brilliant people we sometimes… feel a little inadequate.

    But then when we feel like that, we stop feeling like that and go and be awesome instead.

    Thinking about it, a great day’s programming, is when you get a week’s worth of work done in a matter of hours. But a bad week’s programming, is when work that shouldn’t even exist (because you screwed up) takes all week.

    This is what makes it addicting. The high highs, the low lows. The unpredictable reward. So we’re probably all having low points on a pretty regular basis (and they last longer than the highs).

    Meanwhile, I’ll try and stop feeling inadequate about feeling inadequate… and go and have an awesome time, instead.

  • Bikeshedding

    bike shed
    Credit: Pixabay / Unsplash

    One of my friends sent me a grammatical suggestion on something I had written. I assumed he was right, made the edit, but then that looked wrong too, so I looked it up. Discovered they were both fine, but the way I had it was slightly preferred. Sent him the link, without that explanation, because it seemed redundant.

    Offended him, because I had inadvertently played into the thing that we do in tech, the petty one-upmanship, and the assumed superiority. Realised, as soon as he called me on it. But was shocked, because I had no concept that dudes do that to each other, too.

    I realise, how blinkered that sounds. But as I work so hard to balance my own environment, even if the wider one is completely out of whack, I see and hear these things happening to other women, as they happen to me, and miss them happening to dudes.

    Added factor, with dudes it’s less likely to induce massive stereotype threat, so maybe they don’t feel the need to mention it.

    How much time do we spend arguing about stupid shit? The Heartbleed vulnerability was checked into an Open Source project in December 2011, and to name one example, how many examples of huge arguments about de-gendering Open Source Project language have I seen in that time? Instead of, ooh, I don’t know, a unit test?

    (Note: I’m not saying the change to de-gender language is stupid, but the argument about it is. OSS competes for the rarest commodity – time – alienating large segments of the population can hardly help with that. These arguments typically centre around rejecting a patch.)

    Or, variable naming, file structure, ordering of cases in if statements. All these things that it’s so easy to have an opinion on, because above some low bar it doesn’t matter.

    Bikeshedding. Trivial arguments and intellectual pissing contests. Why, if every minor decision needs to be justified to half a dozen people, do we even bother having multiple people on a project? More time spent arguing over trivialities than actually getting shit done. At best tangentially relevant information is introduced, not because it might be interesting, or helpful but to demonstrate the towering intellect of the author.

    Except, does it? How is it smart to waste time on this stupid shit? I’ve never understood arguments about style guides for example, or the benefit of 80 vs 100 character line lengths. The whole point, I thought, is to not have to think, or worse, debate this stuff. Pick something. Stick with it. It’s fine. It doesn’t really matter.

    I’m pretty sure no-one ever encountered an argument on file structure that was so utterly brilliant, they thought, “wow s/he must be an amazing programmer!”.

    There are many things that I find tiresome about the tech industry, but this must be… ooh, top five.

  • Passion and the Developer

    danbo tightrope
    Credit: Flickr / Andreas Kiebs

    I go to a startup event, and it’s interesting to hear non-technical people talking about developers like over-priced commodities.

    L comes to me for advice, she’s contemplating her next move and worrying about whether or not she feels passion for the project.

    C reads my blog, tells me that she can tell I’m passionate about writing from my writing. I say, “that doesn’t mean I want writing to be my job.”

    R knows what she wants to prioritise with her career, but is hearing conflicting advice about what she should prioritise instead (and it sounds a lot like “passion”).

    I loathe the word “passion”. I loathe it in relationships, where it seems to mean seeking out the movie style ending rather than the day to day. And I especially loathe it in career advice. I like the Study Hacks ethos – it’s not passion, it’s hard focus.

    Entrepreneurs talk about passion. Cool. You probably have to be chasing something really hard to give up economic stability. That doesn’t mean it’s for everybody.

    Passion is Blinding

    To be passionate about something, means being unable to look at it rationally. This is unfortunate, because rationality is a very important part of building things well. Maybe it helps you stay awake for a week on a caffeine-fuelled coding binge. But it’s hard to love anything that much, for long.

    Passion doesn’t help you prioritise, it asks you to do everything. Data and pragmatism help you to prioritise.

    Passion doesn’t help you weigh up the eng-overhead and the data on usage of that feature and advocate for cutting it.

    You are Not the Decider

    There’s a reason why Product (PM) and Engineering are two separate roles. The PM looks at the big picture and the whole product and market (the what), the engineer owns how to build it (the how). It’s cool to have an opinion, but the PM is the decider on the what (this is fair! Engineers don’t like it when PMs try to be deciders on the how).

    When you feel passionately about the what, but you disagree with your PM and they overrule you? That sucks. But that is their job.

    You might think you know better, and maybe you have a really bad PM and that is true. But if you have a competent PM, they are going to make better decisions than you (on average) because that is how they spend their time.

    Competition is Fierce

    A friend was working on a super cool project, that she should totally have loved… but she didn’t. She should have been really happy… but she wasn’t. She was really stressed by the environment.

    We talked about it, and I observed something along the lines that it wasn’t that I didn’t want to work on something like that, but that I really didn’t want to work with the people who really wanted to work on something like that.

    Because a lot of people go looking for passion, and The New Shiny, the people who end up building The New Shiny are often the people who were willing to shove other people out of the way to get there. If you are happy to go about your work looking over your shoulder to see who might push you out of the way to get what they want, cool. I’m not.

    You Live in the Details

    It’s great to like the bigger thing that you are working on, but at the end of the day engineers mostly spend their time pushing pixels or protos. 1000 lines of test code does not make me feel warm and fuzzy about the product; it makes me feel confident about it’s stability. The menu bar might be part of some grand vision, but after a couple of days of just you and the menu bar, the vision seems pretty far away.

    If Not Passion, Then What?

    As a developer, passion is a distraction. For me, it’s not about passion for a product, it’s about having a healthy relationship with my job, a commitment to my career, and then maybe a general excitement about technology.

    What does a healthy relationship look like?

    • I like what I’m working on, and I think people will be better off because it exists.
    • The people I work with treat me with respect.
    • My work does not have to encompass my entire life. I can maintain other interests.

    Most importantly though, it’s good if you think that leadership can manage and ship a project of this scope (preferably, this should be based on evidence) and that you can manage and execute on the part of the project within your scope (again, it’s best if this is based on evidence).

    I say with evidence because passion hides, rather than cures mismanagement. Passion is the advocate of scope creep, the delusion that sets in at the expense of prioritisation, the fuel of Dunning-Kruger, and the carrot that would have you work more hours, for less money, on something that is destined to fail.

  • Teaching Chaos

    Chaos Theory
    Credit: flickr / Steve Jurvetson

    My friend Linda teaches drawing at University (amongst a wide assortment of things), and she was explaining a fascinating exercise to me.

    Requirements: white paper, charcoal, eraser, glue stick & tolerance for dirt.

    This is all about developing lots of strategies for recovering from errors and changes, and stumbling upon expressive, aggressive marks and effects that you can integrate into your safe, well-observed drawing.

    1.

    Start drawing the model, large, over the whole page

    Once everyone has a drawing well under way, committing to using the whole page, ask the model to change one thing about the pose, and ask the students to smudge out or erase the drawing as needed to incorporate the changed pose. Then ask the model to change again, and again. Eventually the students learn to use the smudges, ghosts and erasures as constructive marks in a drawing that combines observation and expression

    Give them a couple of tries at that. First time, they will learn what can happen. Second time, they can start to leverage the effects, not just recover from them.

    2.

    Like that, but after a couple of changes to the pose, stop the students and tell them “Tear your drawing into two pieces and keep the one you like better. Crumple the other piece up and throw it away. Look at the piece you kept. If you like it all, keep it. Otherwise, tear that in two and keep the one you like better. Lather/rinse/repeat until you have a fragment of the original drawing, a fragment you like. Glue it onto a new page and keep drawing.”

    3.

    Like that, but then put a splodge of white tempera paint or gesso into the palm of everyone’s (non-working) hand. Have them use that as hand-painted “white-out” to make changes to the drawing. Students gradually discover that they can not just erase but blend in charcoal and apply paint as highlights and other constructive marks. Erasure, tearing and patching fragments together are all still in play.

    4.

    Now play with equally messy colour – water-soluble crayola markers. Draw for a while in colourful crayola markers, then spray with water until they bleed. Integrate white tempera paint (which never perfectly covers the marker, and often blends into it) as you go. Keep brush and black ink, and all the strategies above.

    5.

    One of the hardest, weirdest experiences is working on a drawing for longer than an hour. Of working on something, and stopping, and coming back to it the next day… and holy shit it’s like it was made by a whole other person, and you need to look it over and figure out what today’s artist wants to do with it next.

    So let’s approximate that effect, fast-forward, in the classroom, with tag-team drawing

    Arrange students in a circle around a subject (still life or model), start drawing in your choice of material. One they get something established on the whole page… stop. Have them leave the drawing, pick up supplies and move to the next drawing over. Tell them to “Look at it as if it were your own. What does it need next? Do that”. Next drawing, next drawing.

    After adopting several drawings, have them come home to “their” drawing and look over the many marks and styles and changes that classmates have applied. Students then work over the whole drawing, including any of the strategies used above, to emphasise and reiterate the properties they like, downplay the things they don’t like, make some corrections and integrate the whole thing into one image

    6.

    If students are really risk-tolerant and energised by this approach, ask the very best ones to send the drawings one direction while the artists travel the other. The drawing no longer aligns with the viewpoint on the still life (or model) and students have more extreme changes to cope with, change or embrace.

    7.

    Then you give them long sustained poses with complete free will and let them apply what they’ve learned when they want to.

    How Could We Increase The Tolerance for Chaos in Software Engineering?

    1. Shifting Priorities. Assignment is a choose your own adventure – you have a list of features to add, and some discussion about priorities of each. There are a series of deadlines, and at each deadline you have to hand in a feature, but it’s up to you which. The catch – each new round of deadlines, the features and the priorities change. The worse the choices you make early on (most interesting feature instead of most important? Added bells and whistles instead of infrastructure?) the harder things will get.
    2. Shifting People. Assignment is a series of features. After each deadline, you get someone else’s code. You lose marks for re-writing it unnecessarily. Added  chaos – the features are not ordered.

    Group work is supposed to teach this – or the experience of working with other people in a team, at least, and sometimes it works, but too often one person takes on the task of writing everything. Other students can then feel alienated and inadequate, view it as their failure to be the person doing all the work. It’s actually a failure of the exercise.

  • 5 Reasons to Build a Native App

    cellphone
    Credit: Flickr / Janine

    Notifications

    This is a really common reason to want users to have a native app, but the question is – do users actually want alerts for this product? And if so, how many? For example news apps – they could sent an alert for every new story but that would be excessive! It’s important to be selective.

    If the app overloads on notifications, users have a choice between turning off notifications for that application, or removing it. Removing it takes fewer taps.

    This is the only option that isn’t available (at all) in a web-app.

    Offline

    Offline experience natively is really pretty easy. In the browser, much much harder. If offline is important (the biggest place I notice the lack of offline is my RSS reader, which renders it basically unusable on the tube) it usually makes sense to go native, depending on the complexity of your application and how much needs to be reimplemented.

    Location

    One-off location is obtainable through the browser, but anything that requires more than that, e.g. ongoing location, or location-based alerts, needs to be native.

    Uber is a good example of this.

    Camera

    You can upload pictures through the browser (as of iOS 6), but it’s hard to imagine Instagram succeeding quite as much with a webapp. If images are an important part of the experience, the image selection and picture taking experience is much nicer from a native app.

    Audio

    Background audio requires that the app be native (with some limited exceptions), if your app uses a lot of audio, for example museum apps are very audio heavy, a native one will be able to be played in the background with the screen off (screen is a major battery drain), whereas this is not the case with the mobile web.

    Peak App

    I prefer native apps – to build, and to use. They are faster, more convenient, better at saving state. But, I only want them for things that I use a lot, or have a short period of high usage – museum or conference apps are good examples of this. I don’t tend to download them unless I’m on wifi.

    Heathrow Airport now has a native app. Which I have taken to be a sign that we have reached Peak App – I spend a lot of time at airports, but I can’t fathom wanting such a thing.

    There seems to be a knee-jerk reaction sometimes that “going mobile” means “build a native app”, but I don’t think this is true. The mobile web is one option, but I think more broadly, sharing and other social apps are also part of it. People are tasked focused in the use on mobile. By which I mean, they’ll think “I should find somewhere to eat”, or “I need to check my flight time” rather than “I want to explore everything that is going on at this airport”.

    Restaurants, for example, as people check reviews, and menus on the go. Personally I rarely go anywhere below an 7.5 rating on Foursquare (exceptions are usually personal recommendations). This is part of how mobile affects the restaurant business, but is the answer for each restaurant to have a native app? No, that is clearly ridiculous (although one chain does have one), the answer is about making sure that information about the restaurant is in the existing apps that users use to discover and decide where to eat.