Skip to content

The Amazing Adventures of a Sexy Software Engineer Posts

What does a senior developer do?

This is a post I have been meaning to publish for months, but I am always hesitant to do so for multiple reasons.

Firstly, because giving advice to others about how they should do their job is not the most humble thing in the world, and secondly because I have learnt most of what I am going to discuss in this post from my own mistakes.

So let me start with an apology to all those developers that had to deal with me doing the actual opposite of what I am going to suggest now. You know who you are. Sorry, guys,

What is the difference between a senior and a junior software engineer?

Let’s begin by setting some common ground. What defines a developer as senior? This is my premise:

  • A senior developer has confidence.
  • A senior developer sees the big picture.

I have been lucky to work in three different countries, with three extremely different work cultures and ethics. But there is a trend I have seen everywhere, a significant misconception of what defines a developer as senior.

Obviously what makes a developer senior is not the number of years in the craft. There is a difference between having five years of experience, and having the same year of experience five times. And it hurts deeply when I see hiring managers that refuse to see it that way.

What makes a developer senior is not the amount of encyclopaedic knowledge a developer might have about a specific language, API or framework either.

The difference between a senior and a junior developer is confidence . A senior developer makes faster and better decisions. But not only because they have more experience, but because a senior developer is capable of seeing the big picture.

Now, it can be argued, with reason, that confidence can be a liability more than an asset. And I tend to agree with that as well.

So allow me to clarify: confidence is not refusing to be open to other people’s opinions, it is not thinking that you already have all the answers, it is not thinking that you are the smartest person in the room.

A confident developer will be open to fresh ideas, when not actively pursuing them, that challenge his current knowledge, and confident developers will always approach a technical discussion trying to find better solutions than their own to solve the problem at hand.

Confidence is also what makes senior developers want to share their knowledge and experience with others.

How to behave as a good senior developer

A senior develop must be humble and respectful, honest and transparent, and willing to challenge others and himself.

Humble and respectful

A senior developer would assume that his knowledge of certain areas of his daily practice is outdated. And senior developers can be sure that there will always be another developer in the team that knows more than them about one or more of those areas.

And you know what? That is great. Remember, this software thingy is not a pissing contest, this is about building great products, with code of the highest possible quality. A senior developer, a team/technical lead in particular, should be able to recognise when others know more, and encourage them to use that knowledge for the greater good (the final product).

Honest and transparent

We all learn by making mistakes. A senior developer has, most likely, reached that point in her/his career due to all the mistakes he/she has made in the past.

Also, due to the aforementioned confidence, a senior developer won’t be scared of making more mistakes, because the senior developer knows that what matters is not writing perfect code, but recovering from the inevitable mistakes fast and with elegance.

By being honest and transparent, but alway thinking out loud in the open, by discussing his approach with the rest of the team, by showing her/his thought process in the most possible honest and open way, the senior developer will help others understand that what matters is having an actual thought process, and that what matters is taking time to consider the trade-offs before starting to write code like crazy.

I believe there is nothing more valuable for a junior developer that seeing someone, with way more experience, struggle with the same issues that he/she struggles with.

A senior developer always attacks problems with an analytic approach, and a senior developer always has in mind those things that junior developers are usually not aware of yet: business requirements, trade-offs, and the big picture. And makes the importance of those constraints crystal clear.

Because a senior developer always sees the big picture. The senior developer always has a long term plan. The senior developer is relentlessly moving towards the goal posts, no matter what it takes.

Constructing that big picture, that master plan, and setting the placement of the goal posts openly, in front of everyone, rationalising and explaining every single decision is the best that the senior developer can do to mentor others.

Because mentoring is not lecturing, mentoring is not only suggesting using an obscure class in the system frameworks, mentoring is showing, with your own actions, day after day, that a master plan, and a thought process to fulfil it, are necessary.

Willing to challenge others and himself

A senior developer cares deeply about what he does, and cares deeply about the end result of his practice. That means a senior developer cares about excellence.

A senior developer has to be a living and breathing example of how excellence does not happen by accident. Because excellence requires work, dedication, commitment, and the will and drive to actually achieve it.

