Abstraction vs Duplication. Why DRY is bad advice

In this post, I want to challenge the DRY mantra.


Don’t Repeat Yourself!

This is something that we are fed on a seemingly continual basis.

No matter how you came into software engineering, whether through a computer science degree, or through less formal training, you have probably heard many people exclaim that we should not repeat ourselves.

The DRY principle is stated as

“Every piece of knowledge must have a single, unambiguous, authoritative representation within a system”.

If for some reason, this has bypassed you, or if you haven’t read the book, then I would encourage you to checkout The Programatic Programmer, by Andrew Hunt and David Thomas.


There are some problems though with the way that DRY is often interpreted that I want to highlight.

It’s something that I see come up frequently to the detrement of good software design. It’s something that can cause more issues than it solves despite coming from a place of good intention.

If we go back to the wikipedia definition of DRY, we can see it talks about DRY vs WET solutions

Violations of DRY are typically referred to as WET solutions, which is commonly taken to stand for either “write everything twice”, “we enjoy typing” or “waste everyone’s time”.

This sounds fine in theory, but the problem is when we seek to avoid to “write everything twice”, sometimes this can become never write anything twice. And this is where I think the problem lies.

Instead of us seeking to avoid encoding the same knowledge in more than one place, it often manifests itself as never write the same or similar looking code twice.

And this causes problems when we have similar looking code, similar business processes in our code, similiar sequences of method or funciton calls that are only similar, not the same.

In my view, attempting to coerce them into some common place, so that we don’t have similar looking code, or the same line of code in two different places is the wrong thing to do. Far too often I see developers prematurely create abstractions out of fear of having duplicated code.

The problem is that these abstractions are often very weak abstractions, or only appear to be a meaningful abstraction at surface level.

I want to look at a couple of examples of this in action, firstly in application code, and then in test code.

Here is an example of some application code that certainly suffers from over abstraction, of being too DRY.

package com.seriouscompany.business.java.fizzbuzz.packagenamingpackage.impl.strategies;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.seriouscompany.business.java.fizzbuzz.packagenamingpackage.impl.strategies.adapters.LoopContextStateRetrievalToSingleStepOutputGenerationAdapter;
import com.seriouscompany.business.java.fizzbuzz.packagenamingpackage.interfaces.loop.LoopContextStateRetrieval;
import com.seriouscompany.business.java.fizzbuzz.packagenamingpackage.interfaces.loop.LoopPayloadExecution;
import com.seriouscompany.business.java.fizzbuzz.packagenamingpackage.interfaces.strategies.OutputGenerationStrategy;

@Service
public class SingleStepPayload implements LoopPayloadExecution {

	private final OutputGenerationStrategy _outputGenerationStrategy;

	@Autowired
	public SingleStepPayload(final OutputGenerationStrategy _outputGenerationStrategy) {
		super();
		this._outputGenerationStrategy = _outputGenerationStrategy;
	}

	@Override
	public void runLoopPayload(final LoopContextStateRetrieval stateRetrieval) {
		final LoopContextStateRetrievalToSingleStepOutputGenerationAdapter adapter =
				new LoopContextStateRetrievalToSingleStepOutputGenerationAdapter(stateRetrieval);
		this._outputGenerationStrategy.performGenerationForCurrentStep(adapter);
	}

}

 

This is from a version of the classic FizzBuzz problem.

It’s intended to poke fun at the common ‘enterprise’ Java code that exists, but it’s not too far removed from reality. It has all of the hallmarks of developers being too eager to generalise, to introduce abstractions.

Here’s an example of the same kind of problem from a different project, but this time in test code.

public class IntegrationTestUtil {

    public static final int AVAILABLE_SEATS = 20;


    public static Pair<Event, String> initEvent(List<TicketCategoryModification> categories,
                                                OrganizationRepository organizationRepository,
                                                UserManager userManager,
                                                EventManager eventManager) {

        String organizationName = UUID.randomUUID().toString();
        String username = UUID.randomUUID().toString();
        String eventName = UUID.randomUUID().toString();

        userManager.createOrganization(organizationName, "org", "email@example.com");
        Organization organization = organizationRepository.findByName(organizationName).get(0);
        userManager.insertUser(organization.getId(), username, "test", "test", "test@example.com", Role.OPERATOR, User.Type.INTERNAL);
        userManager.insertUser(organization.getId(), username+"_owner", "test", "test", "test@example.com", Role.OWNER, User.Type.INTERNAL);

        LocalDateTime expiration = LocalDateTime.now().plusDays(5).plusHours(1);

        Map<String, String> desc = new HashMap<>();
        desc.put("en", "muh description");
        desc.put("it", "muh description");
        desc.put("de", "muh description");

        EventModification em = new EventModification(null, Event.EventType.INTERNAL, "url", "url", "url", "url", null,
                eventName, "event display name", organization.getId(),
                "muh location", desc,
                new DateTimeModification(LocalDate.now().plusDays(5), LocalTime.now()),
                new DateTimeModification(expiration.toLocalDate(), expiration.toLocalTime()),
                BigDecimal.TEN, "CHF", AVAILABLE_SEATS, BigDecimal.ONE, true, Collections.singletonList(PaymentProxy.OFFLINE), categories, false, new LocationDescriptor("","","",""), 7, null, null);
        eventManager.createEvent(em);
        return Pair.of(eventManager.getSingleEvent(eventName, username), username);
    }

}

 

This is some test code taken from an open source project that I won’t name, and it’s a little different to the application code example. This time, we are looking at some so called ‘helper’ code that is used by many different tests.

There are less technical abstractions present, but there is still a high degree of coupling. We have common test setup methods that at first glance seem like they might provide a benefit to us. After all, it saves us from having to do all of that same setup in each test method.

The problem with this is though, that far too much setup has made it’s way into this common method. Every line of that shared test setup code is relevant to one or more of the test methods, but not all of that setup is revelant to every test.

This creates brittle and fragile tests, where for any given test method, we don’t know what input is relevant to the scenario being tested.

And, if we need to have more or slightly different input data for a particular test, then if we add to or modify that shared test setup, we don’t know what effect that might have on the other tests using this setup method.

I have seen test code with a large number of shared test setup helper methods get to the point over time that these shared methods have been modified so much, some of the tests are no longer testing what they original were, because of the lack of clarity of the relevant input data for each test.


To summarise the examples, they both suffer from the problem of developers being too keen on not duplicating code.

This has been taken to the point of not wanting to duplicate the same or similar set of method calls in a codebase, and has resulted in abstractions exisitng not to encapsulate something from our problem domain, but to simply avoid code duplication.

These are vague abstractions that increase complexity.

This kind of coupling can result in:

  • Developers being fearful of changing the common code in case it breaks some unknown part of the system.
  • Excessive parameters being added to methods to control different branches or use cases of the shared code.
  • Logic relating to a particular use or case or area of business logic becomes fragmented, and distributed between classes.

Signs that we should be duplicating code

