Close

SOLID By Example

So I’ve recently been discussing SOLID principles with some engineers who are unfamiliar with them, and have realized that a good set of practical examples would be really useful for programmers who haven’t had professional experience with SOLID come to understand it. I won’t claim to be an expert at SOLID, so this is mostly an exercise for myself and a resource geared towards those who are less familiar with the SOLID principles and how to put them into practice when architecting applications in a modern object-oriented language.

To this end, I will take a very simple WPF application which uses a REST client to pull data from an online REST API. Then I will apply SOLID principles in a refactor to make its structure more testable, extensible, reusable, and maintainable. The example repository can be found on Github and is written in C#, but the basic principles apply to all object-oriented languages.

In the coming weeks I will create 5 more blog posts, each centering around one of the SOLID principles:

  • Single Responsibility Principle
  • Open Closed Principle
  • Liskov Substitution Principle
  • Interface Segregation Principle
  • Dependency Inversion Principle

I hope that newer developers will be able to learn from this, and that those of you who are already familiar with SOLID principles will find it to be a useful example!

Starting the Hello Language Project

So I recently realized that while I often read blogs and social media comments about a really wide variety of languages, I actually only tend to use a handful on actual projects I work on. I’m most comfortable with C# and Type/Javascript, so those are the tools I use to solve programming problems I encounter. I have about 5 years of experience in both, and between the two, I can write code for basically every platform thanks to projects like mono and the ubiquity of Javascript. They’re really versatile languages.

That’s all fine and well, but I want to break out of my comfort zone a bit and actually write code in all of these languages I frequently hear about. At first I thought that coming up with a project for every language I was interested in would be prohibitive, and if I’ve never used them before, how would I even know what a good project for a language might be?

So to break out of my analysis paralysis, I decided to start the HelloLanguageproject as an exercise for myself: to write Hello World, Fibonacci, FizzBuzz, and possibly a few other very simple applications in every language that interests me. So far I’ve done 17 languages, including Rust, Scala, LISP, and Fortran, and plan to do about a dozen others including D, Go, and Swift.

It’s actually been a really interesting exercise just switching between multiple different syntaxes for solving problems in a single evening. If you have any suggestions for cool languages I should take a look at, a favorite feature of a language I should explore, or small exercises I could do in multiple languages to highlight their differences, please let me know in the comments!

Why the Open Code of Conduct Isn’t for Me

Github recently announced that they are adopting a new code of conduct for their open source projects. Specifically, it is the Open Code of Conduct, published by the TODO Group.

This inspired some debate on Reddit when it was posted, and I groaned inwardly when I saw it: ugh, more political correctness.

Yet this was clearly a well-intentioned and well thought out effort on the part of Github, so I asked myself: why does it bother me so much? Before I elaborate, let me cite a few snippets from the Open Code of Conduct:

Although this list cannot be exhaustive, we explicitly honor diversity in age, gender, […] and technical ability*. We will not tolerate discrimination based on any of the protected characteristics above[…]

Harassment and other exclusionary behavior aren’t acceptable. This includes, but is not limited to:

  • Discriminatory jokes and language*.

If someone has been harmed or offended*, it is our responsibility to listen carefully and respectfully, and do our best to right the wrong.

(* = emphasis mine)

While I agree with most of the Open Code of Conduct (as well as its underlying intent) – these passages struck me as being problematic. They, like all forms of political correctness, center around people being offended, sometimes about things like technical ability which can and should be spoken about frankly in any open source project.

Here is the problem with using offensiveness as a standard in a code of conduct:

  • It judges the speaker by the listener’s opinions.
  • Opinions are subjective and cannot be known by the speaker until after they speak.

Judging and punishing the behavior of those who speak based on the sensibilities of those who listen is a standard which is inherently unfair to the speaker. This precipitates an environment where the exchange of ideas between people who differ is impossible if either of them thinks that the other may find the topic offensive. This carries with it the danger of stifling communication and learning between people who would otherwise benefit from a conversation that might just ruffle some feathers.

Being offended is a choice

I am a Christian. When people speak ill of religion in general, and of Christianity in particular, I have a choice about whether to be offended, even when confronted with very vitriolic assaults on my core beliefs.

I choose not to.