A senior developer will always challenge himself. A senior developer is never satisfied with the current state of the code, and is always willing to improve it in some way. And he is open, even vocal, about it.

A senior developer will also challenge junior developers by asking them challenging questions. There is nothing worse than telling a junior developer, straight away, that something he implemented is not good enough, or plain wrong.

However, there is nothing better than reading carefully a junior developer’s code and ask the kind of questions that will make that developer understand that the code can still be improved.

A senior developer will not provide direct solutions, but gently steer the junior developer towards those spots in the implementation that do not align with the big picture, the masterplan. Because, remember, the senior developer always has the masterplan in mind.

A senior developer will always end a code review with some open ended question or suggestion to the junior developer. A simple “do you think the functionality of this particular part of the system would be easy to extend?” makes wonders. A “do you think there is a way to make this code simpler”, accompanied by a “by the way, have you heard about the builder pattern?” will provide a great learning opportunity to another developer.

And a senior developer will carefully consider when to let others make mistakes. Because mistakes and the lessons learnt from them, are what made the senior developer, well, senior.

Note:
Edited on May 6th to (try to) remove some gender specific pronouns, as pointed out by @fbartho. My apologies if anyone felt this article was gender-specifc. I am not a native English speaker, and the best I can do as a senior developer is try to recover from my mistakes the best I can. If you still feel this post is gender-specific, please let me know.

3 Comments

Polymorphism and protocol extensions

Allow me to start using a big word: cyclomatic complexity

Cyclo-what? Illustrate that with an example!

Let me illustrate a typical example of cyclomatic complexity. Imagine you have some entities similar to these:

Now, imagine we need to render a table view containing Images, Movies, and TextMessages. Notice how each one of those entities provides a description of itself (the data that will need to be rendered) of a completely different type. In plain English, the table cells will need to display a UIImage if the object to render is of type Image, a NSURL if the object to render is of type Movie, and a String if the object to render is of type TextMessage.

So, the obvious implementation, the one that first comes to my mind, the one I have seen in a thousand different projects in the good old Objective-C days (yes, that was sarcasm), would be declaring a method typing the parameter as id, and then cast and check the type of whatever is passed. Translated to Swift, it would look like this:

Well, that was bad in the good old Objective-C days (sarcasm again), but now, in the bright Swift present, code like that is just unacceptable.

What wait, why is that bad?

Here is where the cyclo-thingy kicks in.

That method is very apparently very simple, but in reality is very complex. Or, to be more accurate, it has the potential to become very complex, very fast.

First, as soon as we start to create different logical branches, we are starting to add different behaviours to somethign that, in fact, is just one single behaviour (in this case, rendering data in a cell). Since we are not dealing with a single behaviour anymore, it is very likely that the behavious in each one of those logical branches will start diverging more and more as time goes by.

But that is not the only reason. As soon as we start creating different logical branches, and each branch starts behaving differenly, the code starts to become more difficult to understand, which makes it more difficult to maintain.

Also, when the code is more difficult to understand, specially because it does multiple, very different things, it is easier to make mistakes. Never understimate the importance of this. This, in my experience, is the first source of bugs in every single codebase I have ever touched.

It took me years to figure it out, but once I got it, I decided to make this my only non-negotiable rule when it comes to writing code:

The Single Resposibility Principle applies to every single task in the daily practice of a software engineer, from organizing code in files, to structs, classes, methods, functions, or any other construct.

Again, let me be clear about this: to me this rule is non-negotiable. Sowftare engineering is all about trade-offs except when it comes to the Single Responsibility Principle.

One file should contain only one abstraction (a struct, a class, an enumeration, a protocol, you name it), one method should only do one thing (either render a movie, or render an image, but never, ever, render a movie or an image), one class should do just one thing, one module should deal with only one high-level concern, and so on.

Now that we got that out of the way, let’s look again at the implementation of the Cell class, because there is another violation of the SOLID principles: the Cell class is not open for extension and closed for modification. If we want to render another type (say, Audio), and since Cell is already rendering three different tyes it wouldn’t be that surprising if we had to add yet another one, we would need to edit the source code of the Cell class. And we’d need to edit it to add yet more logical branches, more complexity.

In other words, we would need to edit to make even more brittle. Not good.

