The more I work with deep inheritance hierarchies, the more I wonder if inheritance is actually a good idea. If you’re looking to avoid the trouble overusing inheritance can get you into, this article has some handy tips: Inheritance is evil. Stop using it.
We all know we have personal biases, but have you ever thought about your software design biases? I certainly didn’t until I read this article about Software Design Bias by Sandro Mancuso. If you’re having trouble with the design of a piece of software, it’s worth taking a look at Sandro’s handy list of biases and thinking about whether they way you prefer to design software is actually the best one for the particular thing you’re trying to build.
Their dream was to travel the world in a sailboat, yours might be to become a freelancer, to start your own business, to switch to game development, or something else entirely. If you try something and it turns out to make you miserable, it’s okay to stop and do something you actually like. I’ve read a lot of sad stories about people who made themselves miserable, put themselves under so much stress it wrecked their health, or financially ruined themselves pursuing a dream that just wasn’t working, and I really don’t want that for any of my readers.
On a lighter note, if you do New Year’s Resolutions, consider quitting something you don’t actually like instead of trying to squeeze more and more activities into your life. If that feels selfish to you, think of it as setting a good example for others :)
Learning Fluency, by Sara Simon is a really interesting article and you should definitely read it. It’s kind of hard to summarize, what I got from it was that there are a lot of parallels between learning natural languages and learning to program, one of which is that rote memorization is both really useful and really underrated. Variables and for loops are really boring for experienced programmers (which I’m suspicious is why ), but just like it’s really hard to tell someone how to get to the grocery store in a new language until you’ve memorized enough words, it’s really hard to build a program before you’ve memorized enough programming constructs.
Another good point Sara makes is that not everyone learns the same way. Some people are happy to jump into a project and learn as they go, and other people need more structure to get started. That doesn’t make anyone wrong, but it does mean we need resources for more than just one kind of learner.
Learning Fluency is a bit of a long read but it won’t take your whole lunch break either.
You might have guessed from my extremely wordy blogposts that I like writing as well as programming :) Aside from having a personal interest in writing, I think there are some really useful parallels between writing and programming.
Let’s talk about one of them: separating writing and editing. This is a pretty common piece of writing advice, I’ve seen it all over the internet.
More specifically, what separating writing and editing means is that when you start a piece of writing, you don’t edit, you just get your ideas out onto the page. Only after you have a complete first draft, whether that’s a blog post or a novel, do you edit it. Editing can be as simple as fixing typos or as in-depth as moving whole chapters around.
Why is editing while you write such a bad idea? We’ve all written essays for school and edited while we wrote and we survived, right? Well, we did, but we also put in way more effort than we had to. It is totally possible to edit while you write and turn out a perfectly good school assignment, or even a professional article or book, it’s just way more work than it has to be to do it that way. It takes for-freaking-ever too and we’ve all got other things to do :)
Separating writing and editing makes you way faster. Yes it works better if you have a little space between the writing (drafting/outlining) and editing steps, but you’ll spend less time altogether on a piece of writing if you put a day or two between those steps.
But why is that? Writing isn’t that hard, and editing isn’t that hard (to be fair, I’m saying that as someone who has always had an easy time with writing), so what’s the problem?
Part of it is that people just suck at multitasking. Fiddling with your words is a very different task from getting them down in the first place, but I think is the real issue is that editing and writing at the same time is mixing two steps that need to be done one after the other.
It doesn’t actually make sense to worry about how you’re saying it before you’re done sorting out what you want to say in the first place. That’s just going to make a mess.
Okay great, how does this relate to programming?
Programming is in many ways a very similar process to writing. You need to know what you want to do before you can figure out how exactly to do it. Programming is certainly more rigid, with writing you can still make yourself understood with a misspelled grammatical trainwreck, but it’s not so very different either. You can start a piece of writing and know just what you want to say and then discover it just sucks and you have to scrap it and start over.
What you want to do with a program can be more tightly constrained by what’s feasible given the existing system/libraries available/limitations of the language you’re using, but in some ways that makes it easier because there’s no debate over whether your program works or not, you can just run it and find out.
When you’re writing code it’s very simple to separate writing from editing: write pseudocode first. Figure out what you want to accomplish (yes that’s a big enough problem for many books on its own, but that’s another blog post) first, then break it down into simple steps, then start implementing it after you know what you want to do. It may turn out that there’s a technical reason your original plan won’t work, but you can still iterate on that and make a new plan before trying to implement that one.
If you find yourself stuck on a problem, you might be trying to do too many things at once. Try separating what you want to accomplish from how you want to do it.
Why tomcat? Because it’s open source, I’ve used it before, and honestly it was the first thing that came to mind :) Oh, and for anyone reading this who hasn’t spent a ton of time writing Java webapps, a servlet container is a kind of webserver that provides a nice little home for your servlets, which are little Java programs that take http requests and give back http responses.
Tomcat does indeed have a main method, it starts on line 457 in Bootstrap.java. There’s even a helpful comment that says “Main method and entry point when starting Tomcat via the provided scripts.”
Which is all well and good, but that makes for a pretty boring blog post :) So let’s talk about how I hunted down that main method. I could have just searched for “static void main” in the Tomcat github repo, but a) I just tried that and it wasn’t actually super helpful, and b) what I really wanted to know was what happens when you start Tomcat.
It’s been a while since I used Tomcat so I looked at the docs first. In the readme on the github project there’s a link to RUNNING.txt, which looks promising.
So I skim through that (there’s a bunch of stuff about installing tomcat and setting up environment variables that I don’t care about right now, I just want to know what the startup script is called) and eventually find the section about starting tomcat. In there it says that the startup script for linux users like me is $CATALINA_HOME/bin/startup.sh (there’s a .bat file for windows users too if you’re curious).
Okay great what’s in startup.sh? (also thankyou github for having a file finder!) It turns out there’s not a ton in there and I don’t understand most of it, but at the end of that file is “exec“$PRGDIR“/“$EXECUTABLE“ start “$@“”, which I think I can assume executes a thing :) Also a little earlier in the file is EXECUTABLE=catalina.sh.
Given that, it looks like startup.sh does some pre-setup setup and then catalina.sh actually starts the server (if there’s a 3rd level of startup scripts I’m going to be really sad). There’s a lot more going on in catalina.sh that I skimmed through, but I eventually started seeing a lot of evalexec“\”$_RUNJAVA\”“ [many more vars] org.apache.catalina.startup.Bootstrap “$@“ start. That $_RUNJAVA thing sounds like it might, you know, run Java :) That probably means that the startup class is org.apache.catalina.startup.Bootstrap, let’s go see if there’s anything interesting in there. And what do you know there’s a main method. It took some scrolling to get there but we made it eventually!
You may or may not care about how Tomcat (or any other given application) works, but what I hope is interesting is that everything an application does is understandable. Nothing the computer does is magic, it’s all knowable.
Because you definitely all care about my opinions on phones :)
The very short version is I really like this phone and recommend it for anyone who likes the Google Pixel but is put off by the price. Now for the details!
The hardware is really nice, it feels solid and well put-together. Fair warning, it is a phablet and the formfactor is very large – without a case the phone is 154.2 x 74.1 x 7.25 mm. As a bit of an aside, if you’re a woman and have any wild ideas about putting your phone in your pocket I highly recommend eShakti jeans with the deep pockets option.
I also highly recommend a case, the phone feels kind of naked without one, plus it’s expensive and smashing it would suck a lot. The Otterbox case is what I went with because I want my phone to be as well-protected as possible. That case also gives the phone a more satisfying heft in your hand, it’s almost too light without a case.
Performance wise it’s great, which is maybe not great for getting my tab habit under control. Yes, I have a problem even on mobile :) It opens demanding apps (like Tap Tap Fish, which I have a terrible obsession with) faster than my last phone, the Nexus 5x and it performs the same with one app or a dozen open. Often the only way I figure out how many apps I left open is when I hit the recent apps button looking for one of them and ending up scrolling, and scrolling, and scrolling, to find it.
The screen is really nice too, it’s huge (you know, like you would expect from a phablet) and sharp and bright. Reading on it is a much nicer experience than it was on the Nexus 5x if only because it’s bigger, but I think the colours are brighter too.
Battery life on this phone is fantastic, I’m guessing the bigger form factor allows a much bigger battery. Even running that huge bright screen for hours (say if you’re extremely bored in an airport) won’t kill the battery. And even if it does, dash charging really does charge your phone back up incredibly quickly.
I can’t condone actually taking calls on speakerphone, but if you want to use the speaker for more civilized pursuits like listening to podcasts while you get ready in the morning, it’s pretty decent. I mean, it’s a smartphone speaker, you can only expect so much, but I can hear it from across the room without turning it up as loud as it will go, so that’s handy.
All I can tell you about the camera is that it exists, I don’t take a lot of pictures so I don’t have anything useful to say about it.
Updates have come steadily since getting the phone, and even if OnePlus stops supporting the phone it’s popular enough that there’s a good chance of finding a custom ROM to put on it.
Now for the cons:
Getting the phone was seriously painful. I ordered mine about 10 minutes after a coworker and got it days after he did. The OnePlus site just doesn’t like some credit cards for no particular reason, you may want to make sure your PayPal is setup to charge directly to your credit card so you still have some protection and use that to pay for the phone.
If you order anything from OnePlus, you need to resign yourself to the fact that they will ship your order when they damn well feel like it and not a second before. If you have a workable phone then the wait isn’t so bad, but if your primary phone died weeks ago and you’re using a ~5 year old phone it’s really painful to wait and wait and wait for your phone to finally show up. In other words, don’t order from OnePlus if you’re in a hurry to get your phone, especially if they’re running a launch event.
This is probably the meanest thing I will ever say on this blog, so brace yourself :) OnePlus support is LESS USEFUL THAN DHL SUPPORT. LESS USEFUL. To be worse than DHL at delivering packages, you would have to open the package and defile it before throwing it in the garbage, and yet somehow DHL support was able to tell me what was happening with my package and where to put my tracking number when OnePlus support had absolutely no idea what was going on. If you’re going to sell a phone comparable to the Pixel for around $250 less you’re going to have to cut corners somewhere, but seriously, OnePlus support is amazingly terrible. As in, so terrible I feel perfectly safe sassing them like this because it’s not going to make them noticeably less useful.
All that said, if you can stand to wait and wait and wait for it to show up, the phone really is excellent.
Let’s talk about classes! Classes in Java are super weird (okay they’re weird in any language), and I really struggled with them when I was learning Java, so don’t feel bad if classes/objects are hard for you.
When you write simple code where everything is in main and runs immediately, it’s way easier. With classes you can’t just write it and call it, you have to create an instance first. What’s even going on there?
A class in Java is just a blueprint, it doesn’t do anything until you create an object using the blueprint (there are exceptions but let’s go with that for now). That’s a big part of the weirdness, you write all this code and it just kinda sits there until you write even more code, and here’s the kicker: that code has to be somewhere else.
In a small project your probably have a Main class somewhere that has a main() method, that’s where you need to call your other class from. Why? Because Java says so, that’s why :) Or more precisely, when you run a Java project you have to tell the JVM where to start. Something, somewhere, has to have a main method no matter how you run your project. Even if you create an archive that you drop into a servlet container like Tomcat or Jetty, that servlet container has a main method somewhere that gets called when you start it up. It may be very stealthily called by a script that calls a script that starts a service, but there’s definitely a main method in there somewhere. No matter how complicated an application seems, it’s really just a much larger version of the tiny little projects you do in school. Programs get larger and larger but the basic principles always stay the same.
Back at basic principles, you create actual objects you can interact with using the class/blueprint. In Java you do that with the new keyword. new YourClassName() creates an object using the blueprint, you can assign that to a variable like any other value and then do what you like with it. Once you create an object it’s separate from any other object you create even if you use the same blueprint (class) again. Again, there are exceptions, but I’m trying to keep this simple.
It’s like building two houses from the same set of plans, they’re separate houses even if they start out the same. You can put completely different furniture in each of them, paint them different colours, make a bedroom into a home office, but whatever you do to one house doesn’t affect the other one. And you can put objects inside other objects, like a house object could contain a fridge object or a couch object or a CNC router object if you have an especially interesting garage.
You could also have an array of house objects – pretend you’re keeping track of one of those subdivisions where all the houses are the same :) Those houses could have a method like closeWindows (pretend it’s an automated house), so you could loop through your array of suspiciously similar houses and close all the windows if the weather report said it was likely to rain. But you would need to call the closeWindows method on every single house, if you close the windows of one house it doesn’t affect the others.
This gets much more complicated when you start thinking about multithreading, static methods, and static fields, but those are another blog post. For now all I want to get at is that Java needs you to spell out exactly where to start and that programs all work pretty much the same way no matter how complicated they are. Frameworks like Spring or Struts and containers like Tomcat and Jetty will hide details from you, but no matter how many other programs or libraries you use, the computer always needs to know where to start.
Today’s code smell is feature envy. Feature envy is when one class uses the methods of another class to excess. It’s called feature envy because classes that use methods from another class excessively look envious of that class’s features.
The problem with that, as usual, is the way your logic gets spread around between multiple classes. If you have one method that’s using another class so much that it’s hardly even separate from it, you’ll probably have to change things in both places when you need to fix a bug or add a new feature, but the compiler can’t tell you that you need to do that so you risk creating a shiny new bug by missing a spot.
Feature envy probably makes more sense with an example. Let’s say you have an address class and a customer class, and when you call customer.getMailingLabel() your customer class calls address.getStreetNumber(), address.getStreetName(), address.getCity() and so on to build a complete address string for printing a mailing label. Let’s imagine that policy changed and you’re now able to ship to rural mailboxes, so you need to add route and box numbers to your address and to use those instead of street number and street name if they’re present. If your code has feature envy, you have to change both the address object and the getMailingLabel method to support rural mailboxes. If you moved the getMailingLabel method into the address class, then you would only have to change one class when you wanted to change how you build mailing labels.
As with just about all code smells, feature envy isn’t always a sign there’s a problem. Sometimes you want to separate your data from operations on it, especially if you’re using a strategy or visitor design pattern. If, for example, you want addresses formatted differently for different reports, the formatting is probably more the job of the reporting code than the address object. In that case it would make more sense for a visitor to contain the formatting code so the address object doesn’t have to care about all the different reports.
Today’s code smell is switch statements. Long switch statements or complicated if statements often (but not always!) mean that something has gone wrong with your design. Objected oriented languages give you a lot of tools to avoid big complicated switches, if you aren’t using one of those there needs to be a good reason for it. If you’re not using an object oriented language, on the other hand, I’m honestly not sure if switch statements are a sign of a potential issue. If any of my readers could weigh in on that, that would be really helpful.
But why are switch statements a problem? Because you’re spreading around logic that should probably be in one place, and if you add a value to one switch statement you’re likely to need to hunt down all the other ones and change them too.
If, for example, you have a switch statement that does different calculations based on the type of the object passed in, that logic for how to do the calculation probably belongs inside the object passed in to the switch. If you change that object, you’ll have to hunt down every place it’s used and make sure nothing else needs to be changed, which is obviously asking for trouble :) If you give each object a doCalculation method and replace the switch statement with a simple call to doCalculation, then all of the logic for that object stays inside the object. With all your logic in one place, you don’t have to search for every thing you need to change and risk missing a spot, and your design just makes more sense when logic for one thing isn’t smeared across multiple objects.
Polymorphism isn’t the only way to fix a switchy smell, if your method switches on a parameter that’s passed in, you may want to change it to separate named methods to more directly do the thing. If you have a setProperty(String name, String value) method, you could replace it with named methods like setType, setModel, setYear, etc. You might end up with a lot of little methods, but it’s still clearer than one setProperty method with a giant switch. If you end up with a truly excessive number of methods, that’s another code smell that points to your object doing too much.
Just because switch statements are sometimes a problem doesn’t mean they always are. Sometimes what you’re doing is so simple that an interface and a set of objects that implement it (or changes to your existing interface and objects) makes your code more complicated rather than less. And sometimes there just isn’t a better way to do it: factory methods and abstract factories rely on switches or a series of ifs to figure out which implementation to return.