Iterative Development
2016-10-18 21:54
This is a series of posts for my CS3216 project, you can find the original post here.
Easy to over-enginner things, try and make things abstract/generic.
The process I’ve adopted for final project is to start with the most hacky way to do things — pretend this code is read-only. Besides, the module is so frantic that you barely have time to refine your code…
We are writing a chat app, and our choice of backend framework is Socket.io. It works by attaching event handlers to events, for example:
This means that when the client (browser) sends an add
message to the backend, the data
associated with the event will be logged.
An example client call is:
For certain events, such as adding a message, we needed to have a roomId
. It is easy to add in this check:
io.on('connect', socket => {
socket.on('add', data => {
if (!data.roomId) { console.error('No Room Id'); }
else { /* something else */ }
});
});
However, this gets unwieldy fast, because there are multiple events that will require a roomId
, such as adding a reaction, sending typing and stop typing indicators, reporting a user, etc.
As I started to implement more events, I found myself copy-pasting code, specifically the checks for data.roomId
.
Copy-pasting is a smell that we have reusable code — DRY.
So I began to think of ways to extract this logic into a common, reusable piece of code.
1 way is to extract this into a common function:
But this doesn’t really save much code, it’s still 1 line of code, and now I have to handle an exception.
I eventually settled on a more functional way.
function ensureRoomId(socket, fn) {
return function(data) {
if (!data.roomId) {
socket.emit('error_room_id', 'No room id specified');
} else {
fn(data);
}
}
}
socket.on('add', ensureRoomId(socket, data => {
// data is guaranteed to have roomId!
}));
Now every event handler that requires a roomId
can wrap itself with ensureRoomId
, and as a result, we get a single place to define a error_room_id
error! This helps a lot of consistency of error code and messages.
A little ugliness there is that we have to pass in socket
into ensureRoomId
because it needs to be able to emit an event to that socket
but I find that pretty bearable for now (and don’t have a good way to solve it).