Thankfully though, there are some things to look for in our codebase that could indicate we are creating an artificial abstraction that might increase rather than reduce our complexity.

These traits in your codebase don’t necessarily mean you have this problem, but should be indicators you need to pause for a minute and work out whether you are heading in this direction

Some of these are:

  • Classes with only one methods
  • Classes with methods that are named pretty much the same as the class itself
  • Big if statements in methods with a parameter used to control which branch executes
  • Classes named after what they do rather than what they represent i.e. named after the code they call, and typically contain suffixes such as ‘Orchestrator’, ‘Manager’, ‘Utility’, ‘Helper’ etc
  • Abstractions that exist for ‘future’ benefit e.g. to allow a part of the system to be swapped out in future.
  • Large amounts of configuration required just to wire up dependencies

So, what should we do?

So to conclude, if you see yourself spotting traits like this in your codebase, then I would recommend you start off by duplicating code instead of creating abstractions.

Then, once you have a good understanding of how the different parts of your codebase use the duplicated code, you can decide whether or not there is a genuine common abstraction that should exist.

Sometimes there may well be a valid abstractions that should exist to encapsulate something about your problem domain and it’s behaviour.

Often though, we don’t actually need to introduce new abstractions. Remember that they are not cost free. They introduce coupling and complexity.

In my experience it’s almost always cheaper and easier to fix the codebase, starting from a point of having a small amount of duplicated code rather than try to deal after the fact with high complexity and coupling with the wrong abstractions in place where you have to try and unpick the shared code.

Duplication is far far cheaper than the wrong abstraction.

Code review goals and merits, and why you might not always need to do it

I want to talk about code reviews.

Pretty much every job I have ever had as a software developer and every client I have worked with has had some kind of code review process.

A simple search for the term code review yields many results, so what do I think I can add to the conversation?

Well, most of these search results either relate to specific things we should be doing or looking for in a code review, or are for tooling to supposedly allow us to review code better, or to actually force us to do a review.

Most organisations though, aren’t talking about why we do code reviews. I am a firm believer in equipping myself with a set of tools as a developer, and then having the ability to make intelligent selection of the right set of tools to use in a given situation, given a set of goals I am trying to meet. Tools such as TDD, unit testing, integration testing, pair programming, and, yes, code reviews.

Moat organisations and development departments are keen to put a code review step in place, probably as a mandatory step in Jira in between development and test.

After all, it’s pretty hard for anyone to argue that code review is a bad thing.

My problem though is that this can often leave us with a process that just feels good. It feels like we are doing the right thing by having a mandatory review step.

But, if we don’t agree on what purpose this step in our development process is serving, then how do we know it is serving this purpose, and therefore a valuable thing to be doing?

And, as a reviewer, how do I know what I should be checking?

Should I be running the code?

Just inspecting the code?

And what should I look for when I do inspect it?

If I do have any questions or comments, then does the original developer have to address all of them?

So, what is the point?

I would like to start by working out what some of the most common reasons people cite are for doing code reviews, and use this as a starting point.

Once we have this, I would then like to look at a number of different tools that we might use to achieve those cited benefits.

I feel that code review is almost always used dogmatically, without a shared purpose in mind. If we equip ourselves with a shared view on what we are setting out to achieve, then we may find that code review isn’t always the right tool.

And when it is the right tool, we can deploy it far more intelligently, more precisely and effectively with confidence we are looking for the right things.

OK, OK, I get it, so why do we do code reviews?

Looking at some of the popular search results for ‘code review’, we can see many posts providing us with a set of guidelines we should or could follow.

For example, in a post that lists ‘10 best practices for code review’, we see that the very first two points tell us how many lines of code we should be reviewing at once, and the rate at which we should be reading these lines of code.

The reasons for this, we are told, are because deviating from this will affect our defect detection rate.

Ah, ok, so code reviews are about detecting defects then?

There are other points, and indeed many other articles, that all focus on code review from the perspective of being an exercise in detecting defects in code before it goes live.

For many people, this is the sole reason for performing code review.

There are many other posts, that tell us there could be other reasons for doing code reviews.

The most common ones are:

  • To ensure that appropraite ‘coding standards’ are maintained
  • It’s a learning exercise for the reviewer, or a way of sharing knowledge
  • It helps to detect bad or wrong design
  • It encourages collaboration
  • It ensures non functional requirements such as security or performance have been met
  • It ensures the appropriate tests exist alongside the code

So how do we do code review?

So, with 90% of the developers and teams I have worked with, it goes something like this:

  1. A developer finishes work on something, raises a merge request, and moves the Jira card from ‘Development’ to ‘Review’
  2. The original developer will either assign the merge request or review to someone explicitly, or request that someone who feels like reviewing this should pick up this review task
  3. The reviewer will independently look at the code in the merge request, and make a number of comments against the changes in the merge request
  4. The original developer and reviewer go back and forward a few times, making changes to address comments, re-reviewing etc
  5. Once the reviewer is happy, they will either accept the merge request (and responsibility of it), or let the original developer know that they are happy for the request to be merged
  6. The Jira card moves along to the next step, typically some kind of ‘Ready to test’ or ‘Test’ state

This is how it tends to happen most of the time.

Sometimes developers will sit together to walk through the review.
Sometimes there are more formal review meetings.

But in my experience, this is how most people implement a code review process.

Does this process work?

It can do. I have seen it work, but often there are a number of issues with this kind of workflow.

One of the biggest problems, as mentioned before, is that people go into this with the wrong mindset. They perform code reviews, mainly as an unfocused feel-good exercise. Yes, good reviewers will catch issues, give good feedback etc. But this happens unreliably because most people don’t have a shared view as to what they are trying to achieve with these reviews.

Another big issue is that, especially when code reviews are the time that feedback on design is given is that often this feedback comes to late to do anything productive with it.

It’s pretty demotivating to find out after having written a lot of code that someone else thinks we should change it all. No one wants to be in this position, and to be honest most people wouldn’t want to have to tell someone this either. It’s far too late for code review to be an effective way to validate design. This leaves you with either two developers feeling uncomfortable, or sub-optimal design getting through.

Also, due to the asynchronous nature of a code review, often by the time feedback is given, it’s an interruption to the thing the developer is trying to focus on.

Note, I’m not saying don’t code review. Please please do code review, but do it intelligently, with the pitfalls in mind.

So, what should we do?

Treat code review more like a tool used to achieve something, rather than a process.

This means first of all, working out, and agreeing on the goals you have, the things you want to be able to verify and try to protect against.

So, you probably want to agree on design standards, coding standards, what your approach to testing is, what kind of non functional requirements you have.

Once you have agreed these things, written them down somewhere, then for each change, rather than trying to cover all of those bases at once, after the code has been written, think about how and when you can ensure those goals are met for any given change.

Decide which tool or tools you can deploy most effectively to verify the things you care about for any given change.

The key thing is, some changes may require more or less review, at different points in time. For some changes you may want to discuss and decide on the design before doing any code. Sometimes part way through coding design choices come up. Some changes are so simple it isn’t an issue.