So, where do protocol extensions fit into all of this?

Well, protocol extensions make composing behaviours very easy.

Now, it could be argued that the solution I am going to discuss is not the only possible solution. And that would be true. And we have already discussed an alternative solution to a problem very similar to this, by relying on plain-old polymorphism. So, one thing we could do here would be having a bunch of Cells, all of them implementing a protocol, or all of them subclasses of a base Cell class. However, I believe there is a neater way to implement this.

So, let’s start again with the same entities:

Now, let’s declare a protocol, and declare the render method in it:

The next step would be declaring a Cell class:

Notice how this class is actually empty, does not provide any behaviour at the moment. Nowm let’s start composing behaviours in extensions and protocol extensions. The first extension would make the Cell class implement the Populable protocol, and provide a “default behaviour” for it:

To be honest, having to provide a “default behaviour” is the only part of this solution I don’t like. As you can see, I typed the parameter as Cell, assuming a cell won’t have to render itself, and that way, I am providing a defaul tbehaviour that I do not expect to be necessary. And, again, that makes me feel uncomfortable.

Anyway, now I can start providing the rendering behaviour that I expect from the Cell, in separate extensions, one for each type of data I want to render:

Notice how Swift’s type inferrence makes the final code clean of any extra type information: it just works:

Now, here is the actual beauty of this solution. If I want to render a new type, all I have to do is add an extension to the Populable protocol with the logc necessary to deal with that specific type:

And, as added bonus, Xcode, with the help of the Swift compiler, will provide me extra documentation, in the form of code hints, about what types can be rendered by an instance of Cell:

codeHint-supported-types

Recap!

In object-oriented programming, polymorphism (from the Greek meaning “having multiple forms”) is the characteristic of being able to assign a different meaning or usage to something in different contexts – specifically, to allow an entity such as a variable, a function, or an object to have more than one form.

By relying in strict typing, the single responsibility principle, favouring composition over inheritance, and using protocol extensions in our advantage, we can implement very robust solutions to complex problems, with code compliant with the Single Responsibility Principle, and therefore simple to read, understand, and maintain. And, as an added benefit, easy to test.

7 Comments

Modularity in layman’s terms

Imagine that every Sunday you have the opportunity to design your week schedule.

Now, imagine that you are only allowed to design your schedule by combining pre-built blocks, and that you are given blocks like those in set A.

Screen Shot 2016-04-19 at 12.08.21 PM

And now imagine you can choose from blocks like those in set B

Screen Shot 2016-04-19 at 12.08.29 PM

Which set of blocks will allow you to build a more flexible schedule? Would the schedule built with blocks from set A be more or less difficult to adapt to change that the schedule built with blocks from set B?

That’s modularity. And that’s why the single responsibility principle matters. And that’s why methods should not be long. And that’s why classes should not be long. And that’s why view controllers that control views, do networking, and contain logic to deal with navigation are bad.

Leave a Comment

It’s the open-closed principle!. Duh!

So, this has been my “facepalm moment” of the week. Not the only one I had this week, but the most remarkable one.

I was trying to explain what the Open Closed Principle is all about to a colleague. You know, “modules should be open for extension, but clsoed for modification”. You know, the good stuff.

As usual, I was trying to find a good example to illustrate the point of the OCP, and as usual, I was having a hard time finding it. Side note: finding good examples to illustrate abstract concepts is hard; if the example is too simple, everyone misses the point, if the example is too convoluted, everyone falls asleep.

And suddenly, the duh-facepalm-eyerolling moment! How can I be so dumb, the perfect example of the OCP is sitting right there, looking at us!

Extensions!

So, here comes the example (not too simple but yet not too convoluted) to illustrate my point.

Imagine a model object:

Now imagine we have a mechanism for transporting model objects across the wire, based on JSON:

Well, we want to be able to send Contacts using this JSONDataSender, so we should make Contact implement the JSON protocol, right? True, but devil is in the details, and in this case, the simplest solution would require modyfing the source code of the Contact struct to add the new behaviour:

Which would be a blatant violation of the Open Closed Principle (the object had to me modified in order to add behaviour to it). Tsk, tsk, tsk…

