Sometimes ideas flow, very suddenly, abruptly, and they seem just such perfect fit. Then comes the amazement; why didn’t I think this before?
I’ve done mobile software development on three rather distinct stages of the ecosystem: very early (2000-2001), Single Page Apps, and now Current Age of Cross-platform Apps (2016- ).
Open source components are all the rage, and there’s plenty of schools of thought to follow. Once you settle, you might settle for React Native.
My tool for the trade is React Native, for now. That’s what I’m giving an example about next.
Many developers from the World wide web, who come to RN, transition rather quickly from the syntax shock, on to inspect and learn the real joys and capabilities of the new platform. Tooling issues apart, things start to look very good. The initial pain of creating a component subsides, and you hit that 17 lines-and-no-bugs-look-ma! bar. Keep the compiler in the loop, and things are fine. Emulators hot-reload your creations, and the cycle feels good. React Native itself drips and distills to newer versions, like that Elixir Generator of Clash Royale.
The “dark clouds” equation
Every mobile developer probably at some point of their lives thinks about this kind equation:
B = OS * D * ORIENT
The number of branches to develop (&test) is an equation involving multiplication between three factors:
OS: operating systems (iOS, Android, Windows Mobile)
D: distinct display sizes
ORIENT: screen orientation (landscape/portrait)
Plugging mere (2, 3, 2) gives you 12 branches. Auch!
In web-world, you’d have to plug another major multiplication factor, the number of Web Browsers (Opera, Mozilla, Chrome, IE, Safari, perhaps their mobile equivalents, too!). So, in the mobile development this is rather optimistic figure.
Developing a strategy to tackle platpourri
Insert “platform” and “potpourri”, and you have the platpourri. One has to tackle this somehow, “on an intelligent way and in the proper level”. Chaos containment is evident for a sane developer life.
React Native gives you a freeride!
React Native actually drops the OS completely from the Dark Clouds equation, which is great! That means you’re down to 6 branches. Androids come in a chameleon infinite variety, that might prove to be a bit of headache. Anyway, a strategy will formulate.
Then comes the big question: “But wait! Where’s all those responsive design mechanisms in React Native’s components??”
They seem absent.
Responsive, mobile; device independent pixels.
Responsive, mobile, device independent pixels.
Are you getting it?!
No, wait! Hold on for part 2 – it’s boiling. I might have something up my sleeve.
Wishful thinking is one of those concepts that really struct a chord when I was studying theoretical computer science. The term was introduced on a introductory programming course, and I believe it originated from the MIT “SICP” course authors. “Wishful thinking” basically means that a developer sets aside some problematic details, for a while, in order to effectively work on another part of the same problem. In practical terms, you can create an interface (or a dummy function with input parameters) and pretend that it does the thing it will eventually do. For now, you can just use a static ‘return’ clause and make the call superficially work as intended.
What’s the Code gremlin?
Wouldn’t it be super, if you could go home, and let someone clean up your code base while you were asleep? This is the Code Gremlin I was thinking about: just insert the guy through your laptop’s USB port, and with its magical powers it cleans up any mess, whatsoever, that was left after a busy day of coding.
Less strain on brain; no bad line justifications. Documented functions, yes please. No weird ‘tmpNet’ variable names, will do! Modules written in lengths that are easily absorbed, and make perfect sense to future code reuse needs.
Refactoring aims to change software’s staticstructure – the source code. It’s not often so much about the performance (run-time), but rather how a developer perceives the source code. You might even say, the ‘elegance’ or ‘beauty’ of the code.
Refactoring itself can be a beneficial mental process, during which developer takes a second glance at the form of the solution; it might also reveal bugs.
Stack Overflow. It’s right there! That’s your solution. Click, hooooold, done. Then Paste! Compiles? Good! I’m finished.
Yeah I know. Copy paste coding. We all do it. It’s the little brother of open source. Come on. Don’t stare at me. It works.
I watch daily how two guys, brothers S and L, are doing fascinating play with Legos. Those were my favorite blocks some 35 years ago, too. There’s two methods to building legos:
you buy a boxed set, open the manual, and build that particular thing according to the instructions
you pour hundreds of colorful pieces on the floor and start experimenting
Not going too deep philosophically into the ‘Code and legos’ paradigm, I can say that doing code often has both of those methods at some phase. And it’s important to be able to do both. Sometimes you have (1) the blueprints available, sometimes you don’t. Fundamental building blocks — in code — are the reserved keywords and functions in standard libraries (packages).
“Stretch and rebound”: causes for the need to refactor
Many times there are phases in a software project, during which a developer ‘stretches’: makes an adamant commitment to work until a feature works; however rudimentary, but still it “works”. Psychologically it’s tremendously liberating. You have a gut feeling that you’ve proven something to be feasible.
From the solution you’ll “rebound”: return to your upstream requirements. Often in practical software engineering we do code for “someone in need”: our code will be consumed; for example, in order to make a View in a a mobile software, we construct components: buttons, scrollable areas, lists, etc. When we finish doing the early prototypes of these building blocks, we rebound back to the “top” level (the View) and start tying the knots and making it all work together. Often the component placement means that we must supply some sort of parameters to the components.
This time of rebound is also a kind of turning point where we might ask “Was the component good enough? Should I polish it a little bit?” We’re talking refactoring here.
Case example: doing REST call code
Say, you’re making the network connectivity features, and the first RESTful API call requires some more boilerplate code than you ever thought. The concept is something that you know is viable, so you start stretching the solution: create all variables you might need; crunch the call string (doesn’t care yet how it looks), and fire a first call to see what possibly happens. You get an answer, so lo and behold! You know the server has received your packet of data! That’s great! Encouraged by this you add bit more to the code to really get going. In fact, you need to do some parsing on the return packet. Then you need to wire the error handling code, and… more. You now got some 50 lines of code, which indeed seems to work.
We’re at the rebound point. You can take the “Go-ahead pill“, or the “Refactor pill“. The choice is yours. The implications of these, as in Matrix, are not so evident, as I’ll cover in another article.
This is indeed quite an important approach. During a stretch, it might feel uncertain and being out there in a jungle, without a compass, you as a developer are also putting a lot at stake: there’s a chance that the solutions a) won’t work b) was completely the wrong one to begin with. But nevertheless those stretches are crucial for keeping the velocity (going forward) in a project.
You are trading risk for risk: by taking some risk you alleviate the risk of being faced with an unknown task, of whose complexity you cannot say anything certain. Now that you’ve done the rudimentary code, you know a thing is doable, and you know the basic solution structure.
The tendency to favor even hasty development to stagnation is actually very healthy. The thing that’s often forgone is that if you never clean up the mess, it’s going to be what you’ll stare for a long time – maybe not this month, or even this year, but believe me – there are no code gremlins that tidy up things automatically for you, when you’re asleep.
Once you snap, you can’t.. live without? Update? Stay abreast?
The dream of doing software by snapping together nice libraries (components) is as old as the trade itself.
We’ll be looking at
how does modularity in general change software development process
is the “Lego-land” approach to building software now a reality?
This article is a not a quick “5 steps to…” -type of article. Rather it’s about the philosophy of software development; the nature of solutions, and a bit of historical review for those who have not done coding in the 19xx’s.
Preface: Was software always modular?
No. Modules were kind of “invented”. In the truly old times, programs were a sequence of lines, executed by a computer as a linear sequence (batch processing – Wiki). Along the execution of a program, side effects did things like set values to variables. In the end, the variables were printed out on a printer paper or some kind of console. Typical use case: given parameters of a building project, calculate the cost estimates and print out a schedule for the project.
Then came two things:
a need from the developer’s side to manage large programs
The User immediately brings “interactivity”: you can’t know what parts of your program get executed in which order. User navigates your software, triggers different kind of changes in it, and the user also does things you never knew was possible, or desirable. In the long run it’s quite a challenging job to balance the different user needs with keeping the program technically manageable and its usability high (software being easy to use).
The developer’s needs, on the other hand, have to do with the limits of our brain: seeing thousands of lines of linear but highly “spaghettized” code, characterized by jumps between chunks of the code, buried in IF…THEN cases, becomes a human headache. A computer never has a headache; sure, it can be slower to execute highly branched code, but the computer never “loses it”. We might.
Spaghetti code was difficult to debug, especially once a bug crept into the logic. Bugs are behavior of a software that is clearly against the specification. For example, if you get an “infinite” reading for a velocity of a real-world vehicle, you most liekly have some kind of bug in the software.
Side effects change the state of a program in abrupt manner, and the reality was that especially when handing over work from developer to another, things got really hectic. It probably took at least weeks or months for a newbie to familiarize with the “way of the program does things”. There’s quite scarce set of “by the book” -solutions to problems. Software engineering is inherently humane art, curiously, in that developers tend to easily roll their own solutions, once they get bored with looking for a perfect existing recipe. The more experience, vigilance and skills you have, more likely you are to be able to use well-known libraries and patterns. If you’re just beginning to do code, it’s inevitable that you’ll come up with exotic and rather backwardly solutions at first. And it’s completely ok — a necessary training part of becoming a good developer.
Next up, we’ll talk about batches, visit Object-oriented programming, and ponder on our ability to stand on the shoulders of giants. See you!