Sometimes, the way to ensure coding standards could be through the appropriate use of static code analysis tools.

Sometimes it could be more effective to just pair program the change with someone who knows the area of code being changed well.

And if traditional pair programming isn’t right, then how about cooperative pair programming?

For knowledge transfer, maybe code review isn’t the best tool to use. If learning is a goal, then don’t expect someone to learn how something works and at the same time be capable of giving critical feedback.

If you approach this from place of goals, the needs you want to meet, not from process, and recognise code review is a tool, then it frees you to make intelligent choices on a case by case basis, with full knowledge of what your goals and standards are.

So, it’s not a step in a Jira driven process. It’s a way to make sure the standards you set for yourself (and agree on) are met.

Hopefully this should mean then when and where you do decide to have someone review code, you do it at the right time, and both parties know exactly what to expect, and can actively engage with the process, and see it as a good thing, providing benefit. Something more collaborative than moving a Jira card along and hoping someone will rubber stamp it.

References

Credit goes to the people and pages linked below. Check them out, but remember to work out what you are trying to achieve in your specific situation

https://github.com/thoughtbot/guides/tree/master/code-review

https://blog.fogcreek.com/increase-defect-detection-with-our-code-review-checklist-example/

https://msdn.microsoft.com/en-us/library/ms182019(v=vs.100).aspx

http://jibbering.com/faq/notes/review/

https://www.atlassian.com/agile/code-reviews

https://cwiki.apache.org/confluence/display/QUICKSTEP/Code+Review+Guidelines

https://mozillascience.github.io/codeReview/review.html

https://everydayrails.com/2017/01/16/code-review-mindset.html

https://blog.mavenhive.in/pair-programming-vs-code-reviews-79f0f1bf926

https://developers.slashdot.org/story/16/01/21/1749247/code-reviews-vs-pair-programming

https://arxiv.org/abs/1706.02062

https://collaboration.csc.ncsu.edu/laurie/Papers/XPSardinia.PDF

http://engineering.pivotal.io/post/pair-programming-in-a-distributed-team/

https://smartbear.com/learn/code-review/best-practices-for-peer-code-review/

http://www.evoketechnologies.com/blog/code-review-checklist-perform-effective-code-reviews/

Your unit tests are probably slowing you down

If you are looking at this post, you are probably interested in test driven development, or at the very least unit testing.

TDD, unit testing, and other levels of testing, are, in my mind, just a set tools we can use to help us write better software quicker.

I’m not going to come down hard on people and say thou shalt only write code if there’s already a failing test. There are many times writing tests first is the wrong thing to do.

That said, I think TDD is a tool that is often under used.

I think it’s under used for one reason. And, it’s the same reason I see so many unit tests that are actually harming your development not helping it. These are tests that at surface level seem like they are good tests, adding value, but on closer inspection are actually hurting your development, and just storing up problems for you, and actually even in the short to medium term, slowing your team down.

So, what is this reason?

Well, I believe it’s that for the most part, most developers, even some of the great developers out there, are actually approaching their tests with the wrong mindset, thinking about their tests in the wrong way.

And, by the way, I don’t blame them for this.

In the world of information overload that we live in, I see so many well intentioned blog posts, describing TDD, unit testing, or even just software development in a way that is overly simplified. The problem with this, is that people then come away with the impression that this simplified view of the world covers everything they need to know. That’s all there is to doing TDD.

It’s not helped by the fact that some of the downsides to the tests that most people end up with aren’t actually seen until a little further down the road, when they try to build upon or refactor the functionality they have ended up with.

Then they are in a world of pain, usually with large amounts of tests failing, no one knowing whether the tests or the code is wrong, and spurious bugs because of this.

The developers that I have seen though, that have learnt themselves, or through others like myself coaching them to adopt the right mindset when approaching TDD, are able to work quicker both in the short term and the long term, where tests speed up their work, not slow it down, avoiding problems of brittle tests failing for unknown reasons.

So, if mindset is the important, then what is the wrong mindset, and how should you think about tests instead?

So, I want to describe this by showing an example. This is taken from an open source project that I won’t name, because I don’t want to make it sound like I’m being critical of the person that created it. As I said before, there’s so much information out there that tells us that this is all we should do.

The code that this is testing is from a TODO list application, something that’s often used as an example application because there’s enough complexity there to be interesting, but not too much.

it('should PUT /tasks/:id 200', function (done) {
    request(app)
    .put('/tasks/' + this.id)
    .send({title: 'foo'})
    .expect(200, function (err) {
      assert(err == undefined);
      request(app)
      .get('/tasks')
      .expect(200)
      .end(function (err, res) {
        assert(err == undefined);
        assert(res.body[0].title === 'foo');
        done();
      });
    });
  });

 

So looking at this test, at first glance, it might seem OK. It’s testing that we can PUT a new task. It’s a pretty small test, so we can read it relatively easily.

The test name is ok. Again, it seems to indicate this test is about PUTting a new task. It also ends with ‘200’ which I think we might assume is the expected response code. So, I assume from the name that this is testing the successful test case.

Aside from the name giving us a few things we have to think about or assume, there are some other problems with this test, and tests like this.

This test is more brittle than it should be, and from looking at this and other surrounding tests, I can see that the approach taken to testing, which is the most common approach I see, is one in which the developer is clearly focused on the method, or action being invoked in the test, in this case the PUT method.

Now, you might not see a problem with this, but bear with me.

Instead of focusing on the method or action being tested, I think that we should instead focus on the behaviour of the system under test, which might seem like a different way of describing the same thing. But it’s not. It is different.

Through my own experience and that of others I have coached, I have seen much better results, much more maintainable code, giving the ability to work much quicker at a higher quality when adopting a more purposeful mindset. And no, I’m not talking about BDD syntax here.

So, breaking this test down, let’s look at what it is doing line by line.

it('should PUT /tasks/:id 200', function (done) {
    request(app)
    .put('/tasks/' + this.id)
    .send({title: 'foo'})
    .expect(200, function (err) {
      assert(err == undefined);
      request(app)
      .get('/tasks')
      .expect(200)
      .end(function (err, res) {
        assert(err == undefined);
        assert(res.body[0].title === 'foo');
        done();
      });
    });
  });

So, here, we are creating a PUT request. That’s great, that’s our action being tested.

it('should PUT /tasks/:id 200', function (done) {
    request(app)
    .put('/tasks/' + this.id)
    .send({title: 'foo'})
    .expect(200, function (err) {
      assert(err == undefined);
      request(app)
      .get('/tasks')
      .expect(200)
      .end(function (err, res) {
        assert(err == undefined);
        assert(res.body[0].title === 'foo');
        done();
      });
    });
  });

We have some input data here – an object with a title field