The reasons for this are simple: I respect the cognitive abilities that other educated human beings put to use in forming their opinions about the world, and am eager to hear about the conclusions that they have drawn. I value the opportunity to exchange ideals with others and have had my life and my thoughts enriched by such exchanges in the past.

I have a lot of respect for both Richard Dawkins and Christopher Hitchens, even though our opinions on religion differ drastically. I would consider it both rude and oppressive to try to create a world in which people who disagree with me are afraid or unable to speak their minds.

Just because one person was offended does not mean that another person attacked them

Many of the things people choose to be offended about are the same things that other people honestly and unironically believe. The mere act of voicing one’s own opinion on a topic such as religion or politics can be interpreted by a sensitive listener as an offensive attack on their beliefs. The listener’s perception does not equal the speaker’s intent. Conflating the two mindsets like this can lead to one person’s opinions being punished due to other people’s indignation.

Opinions are subjective

Because opinions are subjective, it is very easy for people who wish to abuse these sorts of systems to choose to be offended by things they don’t like in order to demand punishment for those who disagree with them. In extreme examples, they may even take offense at someone else’s treatment of them, while simultaneously treating others in the same way.

Systems that punish offensiveness open themselves up to exploitation by such people.

Not all speech can be judged the in the same way

While it is true that sometimes people thoughtfully voice their honest opinions, people also tell jokes, speak flippantly, say things without explaining their reasoning, and employ language techniques such as idioms, metaphors, irony, sarcasm, and hyperbole. Given the inherent complexity and ambiguity of human speech, combined with the fact that any two people’s grasp of a language must necessarily differ, there is no guarantee that the offended listener has correctly inferred the speaker’s intent.

Intent is a better metric of behavior

It is not uncommon in criminal cases of harassment or slander for prosecutors to be expected to show not only that the defendant said or did the things in question, but that they did so with the intent or knowledge that it would hurt the victim. We can easily use the same system in a code of conduct, to weed out the same sort of negative behavior without resorting to judging one person’s words by other people’s thoughts.

In Summary

This post may sound pedantic, but I think that the difference between intent to offend and being offended is an important distinction. When an educated computer scientist makes a flippant claim that “Haskell is useless,” I think that their own (in this case jokingly positive) intent when saying it should determine whether punitive action is taken against them, rather than the fact that a Haskell fan felt offended by it.

I hope that Github will reconsider their decision to use subjective metrics like this as a part of their code of conduct. I hope that they will let the people who may say things I disagree with continue to speak their minds honestly. And when they do, I hope Github judges their actions based on their own mindset and not mine.

This is the internet, and I’m here to learn about other people’s thoughts, not be protected from them.

 

EDIT:

I acknowledge that Github chose this Code of Conduct in an effort to improve their community. I also think that it will actually do that, and applaud their effort. I do not think that the political correctness spies have scored some great victory today, nor that the sky is falling.

But I see an edge-case that could result in abuse and misunderstanding. I also believe that a Code of Conduct, like other code developers write, can benefit from constructive criticism. I think that code must be made durable to stand up over time, and I think the best code results from collaboration and many small improvements from people with different perspectives. This is mine.

Consider it a meta-pull request. 🙂

The annoying MySQL Web Platform Installer Bug

So I recently ran into the following error while installing the second WordPress site on a fresh VM:

The specified password for user account 'root' is not valid, or failed to connect to the database server.

MySQLError

After following a few guides and going through the steps to reset the root password on my MySQL installation and continuing to get the same error, I finally stumbled across the solution in this blog post.

Since this issue sucked up quite a bit of my time, I figured I’d mirror it on my blog as well. I didn’t need to edit the registry key, simply installing the MySQL .NET Connector was enough to fix my issue:

MySQLFix

Not quite sure why this is needed, but it worked for me. Hope this helps someone else out there!

Javascript is the Right Flavor of Bad

People are often very hard on Javascript. They make fun of it in “Wat” videos, its community produces a 23 new frameworks every nanosecond, and it’s a common target of criticism among people looking for a dynamically typed language to ridicule.

Yet Javascript is one of my favorite languages to work in, and I think I’ve figured out why: it’s just the right flavor of bad.

Some traditionally bad languages out there (*cough* PHP) are bad deep in their core, buried under layers of pull request makeup and major release plastic surgeries.