What’s the problem with that approach? Well, we might want to serialize to a protocol buffer, instead of JSON. Or write Contacts to a plist file, or to a SQLite database, or whatever. So every time we wanted to add that extra behaviour, we would need to edit the Contact source. Again, tsk, tsk, tsk.

However, if we don’t modify the original Contact, but add an extension:

We would have extended the object without actually modifying it. Again, the object would be open for extension and closed for modification. And adding subsequent behaviours would be a matter of adding more extensions. So, to me, and from now on, this counts as the perfect example to illustrate the Open Closed Principle (in Swift).

Leave a Comment

Binding custom view properties with RxSwift

Lately, I have been dipping my toes into the world of reactive programming. To be honest, I should probably say that I’m up to my neck into it: ReactiveCocoa, MVVM, “everything is a stream”, and all that.

In my spare time I’m looking also into RxSwift. Even though this blog is mostly about Swift, I spend a significant amount of time writing code in other languages (mostly Java, Scala and C#), so it makes sense to learn what seems to be a more cross-platform approach than the one ReactiveCocoa follows. Platform agnosticism FTW!

But, back to the point of this post. Remember the Ring we discussed in the previous post? If you don’t, well, it’s basically a UIView subclass, that exposes a few public properties to make it configurable. Today I am going to focus on just one of them: progress.

The Ring class is part of the UI of a little pet project of mine, where I want to display some data I fetch from an async service. After fetching that data, I want to update a progress ring (my Ring class) and a label.

 

reactive_ring

So, in the good old days, before my reactive enlightenment I would probably do something like this: (for context, this is the view controller that manages the ring and the label)

For the sake of completing the example, the signature of the method in the data service would be like:

So, not too bad, I guess. An async service, a completion closure as a parameter, and done.

But, if there is a use case for reactive programming, that would be dealing with async stuff. So, let’s go Rx!

The method in the data service signature could look like this:

And now, in my view controller, I could do something like:

Not too bad! But it could be better. This code is still a little bit imperative. It is not a big deal, but I think it would look better, be more readable, and in a way easier to maintain, if I could bind both the ring and the label to the result emitted by the data service observable.

Binding to a UILabel is easy, RxCocoa provides extensions for that, but binding to a custom property in a custom view is obviously not provided out of the box.

But fear not, because it is very easy to do. As easy as the following:

So now, back to my view controller, I can bind the Observable directly to the ui controls, transforming the values emitted by the data service, in just one go:

And done!

Leave a Comment

Building a custom ring

A pet project of mine requires replicating one of the progress indicators in the Health app. I want to be able to configure the ring’s thickness, colour, and percentage of completion.

Before launching Xcode and start writing code right away, I wrote down what I knew about the problem I wanted to solve:

  • CAShapeLayer seems to be a good fit for this.
  • Animatable properties are, well, animatable. And for free. All you need to do is set their new value, and core animation will take care of animating the transition for you.
  • It is easy to build an oval UIBezierPath.
  • It is easy to apply transformations to bezier paths
  • It should be possible to configure the view both programatically and in Interface Builder.

With that in mind, I decided to build a subclass of UIView, insert a CAShapeLayer into it, and bind the “progress” property of my view to the layer’s strokeEnd property. Also, I decided to took this as an opportunity to explore @IBDesignable and @IBInspectable, which is something I’d never done before.

And this is the end result:

animation-small

The source code is available on GitHub, but let’s take a look at some of the highlights.

Display a custom view in Interface Builder

This one was easier than I expected. I can not claim to be an expert in Interface Builder, so I expected a lot of friction here, but annotating the class as IBInspectable was enough to make Interface Builder aware of it:

Making the view configurable through interface Builder (as well as programatically) was also quite easy, just by annotating properties as IBInspectable and providing a default value for them:

Building the actual ring

There might be a better way to do this -I’m looking at you, UIBezierPath(arcCenter, radius, startAngle, endAngle,clockwise)- but I decided to rely on the fact that UIBezierPath’s strokeEnd is animatable (which means that everytime I cahnge its value, CoreAnimation will animate the changes for me), so I built the path as an oval, and set the strokeEnd to the value of the progress property (which is normalized between 0 and 1).

Of course, that makes the path start at the X axis, so the path’s layer needs to be rotated -PI/2.

After that, it is just a matter of setting the proper frame, and path in the layoutSubviews method. Here is the relevant code:

The full source is available on GitHub, and can be pulled in as a dependency through Carthage.

1 Comment

Swift Class Clusters

There was an interesting discussion at work today that led to class clusters.

First, I was surprised by the fact that, apparently, class clusters are something only old farts like me are aware of. But the discussion got me wondering: would it be possible to implement a class cluster in Swift?

Well, apparently it is. Let’s say we want to consume this cluster within the module it is declared in. So, by relying on inner types, we coudl do somenthing like this:

So, now we could do something like this:

Now, the question is: would I ever do this in production code? I am not sure. Are there better ways to simulate a class cluster? I assume there would be, so if you know about them, please shout out in the comments!

Anyway, for those interested, there is a sample project on github

Leave a Comment

Devil is in the details II: immutable collections

Inmmutability is good. Just yesterday, we were discussing how good it is. But just in case, here is another example.

Let’s assume we are building the software to manage a company’s payroll. We have only these requirements:

  • The Human Resources Department should be able to hire and fire people.
  • The Human Resources Department needs to validate that a Person has a valid id before hiring her (there are very strict immigration regulations in here).
  • The Human Resources Department should be able to produce an up-to-date list of employees at any moment in time.

The simplest thing that could possibly work

With those requirements in mind, this the simplest thing we can build. A Person would look like this:

And the Human Resources Department would look like this:

Notice how we do some fancy validation when hiring a new person, and throw an error if anything goes wrong. Also notice how the employees arrary is public, because HR need to produce it upon request.

The devil is in the details

We can hire someone:

We can try to hire someone without a valid Id, and HR would throw an error:

But, we can also bypass the ID validation by modifying the employees array directly:

Boom!

Public collections should be immutable

This is, obviously, a very convoluted example. But the thing is that when we do not enforce immutability, bad things may happen, either by distraction, by means of unexpected side effects, or just by means of malicious or misbehaving code.

One way, and it is not the only possible way, to enforce immutability in the precious example might be this:

Notice how we made the mutable collection private, and we provide a readonly property (employees) that returns an immutable collection, built upon request. But, remember, what matters here is not how we create that immutable collection, but the fact that the public API of the HR class provides only immutable data.

5 Comments

Devil is in the details: final vars and methods

Immutability is good. I have discussed this issue, briefly, in this blog in the past, and it won’t be the last time we discuss it.

Today, we are going to look at how not enforcing immutability can have undesired and unexpected side effects.

Let’s consider this class:

Now, let’s assume that Human Resources calculates monthly payslips like this:

So, this could happen:

Boom!

One solution would be making the Developer a struct or a final class. But for the sake of the argument, let’s say that making that class final is not a possibility, because we actually need to subclass it. Which is not a rare use case, by the way. Not everything can always be final, even if it probably should.

In this case, one solution might be declaring those properties as final:

The point of this post is that the defaults (default access modifiers, default read/write access) are not always the best. And that we need to be aware of what might happen when we rely on the defaults.

And, most importantly, unexpected see effects are avoidable. And we should avoid them.

1 Comment

Generic datasources and cells. Introducing FountainKit.

A couple of months back, I published a couple of posts that seemed to rise some interest (for this blog’s standards), about unit testing collection and table view cells, and leveraging generics to implement collection view datasources.

Huge, monolithic view controllers are not good for any codebase

A view controller, like any other class, should have only one responsibility. However, often times, view controllers do too much: layout views, deal with user interaction, load data from the network, and prepare data to be presented by table views and collection views.

Let’s take a closer look at that last responsibility: preparing data to be presented by a table or collection view. That usually happens by means of implementing either UITableViewDataSource of UICollectionViewDataSource. Just to simplify the discussion, let’s say that often times, view controllers behave as datasources.

The problem with that is that we are adding a responsibility to an object that is already doing too much. In fact, it is not just responsibility, but multiple ones: the view controller would need to be aware of the structure of the data that we want it to present, it will have to be aware of how we want to present it (since we usually populate public cell outlets in the implementation of the cellForItemAtIndexPath method), and since it is already aware of the data structure, it is very likely that it will also handle user interaction with the table/collection, and therefore it will also be responsible for navigating to another view controller, or performing network request.

That’s too much. Those are too many reason why the code in that view controller might need to be changed, those are too many things to get right in just one object. And code that does too much is error prone and difficult to maintain.

So, now that we have established that we don’t want view controllers doing too much, and in particular that we don’t want view controllers acting as data sources, what can we do to avoid that scenario?

Divide et impera I: Data

As usual, the solution is breaking the problem down into smaller pieces. Highly cohesive pieces.

We need to fulfil three responsibilities: manage a data collection, prepare cells according to the way we want to represent the data in that collection, and render that information on screen. So, we have three distinct responsibilities, but somehow related by the kind of data we want to present on screen.

First order of business would be encapsulating the management of the data collection. We want to do it in a way that allows us to manage strictly-typed data, without knowing exactly the type of our data. Well, that’s what generics are for, don’t you think?

But we also want to be able to manage different data structures in an abstract way. Well, that’s what an interface (protocol) is for, don’t you think? 😏

So, this would be our starting point.

Now, we can have an implementation of that protocol that manages a single section data structure (AKA flat array)

Divide et impera II: Cells

Cells are the only entities that should be involved in actually rendering information on screen. If we think of data in one end of the pipeline, cells would be in the other end.

Cells are pure UI. Actually, me might see them as tiny little view controllers, with one responsibility: populate outlets (i.e. labels and image views) with data, doing that in the simplest possible way (that means, directly assigning values, without being concerned by any other business logic)

Again, have in mind that we are sending a data object (model object) through and imaginary pipeline that starts in our data structure. And, have also in mind that, as usual, we want to be able to provide different cells, all of them sharing the same behaviour (being able to accept a data object of a generic type)

In order to achieve that, we will make our cells implement this protocol:

Divide et impera III: Binding data and cells

Well, that’s what data sources are for, aren’t they?

A datasource is nothing more that the entity that is in a position to know which cell needs to be presented on screen, grab the cell and the data object that needs to be presented, and force them to talk to each other.

If we think about this whole thing as a pipeline with the data model in one end and the cells in the other, the datasource would be the actual pipeline, it would be the glue that binds data and presentation together.

Let’s declare a class that implements UITableViewDataSource. We are only going to implement the required methods of UITableViewDataSource, so we will not make this class final. If, eventually, in an specific project, we need to implement more methods of the data source protocol, we can subclass.

Also, we want to bind a data collection of type T with a cell that implements a var of type T (remember, we want to be able to provide the model object to the cell).

So, this would be the declaration of our datasource class:

Notice the generic constraints: we want this class to be qualified by two generic types, but we want the first of those types to implement DataManager, the protocol that abstracts our data collection, we want the second type to implement DataSettable, the protocol that abstracts our cells, we want the second type to be a subclass of UITableViewCell, and here is the tricky pat, we want the associated type declared in the DataManager protocol to be equal to the associated type declared in the DataSettable protocol.

Now, that’s all good, but we need one extra step in order to make all the pieces fit together. In the data source initialiser, we declare two parameters, the data manager, and the cell type. Notice how we do not retain the cell type, we only pass that parameter to make sure that the generic constraints are enforced.

Divide et impera IV: The benefits of dividing, aka conquer.

It could be argued that all of this is nothing more that a gymnastics exercise on generics. But there are some significant benefits to it:

  • Better testability. This approach makes the cells, the view controllers and the datasources easier to test.
  • Better separation of concerns. This one goes hand to hand with the previous point. When there is good separation of concerns, things are easier to test.
  • Higher cohesion, and lower coupling. We broke the problem into smaller, highly cohesive pieces. Each piece has one and only one responsibility.

Introducing FountainKit

I have been using this approach in my projects for quite some time now. It works well for me, and I thought that it might work well for others.

So I have packed some of my code into a framework, and published it to Github, including a sample project that shows how to implement an actual table view:

https://github.com/ctarda/FountainKit

There are plenty of improvements to make, but there is nothing like receiving feedback (Agile mindset FTW!) to build software that solves actual problems.

2 Comments