it('should PUT /tasks/:id 200', function (done) {
    request(app)
    .put('/tasks/' + this.id)
    .send({title: 'foo'})
    .expect(200, function (err) {
      assert(err == undefined);
      request(app)
      .get('/tasks')
      .expect(200)
      .end(function (err, res) {
        assert(err == undefined);
        assert(res.body[0].title === 'foo');
        done();
      });
    });
  });

Now, our first assertion, we are making sure that we get a 200 response back

it('should PUT /tasks/:id 200', function (done) {
    request(app)
    .put('/tasks/' + this.id)
    .send({title: 'foo'})
    .expect(200, function (err) {
      assert(err == undefined);
      request(app)
      .get('/tasks')
      .expect(200)
      .end(function (err, res) {
        assert(err == undefined);
        assert(res.body[0].title === 'foo');
        done();
      });
    });
  });

Now, another assertion, this time, asserting that no error is returned, but also unfortunately losing those error details.

it('should PUT /tasks/:id 200', function (done) {
    request(app)
    .put('/tasks/' + this.id)
    .send({title: 'foo'})
    .expect(200, function (err) {
      assert(err == undefined);
      request(app)
      .get('/tasks')
      .expect(200)
      .end(function (err, res) {
        assert(err == undefined);
        assert(res.body[0].title === 'foo');
        done();
      });
    });
  });

Next, we are making an additional request. This time, a GET request to retrieve the newly created task

it('should PUT /tasks/:id 200', function (done) {
    request(app)
    .put('/tasks/' + this.id)
    .send({title: 'foo'})
    .expect(200, function (err) {
      assert(err == undefined);
      request(app)
      .get('/tasks')
      .expect(200)
      .end(function (err, res) {
        assert(err == undefined);
        assert(res.body[0].title === 'foo');
        done();
      });
    });
  });

Here, again, we have another assertion, making sure we get a 200 response back

it('should PUT /tasks/:id 200', function (done) {
    request(app)
    .put('/tasks/' + this.id)
    .send({title: 'foo'})
    .expect(200, function (err) {
      assert(err == undefined);
      request(app)
      .get('/tasks')
      .expect(200)
      .end(function (err, res) {
        assert(err == undefined);
        assert(res.body[0].title === 'foo');
        done();
      });
    });
  });

And another again, ensuring there is no error.

it('should PUT /tasks/:id 200', function (done) {
    request(app)
    .put('/tasks/' + this.id)
    .send({title: 'foo'})
    .expect(200, function (err) {
      assert(err == undefined);
      request(app)
      .get('/tasks')
      .expect(200)
      .end(function (err, res) {
        assert(err == undefined);
        assert(res.body[0].title === 'foo');
        done();
      });
    });
  });

And finally, another assertion, making sure the task title is the one we sent in the PUT request.

So, from this set of assertions, it seems our assumptions about this test are correct. It is testing the success case.

The problem though, is that this test is actually testing many many things all at once. It is testing multiple behaviours in the same test method. We can see this by the number of assertions we have, but also the types of assertions.

Just because a behaviour of the system is triggered by one particular method, with a particular input, does not mean that it should be verified in the same test as a different behaviour.

We also have coupling. The way this test verifies the task has been created is via the GET method, which in turn has a couple of assertions, relating to status code etc.

If the GET method code became broken for any reason, then this test would fail, even if the code relating to task creation was working perfectly.

Taking a more behaviour oriented, purposeful approach to thinking about the PUT method would result in more tests, each with a more clearly defined purpose e.g. rather than the test we have seen, why not have