It’s a subtle pain. Like stealing socks from your dryer, or unscrewing the lid on your soda bottles while you’re out of the house so that the carbon dioxide escapes and the flavor changes and becomes too sweet and you’re forced to acknowledge that you had planned to drink a bottle entirely filled with corn syrup all along.

It’s a slow burn, a thousand papercuts you can’t put your finger on, and eventually you resign yourself to the pain. You get diabetes from all the soda you’re no longer ashamed to admit to drinking and you’re permanently forced to walk only in smelly circles because you only have one sock left and you’re too afraid to wash it.

But Javascript is different. When it’s bad, it’s a sharp pain, with no attempt to disguise it. It’s like having your cat jump up on your desk and then vomit on it.

It’s clearly, openly, unapologetically rude, and yet the cat just stares innocently, unblinking back at you. As though it just happened to notice your eye contact and is now waiting for you to comment on the weather. Why shouldn’t it throw up on your desk? This looked like a good spot. Why shouldn’t the result of adding two arrays be empty string? It seemed like a good return value.

So you yell at the cat in English, vainly expecting it to understand you in Cat (hint: it does, that’s why it ran away.) Then you clean it up, and the problem is gone. No slow burn. Just something so stupid you can’t believe it happened, with a clear and direct, easily Google-able solution which you quickly apply and then move on with your life.

Javascript is cat puke.

Most of the time it works exactly as you expect, doing cat things and turning strings which contain numbers into 64-bit floats so you can math with them, converting the same numbers into 32-bit integers so you can bitwise operate with them, then converting them back into 64-bit floats so you only have to remember 20 powers of two while working with Javascript numbers.

The good and bad parts of the language are very clear and obvious, which is why it’s possible to learn how to work around them within the lifetime of a mortal. Then you just get the Good Bits of Javascript, and you’re able to enjoy working with it.

"x

Javascript, the Good Parts

And then one day you discover Typescript and you elope together and live happily ever after.

Learn to Build Bridges in Only a Day!

So I’ve been reading the Joel on Software blog pretty religiously lately, and I’ve decided that part of his success was that most of his blog posts were so short he could probably do them in one sitting. I’ve been trying to blog more, and I think that short, hastily edited blog posts facilitate getting into the habit of writing more, which is a skill I want to keep sharp. So expect more, lower quality content from me from now on!

Everyone should learn to code!!!one1

Something that seems to keep coming up on the programming subreddit and Hacker News lately is the popular movement to teach programming as a skill to everyone. This is generally the point where the career programmers crawl up into their tree fort and pull up the ladder prior to sneering at the optimistic newbies who think that they can learn to code in a day! What fools! How gloriously they shall fail! Come, brothers, and let us await the schadenfreude and “I can haz teh code?” questions on Stack Overflow! Guffaw!

The biggest aspect of this movement that rubs programmers the wrong way, I think, is the fact that these campaigns seem to target themselves specifically at people who understand very little about computers in general, and conveys misinformation to the people who are already least informed. Sometimes they do this because the media networks themselves know nothing about programming, and other times this is done to take advantage of people by offering them $99 one-month online courses in how to get rich in the computer industry.

The following video was probably the most egregious example of the ignorant media. They don’t even manage to make it through the first minute of what purports to be objective coverage of the Year of Code movement without describing the code as “baffling” and “gobbledygook.” It gets better when one of the directors of the program admits to not knowing how to code immediately before making broad assertions about the role of programming in our modern world.

So the career programmers are probably understandably miffed at these sorts of descriptions of their profession, combined with the suggestion that anyone can do it without much effort and that “you can build a website in an hour!”

When your livelihood is based on using over a decade of ongoing education and experience to charge $100/hour to build websites, a task which normally takes you between days and weeks, ignorant assertions like that are both insulting and have the potential to deter prospective customers.

“If it’s that easy, I’ll just do it myself!” the potential customer scoffs, before teaching himself PHP and building a website that exposes his database to SQL injection attacks, lacks even the most basic of usability features, is unusable on mobile devices, and errors frequently (but he’ll never know because he doesn’t even have logging to tell him of the terrible experience his prospective customers are having!)

 

Counterpoint

But on the other hand, some programmers welcome the idea of our profession gaining more mainstream appeal. We work hard and care about what we do for a living, so seeing our friends’ eyes glaze over whenever we talk about what we’re passionate about can be frustrating.

Furthermore, with most employers complaining about having difficulty finding good programmers on the market, we could do with having more talented people entering the field from all walks of life.

If nothing else, it would be nice to get rid of the gut-wrenchingly naïve way that programming is portrayed in popular television.

“It’s a military grade encryption!” – writers of Arrow. Hate to break it to you guys, but that code doesn’t even compile.

 

That scene is essentially the programmer equivalent of a plumber announcing to a room full of contractors that he’s going to “Use a wrench to check the valves to see if there’s some sort of aquatic discharge” before rushing off, clearly in a hurry to get to work before his buzzwords get cold.

Conclusion

Ultimately I think it comes down to educating people and setting realistic expectations. I really believe that people can learn useful programming skills in a limited amount of time. I also believe that coding is an excellent way of helping people to hone their analytical, logical, and problem-solving skills.

Let me put it this way: I’m not a carpenter. I’ll never be a carpenter, and if a genie suddenly appeared and offered to give me the skills of a carpenter, my reaction would be an unenthusiastic “Meh, why not?” or perhaps “Genies aren’t real. Where’s the projector and fog machine?”

Yet I own a tool set, and an electric drill. I used these just the other day to assemble a liquor cabinet for myself and to mount some surround sound speakers on the wall of my living room. But I would not attempt to build a bridge.

People already understand the difference between someone who owns a drill, and someone who makes a living doing carpentry. They also understand the difference between someone who does carpentry as a contractor for a living, and someone who has spent 60 hours per week for most of their life working with wood because it is both their passion and their profession.

Chinese artist Zheng Chunhui’s world record breaking 40-foot long wooden sculpture.

This, I think, is the key distinction that is often lacking when teaching people about programming. Hobbyist, professional, and artisan are all different levels of skill in the same discipline. But many of the most common tasks people need computers to perform are also ones that can be achieved by a hobbyist programmer. Tweaking the CSS on a wordpress blog, automating some simple paperwork task the office, or simply being able to identify which tasks might be automated so that one can make better suggestions to the creators of software.

Thanks, XKCD!

Thanks, XKCD!

Conveying the appropriate expectations to those learning to code and teaching useful basics to a wide audience of people is a Good Thing. But misleading people into thinking that difficult tasks are easy will hurt more than help. People should expect to learn to create simple applications to perform tasks that are both simple and useful.

They should also be told that given what they already know, expanding their knowledge of programming to include new things they’re interested in accomplishing with their skillset is much easier once they know some basics.

They should not be led to believe that they can quickly slap together a fully-featured, multithreaded, asynchronous, peer-to-peer file sharing system on a Saturday afternoon. Nor should they be led to believe that their programmer friend’s work as a computer security expert for an online financing company is actually pretty basic, but she’s just really really bad at explaining it.

Conveying realistic expectations of what these sorts of introduction to programming courses can and can’t achieve is imperative to their success, and so far we’re failing pretty miserably at that task.

3 Ways to Avoid Being Burned by State

If I were to ask you to tell me what the return value of x were after the following lines of C# code executed – could you?

var y = 5;
var x = example.Foo(y);

You’d probably ask me to see the implementation of Foo before feeling comfortable guessing the behavior of the method. So let’s take a look at Foo’s contents:

public int Foo(int num){
  return num + this.z;
}

Now could you tell me the value of x? Nope, not until runtime, because you don’t know the state of example.z. Depending on state, particularly mutable state, is one of the most common ways to build complexity into your code. The result of a single line of code that depends on state could potentially be affected by every line of code that has executed before it which modifies our program’s state. This increases our program’s complexity exponentially.

So let’s take a look at 3 simple techniques for avoiding state in our code.

Write Functions and Methods as Pure Functions.

Let us contrast the previous implementation of Foo with a new one which will allow us to achieve the same thing:

public int Foo(int num1, int num2){
  return num1 + num2;
}

And then invoke it like so:

var y = 5;
var z = 10;
var x = example.Foo(y, z);

Now you can tell me exactly what x will be after Foo executes, at compile time. This is because we no longer depend on the internal state of the object example. We have created a pure function, which is one of the most powerful ways of avoiding being burned by state. Pure functions have two properties:

  1. The function always returns the same result when invoked with the same arguments.
  2. The function has no side effects. None of our program’s internal state is modified by invoking the function. (until we store its return value.)