it('should return a successful response when attempting to PUT task title changes', function(done) {
request(app)
    .put('/tasks/' + this.id)
    .send({title: 'foo'})
    .expect(200, done)
}

This test is only verifying the response, not any side effects.

We can then have a second test

it('should store the updated title against the given task when making a PUT request with a new task title', function(done) {
var datastore = this.datastore
var taskID = this.id
request(app)
    .put('/tasks/' + this.id)
    .send({title: 'foo'})
    .end(function () {
      datastore.updateTask.should.have.been.calledWith(taskID,{title:'foo'})
      done();
    });
}

 

This test should verify the data store interaction required to update a task’s title, probably using a fake or a mock version of the data store. It should only verify this. We don’t need to repeat assertions for the 200 response that we already have in the new test above

In addition to these tests, we probably want other test cases too, like what response should be received if we give an invalid task ID, what happens if we attempt to modify a task with no new task data etc

So, in this example, we have taken 1 test, and by taking a more behaviour oriented approach have done a couple of things.

We have split it into 2 tests, to decouple verifying our different behaviours

1 – the HTTP handling and response generation
2 – the interaction with the data store, the business logic if you like of updating the task

We have also decoupled the test relating to PUTting tasks from the GET request. We no longer need to make a GET request to verify our behaviour.

These changes might seem subtle, but shifting your approach and mindset in this way, will lead to test improvements in terms of having more obvious, clearly defined tests that are not as brittle, leading to a more maintainable system going forward.

I go into much more detail of this technique, and other principles and strategies you can apply to your own unit testing and test driven development in my new 6 week course, TDD Made Easy.

Code That’s Trending: What You Should Be Learning In 2017

Only a little over two decades ago, the biggest technological innovation was IBM’s one-gigabyte hard drive (retailing at a mere $3,000) and the introduction of Windows 95.

To say that tech has changed in the last 20 years is an understatement.

But what will technology look like 20 years from now? Will the war between iOS and Android be redundant? Will fully functioning robots finally be a thing?

It’s hard to say for sure, but the reality for those who work in technology – in this case, programming and coding – things will most certainly change. In fact, things have already started to shift in 2017.

For coders looking to take advantage of some of the new tech, languages, frameworks, and programming strategies out there, here are a few key places to start.

[ Content upgrade with ID = 383 not found ]

Preprocessors

CSS preprocessors – like LESS and SASS – have been around for awhile now, but devs have finally been catching on to their real potential in the last few years, and their popularity will most likely continue to grow over the coming year.

In the past, full language stacks were all the rage, and coders would spend hours building everything from scratch. But then someone figured out that you could build on the work of others by using CSS to extend basic functionality, and preprocessors were born.

Preprocessors can take a chosen language and use it as the foundation for larger projects. Some of the other advantages include:

  1. Modularization for your styles
  2. Reduced redundancy with variables and mixins
  3. Code reuse across multiple projects
  4. Nested, Smart styles

Of course, if you’ve never worked with preprocessors before, know that there is a bit of a learning curve. Because they have their own syntax, you’ll most likely need to choose a single preprocessor to learn first and then move on to the others from there. If you have a good foundation in JavaScript and CSS, you’ll have a solid head start.

JavaScript MV* frameworks

JavaScript frameworks are another underutilized area of development that may see more playing time in the coming year.

Consider these frameworks – called MV* frameworks (model-view-wildcard) as a sort of “next step” to working with vanilla JavaScript files (plain .js libraries sans jQuery).

Popular frameworks include Kendo, Sencha, jQuery Mobile, AngularJS, Ember, Backbone, and Meteor JS, though there are more. Part of their job is to handle some of the more complicated processes of HTML5 Web Apps and to help developers work across different platforms, like desktop to mobile.

Since Web Apps using HTML5 and cross-platform development are both on the rise in the tech world, it makes sense for developers to point their ears in that direction as well.

Single-Page Web Apps

As long as you’re learning how to work with JavaScript frameworks, you may as well learn more about the intricacies of Single-Page Web Apps (SPAs) too.

While SPAs still lag behind traditional web pages in terms of popularity, their use has been growing over the past several years.

An SLA is essentially a single, responsive landing page that works just like an app. The front end of the page pulls from a much larger database filled with content without the developer needing to add markups to every piece of data, so the page stays regularly updated with minimal effort.

They’re also much faster than traditional pages, as the HTML, CSS, and scripts only load once throughout the lifespan of the application. Only data is transmitted back and forth, so bandwidth is reduced and page speed is increased.

Considering how much time and energy is spent by developers creating, updating, and maintaining web pages, you can probably see why SLAs are catching on.

SVG + JavaScript on Canvas

Many tech prophets have been proclaiming the Death of Flash for a while now, so it’s no surprise that it’s on the outs. But Flash has been an integral part of web development for a long time now, and many devs love the look and function of it.

The answer is HTML5 Canvas, which uses SVG (Scalable Vector Graphics) and JavaScript as building blocks to create a better animation.

Developers can essentially “draw” elements using JavaScript code instead of going through the rigorous process of creating animations using Flash.

This process is significantly better for mobile animations, as many devices require scalable graphics to function properly on small screens (and SVG is known for scalability).

With mobile animation on the up-and-up, developers will need to find better ways to create animation that works on a variety of different devices both large and small. So far, SVG and JavaScript on canvas is the best solution.

Machine Learning

When we say “machine learning” we don’t necessarily mean robots taking over the world like The Matrix. Machine learning in web development refers to Artificial Intelligence (AI) algorithms that give programs the ability to learn without being programmed.

Machine learning is incorporated in flashy, headline-grabbing technology like Google’s self-driving car, but it can also handle tasks like tracking activity in one application and relaying that to a different one (say, what you watched on Netflix to what you buy on Amazon).

As of right now, machine learning is still relatively in its infancy. Tools using machine learning run the gamut from performing simple computing tasks all the way up to problem solving tech like Amazon’s Echo or even Apple’s Siri.

As the demand for this sort of “smart technology” continues to grow, so will the demand for developers who understand how to use it properly.

Basically, if you want to make sure your job is relevant in the next 20 years, familiarize yourself with machine learning and you’ll most likely never be out of a job.

[ Content upgrade with ID = 383 not found ]

Final Thoughts

Of course, not all the trends listed here are for the faint of heart, and a modicum of knowledge in any will require some effort and dedication to learning. But that doesn’t mean that these trends are outside the reach of the beginner coder.

The key to successfully following the latest tech trends is to start with the basics: learn JavaScript, learn HTML, learn how to build a website.

Once you’ve mastered the “vanilla” levels of coding, you can move on to something with a little more flavor. And who knows, maybe someday you’ll be the one inventing the latest and greatest technology trend on the market.

 

Should Developers Learn to Design? How to Code for Looks

The relationship between designers and developers often gets a bad rap, but the two roles frequently run parallel.

Designers are often encouraged to learn code to better understand what happens behind the scenes, and some developers actually start as designers and work their way into becoming a hybrid of both roles.

But what about developers who have no love for art? Should they learn to design too?

There are certainly enough jobs available for a pure developer who wants to stick with coding, but there’s a good case to be made for developers – even those that lack an artistic flare – to learn how to design, too.

[ Content upgrade with ID = 370 not found ]

desk-office-pen-ruler

Learning Empathy

Developers should learn how to design for the same reason designers are encouraged to learn code – empathy.

According to Stephen Caver from Happy Cog:

“The primary reason any developer should learn design is to gain empathy for the designers with whom they work. Nothing is more toxic to a project than developers and designers seeing each other as rivals.”

Developers and designers often approach projects from completely different perspectives, and both are necessary for a great user experience.

But for a developer who doesn’t understand the creative process, it can be difficult to problem solve for designers who want to implement creative strategies. You might think, “Why are we doing this?” instead of, “How can we do this?”

Learning to think like a designer will help you overcome obstacles and create solutions faster. In fact, according to ex-designer Mark Kawano, tech giant Apple encourages developers to “think like a designer.”

“I think the biggest misconception is this belief that the reason Apple products turn out to be designed better, and have a better user experience, or are sexier, or whatever … is that they have the best design team in the world, or the best process in the world,” he says.

Thinking like a designer can also help developers communicate more efficiently and collaborate on projects with less interference.

14804632142_38c5c63424_b

How to Think Like a Designer

UX/UI designer Drew Lepp argues that there are actually two definitions of a designer:

  • Someone who designs
  • Someone who is creative with a purpose

Even if a developer doesn’t fall into the first category, they should strive to fall into the latter. According to Drew, there are six ways to be creative with a purpose:

  1. Strive to do better
  2. Be relentlessly optimistic
  3. Dream big
  4. Have empathy
  5. Be comfortable with the uncomfortable
  6. Bring clarity to complex ideas

Thinking like a designer is essentially about looking at a project with broader scope so that you’re not just following directions, you’re innovating. It’s about understanding the needs, desires, problems and aspirations of a business so that you can experiment with forward-thinking solutions.

But thinking like a designer is also about understanding how aesthetics play a role in the final product.

It’s about focusing on things like the look and feel of a website, how color psychology affects the end user, how to unclutter a website for easier navigation, and how to organize elements to net the highest conversions.

Learning the principles of design can help developers become better coders, and coding for visual appeal and user experience will improve your chances of building a high converting site or application the first time around.

You may also have the opportunity to help clients who don’t know what they want. You will be able to clarify confusing elements of a project to them as well as understand their wants and needs better than code along can communicate.

Basically, thinking like a designer will help you become more well-rounded in your profession, helping you work better in teams and one-on-one with clients.

web-design-1419696_1280

Where to Learn Design

So how does a developer learn to code for looks?

One of the quickest ways to learn something is to ask someone who has done it. This means picking the brains of other designers or hybrids and taking note of what matters.

Another way to is to find a course or program that specifically teaches design. David Kadavy at Design for Hackers has a program geared toward developers, and places like Lynda.com specialize in design programs. Or you can find design tutorials on EnvatoTuts+.

But what sort of things should you focus on?

Even if you don’t want to learn how to design a whole website from scratch, you should understand design principles from areas including:

  • Font – how to choose the right fonts for headers, subheaders, body copy, and accents
  • Sizing – how to size elements like fonts and images to stand out on a page
  • Color – how color psychology affects conversions and how to choose an appropriate color palette
  • White space – how to space distances between elements and how to get rid of unnecessary clutter
  • User experience – where to place design elements like pop-ups and navigation to improve UX
  • Copy – how to use copy to inform and move users through the site effectively

Having a general understanding of these principles will help you communicate with designers (and clients) who make design requests to you that seem unreasonable or confusing.

Again, you will understand the “why” behind the choices so you know how to respond if something simply won’t work from a development perspective, too.

[ Content upgrade with ID = 370 not found ]

Final Thoughts

Just because you learn the principles of design doesn’t mean you have to become a designer. In fact, there are some out there who believe that it’s better not to hire or work with a designer/developer hybrid (though others will argue the opposite).

But you don’t have to work as a designer to think like one. Understanding the basic principles of design, how to communicate like a designer, and how to implement creative solutions to improve user experience is a boon for any developer.

You don’t have to be artsy to think like a designer either. Creativity comes in all shapes and sizes, and more often than not, clients will be looking for developers who understand creative concepts and solve their problem in an equally creative fashion.

3 Things You Can Do With CSS That Will Blow Your Mind

CSS is one of the first languages many coders learn, and it’s an integral part of building any website. But it can do a lot more than handle simple style elements.

While traditionalists may relegate it to the basics – fonts, styling, colors, etc. – it can actually handle a variety of design complexities, like animation.

In fact, many modern developers are taking CSS to new heights with a variety of cool and surprising projects. Some of them may be advanced for beginner designers, but each project proves that there are limitless possibilities for working with CSS.

Here are a few inspirational ways you can use CSS for your next project.

[ Content upgrade with ID = 360 not found ]

Animations

The use of animation in web design has certainly gained momentum over the last decade or so. The methods and techniques for adding motion to an interface have become more advanced as well.

Old school designers and developers may have once relied on JavaScript to create eye-catching animations and videos, but CSS has taken on some of the heavy lifting in recent years, as shown by some of the world’s best developers.

Julian Garnier created a 3D model of the planets in orbit, for example.

Julian Garnier

Source: Codepen

Roman Cortes has been known to make complex animations purely out of CSS. His spinning effect on the image of a can of Coke shows what’s possible with a few simple styling sheets. When you scroll back and forth on his image, it looks as though the can is spinning.

coke_bottle_css

Source: Roman Cortes

But animated elements don’t always have to be so obvious. In fact, many of the most popular animations using CSS for the web today are subtle, like an animated menu button effect.

Developer Marius Balaj created a simple button animation that materializes when you scroll down.

mariusbalaj

Source: Codepen

And Sascha Michael Trinkaus created a hover animation for a check mark button that changes the surrounding gradient color.

animated_checkmark_button

Source: Codepen

CSS can also be used with motion curves for even more realistic animations. (Smashing Magazine has an explanation and a few examples of that here), but whether it stands alone or is used in combination with JavaScript, CSS can do a lot for the world of animation.

Text Effects

CSS can also be used to create stunning visual effects for text. In some cases, additional languages like SVG or JavaScript may be used to enhance the effect, but some incredible effects can be added solely with CSS.

Developer Hugo Darby-Brown recreated the Shop Talk logo from scratch using only CSS.

shoptalk

Source: Codepen

Patrick Brosset animated this logo (“Cosmos”) using simple CSS.

cosmo

Source: Codepen

Developer Yoksel takes this idea a step further by turning his text into a simple animation. This text effect is made with a combination of CSS and SVG.

elasticstroke

Source: Codepen

And Yoann Helin created a simple ticker effect that alternates text between three different words.

helloworld

Source: Codepen

While CSS is most often used to add color to fonts and background elements, it can also be used to create images, text, and animated text effects. When used in combination with JavaScript and SVG, there’s very little you can’t do with it.

Fluid Menus

CSS is often used for creating animated menus, and that’s nothing new. But the level of creativity isn’t limited to your average horizontal menu with a few drop downs or a hamburger menu. You can create dynamic and engaging menus that are mobile responsive with CSS.

This menu, for instance, uses transparent icons and an animated slider to create a unique transition effect between items on the navigation bar.

cssdeck

Source: CSSDeck

One developer named Travis created a single-page navigation menu for Mic.com (though they currently use the hamburger menu for their main site).

micnav

Source: Codepen

If you’re in love with the idea of using a hamburger menu, you could take a page out of developer Sergio’s book and create a morphing circular menu along with your hamburger menu.

hamburger

Source: Codepen

But you can also skip the hamburger in favor of a slider. Humaan’s site, for example, has an animated scrolling menu that slides right and stays fixed until reaching the very top of the page.

humaan

Source: Humaan

Navigation is often one of the trickier areas of web design and development, but with CSS, you can rethink traditional design elements to create something more attention grabbing or out-of-the-box for clients that want something a little extra.

[ Content upgrade with ID = 360 not found ]

Final Thoughts

There are plenty of other mind-bending things that you can do with CSS (like this Submarine with CSS by Alberto Jerez), as well as a slew of really practical stuff (like image filters and forms).

Overall, CSS is an excellent option for creating subtle text and logo animations as well as more robust animated images. It’s also very efficient and relatively easy to learn compared to other languages like SVG.

It’s especially great for transitions that require animation, like fluid menus, clickable icons, or buttons. It’s also an excellent way to create 3D animations, as most browsers have an easier time reading 3D animations made with CSS.

Because you can see exactly what you’re getting throughout the design process, you may have an easier time animating these effects with CSS rather than JavaScript (and the end results are equally stunning).

It opens a multitude of new doors for web designers and developers alike, making it possible to create animations and interactivity entirely with a relatively simple language.

Of course, you can combine JavaScript with CSS for advanced animations and really wow your clients, too.

How to Increase Your Daily Productivity and Code Faster

Developers always want to know one thing: How can I get this done faster?

Coding can be fairly time consuming depending on the project you’re working on, and it can eat away at your day if your workload is heavy, your deadlines are tight, or your processes are slow.

But just because devs want to get things done quickly doesn’t mean they want to do a rush job. Rushing through projects can lead to buggy or hard-to-maintain software that needs to be updated down the line (at a greater time expenditure).

Thankfully, you don’t have to sacrifice quality to get the job done faster. Here are a few tips for speeding up your performance without dumbing down your work.

[ Content upgrade with ID = 343 not found ]
characteristics-of-the-best-web-development-company

Gain More Experience

It may seem counterproductive to spend more time working on projects if you’re looking to save time, but the reality is that the more experience you have, the faster you’ll be able to churn out code that doesn’t require extensive debugging later on.

In the early stages of your dev career, you can gain experience and improve your speed and productivity simply by working on your current projects.

You can also:

  • Work on side projects
  • Work on open source projects
  • Work with other, more experienced developers
  • Test out productivity tools and techniques
  • Do programming exercises

You can (and should) monitor your improvement based on both objective metrics like defect rate and velocity, and subjective metrics like code quality and fitness.

If you’re worried about quality, don’t assume that slower work will give you better quality code. The more you practice, the more refined your system becomes and the more productive and effective you’ll be.

Jeff Atwood over at Coding Horror learned a valuable lesson on this from the book Art and Fear by David Bayles.

The book tells the story of a ceramics teacher who asks half of his class to create a large quantity of pots, and then pitted them against the other half of the class who were instructed to produce a single, “perfect” pot.

The teacher found that the students that created a large quantity of pots were producing better quality pots than the students who only had to do one high quality pot.

The takeaway according to Atwood: “When you repeatedly learn from your mistakes, (when you have more experience with a system or method), you will produce better work.”

Automate Testing

Aside from sheer experience, you can also greatly improve your speed and productivity by either catching errors as you go through or automating the testing process.

If you can catch an error while you’re typing it, you will save ten times the effort than having to go back and redo it. But catching every single error with the human eye isn’t always possible, and that’s where automation comes in.

loading-speed-2-01

The purpose of automation is to provide fast feedback, both of successes and failures. The longer you go without feedback, the more time you will have to spend fixing mistakes later on.

This is also important if you have to spend time fixing someone else’s code, or they have to spend time fixing your code. The person who made the mistake understands the error best, so the sooner feedback can come through, the easier the fix will be.

So, how should you go about creating automation?

Ultimately, the best person to build a test stack is you. While this is another example of “taking more time now to make time later,” developing your own automation stack is important to improve productivity.

But think of it like this: If you were using someone else’s automation stack, you would have to learn the tools and tricks to use it, which would take more time.

You already know most of the processes you need to automate, so spend a little time on the front end of the process to build automation and you’ll save heaps of time later on when it comes time to actually produce.

The same principles apply to things like reusable libraries and templates. If you can find something (or build something) that works for you, you will improve productivity automatically.

You will also get some much needed coding experience, too.

Reassess Expectations

Another area that might be slowing down your process – and one which is often overlooked by developers – is actually something that has nothing to do with you: it could be your managers or team.

If you work for an agency or in the corporate world, the slowness of your project may not be your fault, at least not entirely.

The management team plays an important role in setting expectations, helping developers manage workloads (sometimes devs don’t know how to say no), and measuring productivity.

It could be that you are producing code at a reasonable rate, but it’s only considered slow because you’re not meeting an arbitrary deadline.

support

Productivity like this can be difficult for management to measure objectively. They don’t always understand how much work goes into the coding process, so they assume you should be working faster.

A few questions you can ask to assess the situation to see if it’s you (or if it’s them) include:

  • Am I truly inexperienced or do I feel competent in my tasks?
  • How much time am I spending doing things that weren’t requested or required?
  • Do I understand when a fix is finished?
  • Is my code noticeably lower quality than other developers around me?
  • Does management have an objective measure for productivity? If so, what metrics are they going by?
  • Can they give me specific examples of slow coding or idleness or is it just a general perception?
  • Have they taken into account time spent fixing other’s mistakes?

It may be that the problem is on you, and that you’re simply lacking experience or are being slowed down by your own processes. BUT, it could be that there are other factors at play that are slowing you down without you realizing it.

If so, take some time to talk with management or team members about your concerns and ask for feedback on how you can improve your processes to speed things up.

[ Content upgrade with ID = 343 not found ]

Final Thoughts

At the end of the day, a coding-heavy project will probably take you quite a bit of time and there’s not much you can do about that. It’s better to take the time you need to work through the process fully, catching bugs as you go, in order to produce something of quality the first time around.

But if you are under a tight deadline or you’re feeling pressure to speed up your work, remember that practice makes perfect and that automation is your best friend.

You should also take some time to make sure that the setbacks aren’t coming from things outside of your control, like management or team members that are costing you time fixing their errors. Take some time to gauge your situation to determine if it’s really you, or if it’s them.

Why You Should Be Charging More for Your Dev Skills

Are you selling yourself short when it comes to your rates?

Many new developers – or, let’s be honest, long-time developers – have trouble setting rates for themselves that can actually meet their needs. And if you’re reading this, you’re most likely one of them.

Most developers (and designers, and freelancers in general) tend to bill conservatively at first. Often they feel like they lack experience or skills to charge more, or they’re just not sure what the “going rate” is for their job description.

But playing it safe can keep you from having the career of your dreams.

That’s why it’s important to start charging more for your services, and here are 3 of the biggest reasons why…

[ Content upgrade with ID = 333 not found ]

featured10

Reason 1: You Have In-Demand Skills

One of the biggest reasons freelancers in general tend to undersell is self-doubt. They’re just not sure they have a skill that someone is willing to pay for. But that’s simply not true of developers.

The growth rate of the industry is astronomical. According to the U.S. Bureau of Labor Statistics, employment for developers is projected to increase 20% within the next 10 years, nearly doubling the growth of all other occupations.

This is also why you should be charging more for your services. Over time, demand for web and mobile developers will continue to rise, and the more experience you gain, the more your skills will be worth to the public. But even at the get-go, your skills are still valuable.

So how should this affect your pricing strategy?

Conventional wisdom would tell you to start low and then raise your rates, but the demand of your job means that you can actually start higher and work with more lucrative clients from the start.

Freelancer Jake Jorgovan writes, “When I started pricing myself hourly I started with an hourly rate of $30hr. Over time, I kept raising my rate from $30 to $50, $60 and higher. Yet somewhere around that $60 per hour range I noticed a major shift in my mindset. At $60 per hour, I was beginning to start working with higher quality clients who had decent budgets.”

After a while, Jorgovan was able to switch to more lucrative project-based pricing, which freed him from the “hourly rate debate” all together.

But the lesson here is that people will hire you because they absolutely can’t do what you do. No matter how you set your prices, remember that you have something valuable to offer, even if you’re brand new to the gig.

If you want high paying clients, then set your prices accordingly.

Reason 2: Market Value is Negotiable

If you’re not sure what a “high paying client” will actually pay, consider the fact that people will pay almost anything for something they consider valuable.

Think about it: What is the value of a cup of coffee?

If you go to a gas station, it’s probably 99 cents. But if you pour that same coffee into a Starbucks cup, you can charge $3. That’s the market value of a brand.

process02

Your market value is the same. You’re not underselling because you’re a new developer or because you don’t have skills or qualifications, you’re underselling because you’re not marketing yourself as someone with in-demand skills.

Part of marketing yourself well is setting prices that reflect the value your skills bring to your clients. Some of that will be determined by general market value, but that doesn’t mean you always have to charge what everyone else is charging; market value is just a starting point.

Your best bet for setting rates is to start by assessing the average value a developer has in the marketplace today. Consider things like:

  • Average salary for someone with your job description
  • Average skillset for someone in your position
  • Average demand for someone in your position (hiring rates, etc.)

Try to gain as clear a picture as possible about what the market looks like, and then compare where you stand.

Do you have more skills than necessary? Less skills overall, but more experience in certain skills? Do you specialize? Do you have a niche client focus? Are you faster than most?

Make a list of the things that you do well and that set you apart from the average developer. Those unique qualities become your brand, and you can (and should) set your rates according to what your brand can offer clients.

You don’t have to have all the skills or experience in the world; you just have to have something special to offer.

Reasons 3: Your Cost of Living

Another important and often overlooked factor when it comes to price setting is the cost of doing business and the cost of living. Many developers start by charging what the market says they’re worth, but fail to increase their rates enough to make a livable income.

When you’re thinking about setting your prices, ask yourself: How much money do I need to make to live the life I want?

how-much-to-charge-for-an-app

If you want a luxurious, jet-set lifestyle but only charge $25 an hour for your services, you might wind up disappointed. If you want to simply pay your bills and live comfortably, but you live in a city or state with a higher cost of living, you might need to charge more simply to stay afloat.

Even if the “market rate” says you should charge $50 an hour, that doesn’t mean you can actually live off of $50 an hour. You should also keep in mind that charging by the hour limits you to a certain amount of hours per year that you can actually work.

You may consider either raising your hourly rate or, like Jorgovan, abandoning it in favor of project-based rates.

As we said before, the market value is the starting point – a minimum price. Once you have your basic rate, increase the price based on the unique value your skills bring to your clients (your brand), as well as any additional costs of doing business (new equipment, training, conferences, subscriptions, etc.) and the cost of living (rent, food, travel, etc.).

Your pricing should be able to meet your needs. And if you’re worried about whether or not your clients will pay your new rates, consider going after different clients. Anyone who understands your true value will be willing to pay whatever you charge.

[ Content upgrade with ID = 333 not found ]

Final Thoughts

At the end of the day, there’s no set formula for how to set your pricing. But this can actually work in your favor. Instead of setting rates based on what every other developer does, you can set rates based on the value your skills actually provide to your clients.

Remember that even at the most basic level, being a developer means that you’re in-demand, so don’t be shy about charging more for your services. Keep in mind that market value is just a starting point, and if you want to go after higher paying clients, then brand yourself for higher paying clients.

And don’t forget to calculate costs based on how much you want to work and how much it will cost you to do business (and live). After all, you didn’t become a web developer to starve, so don’t set prices that will leave you out in the cold.

Should You Launch Your Own Mobile App? Here’s What to Know

If you stick around the web development business long enough, there will probably come a day when someone asks you to build a mobile app for their company or project.

Or maybe you’ve been toying with the idea of launching the next best moneymaking mobile app all on your own.

Either way, there’s a significant difference between developing a website and launching a mobile app.

The good news is that as a web developer, most of your skills will be somewhat transferable. For example, if you already know Java, you won’t have far to go to build an Android app. But there’s still a significant learning curve involved.

Here’s what you need to know if you’re looking to make the leap from web to mobile.

[ Content upgrade with ID = 323 not found ]

mobile-app-development-myths

The Difference Between Web and Mobile Apps

One of the biggest and most noticeable differences between web and mobile app development is the level of flexibility.

Web development gives you a variety of programming languages, devices, and tools to work with, while mobile apps are more limited.

Generally speaking, mobile apps are designed for individual devices and platforms. The languages you need to know for an iPhone 7 (Swift or Object-C) will be different than the ones you need for a Samsung Galaxy S7 (Java).

You also have to think about user experience in a different way. Mobile apps are more object-oriented while websites tend to be more action-oriented.

Mobile apps also need a level of functionality that will keep users engaged for longer periods. The average user will spend around 15-30 seconds browsing a website compared to the 2+ hours they will spend using mobile apps daily.

A few other factors that set mobile app development apart include:

  • Rankings/Ratings – Mobile apps are primarily ranked by their cumulative ratings instead of their searchability
  • Crashes – Mobile app crashes are more critical than a 404 error as oftentimes the required solution is to upgrade the whole app
  • Integration with other apps – Mobile apps will also need to include features of other apps, like how Uber uses GPS to locate riders or Evernote uses the camera feature to import notes
  • App size – Mobile apps have a larger focus on size of the application, memory footprint, and load/startup times compared to traditional websites
  • Browser compatibility – Mobile apps require more development time and testing due to device compatibility and OS versions
  • Multiple versions – Mobile apps generally run multiple versions depending on when the user downloads the app, compared to a website that typically runs one “live” version

While these things may feel overwhelming for a web developer, there are plenty of good reasons why you may want to switch to mobile app development.

Why You Should Learn Mobile Apps

Mobile development can be intimidating, but you may still want to invest the time in it. Here’s why…

1. More earning potential

Mobile app developers typically make more money than web developers, partially due to demand. Web developers tend to lose business to DIY solutions like Wix and Squarespace, but so far there’s no widely-accepted DIY solution for building a great mobile app.

This means that mobile developers can also charge more for their services without being questioned. Payscale.com lists the average salary for a mobile application developer as $71,072 per year versus $53,036 for a web developer.

And if you launch your own app or co-develop one, you can make residual profits from things like in-app purchases – money which is hard for web developers to replicate.

2. Transferable skills

As we mentioned earlier, many of your web development skills will transfer over to the mobile world, making it easier to get started. This is especially good news for newer developers who are learning HTML5, as its predicted to overtake native apps in the future.

3. More flexibility and creative power

Non-game app downloads will exceed $182 billion in 2020, accounting for a quarter of all app store downloads. The best part for developers is that there are a variety of ways that people can use mobile apps to improve their lives, meaning the sky’s the limit in terms of innovation. Chances are if you have a creative idea for an app, you can probably find a market for it, which puts more control into your hands.

If these reasons entice you, then you should consider switching to mobile app development.

How to Transition Into Mobile App Development

The easiest way to get started is to choose a mobile platform based on a programming language with which you’re already familiar. If you’re already keen on Java, consider starting with Android apps, for example.

Currently, there are three roads you can take depending on your language of choice:

  • Native iOS development with Objective-C or Swift
  • Native Android development with Java
  • Cross-platform HTML5 mobile development with PhoneGap

spin_mobileappnumbers_071014-011

Once you’ve chosen a platform, you will also want to consider the type of app you want to make. Ask:

  • Will it be a non-game or gaming app?
  • How many potential app users are there?
  • What app will have the greatest reach?
  • What app will generate the most revenue?

After you’ve settled on a specific app type, you will want to consider strategy before you start building. Research some of the apps already on the market that may be competing with yours to see whether or not you have a unique enough offering.

You should also consider whether your app should be free or paid (the most successful apps tend to be free with in-app purchases).

After that, it comes down to the technical details of programming and designing the right user interface. If you need help at this stage, check out CodeConquest’s list of resources for learning how to build mobile apps.

[ Content upgrade with ID = 323 not found ]

Final Thoughts

Mobile is the wave of the future, and there are a lot of great reasons to make the leap to mobile development. For one, it’s incredibly profitable.

Whether or not you decide to develop mobile apps for others or you launch your own, mobile apps are in much higher demand than traditional websites. Even if you want to stick with web development, consider adding mobile to your toolbelt for added marketability.

If you’re curious about getting started with mobile app development, start brainstorming some app ideas and doing some research into which apps are the most marketable. Then it’s as simple as choosing a mobile platform and brushing up on the right language.