Because they are explicit about the state they depend on (the function’s arguments) and because they do not mutate any of the program’s state, they reduce the complexity of our code tremendously.

We can compose an arbitrarily complex series of calls into pure functions, and if we know the state of the inputs to those functions, we can prove what the output will be with 100% accuracy. This is the great power of functional languages, however it is important to note that one can program in a functional way and reap the benefits of pure functions in nearly any modern language.

Sometimes however, we need state. After all, sometimes we want to store data somewhere and retrieve it later. Databases, File I/O, DTOs, and Caching are all great examples of this. We can’t get away from state entirely and still be able to do anything useful.

So let us look at another way we can avoid being burned by state:

Make Stateful Data Structures Immutable

We can relax the first property of a pure function when needed (depending on outside state), while still enforcing the second property (not mutating data). With this in mind, let’s take a look at one possible implementation of our example object’s constructor:

public class Example
{
  public int z;
  public Example(int zValue)
  {
    z = zValue;
  }
  public int Foo(int input)
  {
    return input + this.z;
  }
  // Other object methods here
}

Now let’s use this new implementation of Example to accomplish the same task we did before:

var example = new Example(10);
example.ModifyZ();
var y = 5;
var x = example.Foo(y);

By looking at this code, can you be certain the value of x without running it? It’s true that we could inspect the ModifyZ method to see whether and how it mutates Example.z – but there is a better option. What if we made z immutable? Then we could be certain that z would always have the value assigned during the constructor of Example:

public class Example
{
  public readonly int z;
  public Example(int zValue)
  {
    z = zValue;
  }

Now let’s take another look at the same code snippet above:

var example = new Example(10);
example.ModifyZ();
var y = 5;
var x = example.Foo(y);

This time, because we know that z is immutable, we can be certain without executing this code that x will be 15 after these lines execute. The behavior of the ModifyZ method no longer has the ability to affect the state we depend on because z is immutable.

But what can we do if we can’t make some of our state immutable? A database, cache, or file system are all designed to be modified and accessed from many different locations in code.

Make Dependency on Mutable State Explicit.

In the last section, we looked at what would happen if we relaxed the first property of mutable functions while still enforcing the second. Now let’s look at how we can benefit from relaxing the second property while still enforcing the first. Let us assume that our Example class contains a DTO parameter which is an arbitrary struct. Below is a possible implementation of the Bar method on our Example object:

public void Bar(int input)
{
  this.fileStream.WriteLine(input + this.DTO.z);
}

We write a single line to the file, containing the sum of the function’s input and the z parameter of the Example object’s DTO. Now let’s use this new Bar method:

var example = new Example(10);
example.ModifyDTO();
var y = 5;
example.Bar(y);

Looking at this code, we have no way to be sure what will be written to the file without examining the contents of the ModifyDTO method. But let’s look at another way we might implement the Bar method to achieve the same thing:

public void Bar(int num1, DTO data)
{
  this.fileStream.WriteLine(num1 + data.z);
}

And let us assume that the implementation of our DTO struct was as follows:

public struct DTO
{
  public int z;
}

And the following sample code:

var example = new Example();
DTO data;
data.z = 10;
var y = 5;
example.Bar(y, data);

Now we can be certain what will be written to the file because we can easily follow the DTO struct throughout its entire lifetime within our function. Even though its state is mutable, we can limit the code which might modify its state to code which has a reference to it.

By using functions that have no external dependencies outside of the function arguments, we make our dependencies explicit at the time the function is invoked, which makes debugging much easier. And by ensuring that objects like the above DTO which have mutable state do not give out persistent references to themselves, we can drastically reduce the scope of code capable of modifying them.

A good way of identifying candidates for these sorts of changes are methods that either have a void return value, or accept no arguments. Methods with no return value have no reason to be invoked except for their side effects. Methods with no arguments either do something extremely trivial, or depend internally on state in order to accomplish something useful. Every time you find yourself writing a void function, or a function with no arguments, consider whether it might be better implemented in a less stateful way.

The more we reduce our dependence on state, the more we untangle the complexity in our code. Often times widespread dependence on mutable state introduces a lot of complexity and uncertainty into code which could easily be rewritten to avoid most or all of its state. Avoiding state where possible, and using it in deliberate and careful ways when it is needed, are excellent ways to write much more maintainable code!

Back to top