A STORY ABOUT A FEATURE GONE BAD
Chad clicked the button and created his pull request. He had worked on his feature really long — it must have been three weeks. Finally, it was time to integrate his changes into the master branch so they could go live with the new version of the app. This was the first huge feature that was his responsibility. His team lead, Janet, gave him the ticket for the task and he set out to write his code. “When it finally goes live,” he thought, “the churn of our users should drastically go down!”.
Primarily he had found many places in the app, where users committed some actions. Up until now, these actions weren’t registered anywhere, so nothing and nobody tracked them. There was no record of what the user did or didn’t do inside the app. Marketing alerted management that too many users did not renew their accounts, or outright canceled. In turn, management asked the developers to do something about it. Together the team decided to record all user actions and put them into a log of all activities for this user. This way they could make calculations which users were not active in the app and reach out to them to prevent them from abandoning the application, or so they hoped. The development of the feature enabled Chad to take a thorough look at the whole application. After all, he had to integrate his code into all kinds of places. And so he did. Today he was finally ready to publish the code and begin the merging. To integrate it into the master branch so that it could get deployed, he had to create a pull request. “Since my code is well written and worked when I tested it, it shouldn’t take too long for this merge to complete.” was his conviction. He assigned the pull request to his team lead and another backend developer that he had talked to during lunch a few days earlier. Chad used the lunch to tell her about his progress on the feature, and she seemed interested. So another set of eyes shouldn’t hurt.
When Sarah, the backend developer on the team, started work the next day, she saw the notification for the pull request in her email inbox. She decided to take a look. After all, Sarah didn’t like it herself when pull requests lingered for too long. So she dove right in. The first thing she noticed was the warning git
gave her: The pull request couldn’t be merged because it had conflicts with master. She decided this should be something minor because it happened rather often and decided to ignore it. Chad would just do a quick rebase, and everything should be fine. No need to worry.
She proceeded to look at the changes: 4100 lines were added, and 2521 were removed. There were many files changed as well because Chad copied his code into all the different places. When she looked into the data, things looked strange because the code in all these different parts of the app didn’t look the same. Sometimes Chad’s code style fit with his surroundings, but most of the time it didn’t. At least his code looked the same everywhere — because he made sure to pay attention when copy-and-pasting his changes, he later said proudly.
Anyway, Sarah didn’t want to take too long for this review. Since Chad’s code looked the same everywhere, she reviewed two files and what she saw made sense to her. Sarah remarked that it was somehow hard to follow what was happening because he didn’t follow her style in the parts that she wrote. Especially the variable names, she didn’t like. But she would give his pull request a thumbs-up if he could change them in her part of the code.
Janet took a look during the evening the next day since she had lots of meetings to attend. The first thing she did, was asking Chad what this pull request was all about. He hadn’t written any description for his pull request. She also remarked that the conflicts with master were due to this feature taking so long. Many parts of the app had already evolved from his weeks' old state. There was a lot of work to update everything. She also wanted him to proceed quickly with this since this feature already took too long. Marketing was eager to get something into their hands since users left the app left and right.
It took Chad another two days to update his code and bring everything in line with the changes from master. Eventually, the conflicts were gone and Sarah and Janet thumbs-upped the pull request to be merged with master. It went live after weeks of development with only a very superficial review. Marketing began to receive logs of who was inactive in the app, and where active users spend most of their time. They also received angry calls from customers that the app is slower to respond than usual and that it sometimes just crashes—in places that used to work before.
It turned out that Chad’s changes were not tested, neither automatically nor manually. The changes also blocked the main thread of the application with a synchronous network call that sometimes took very long (depending on the user’s network) and sometimes just hangs and crashed the app. Since there was no style guide for the developers, the code looked differently everywhere you looked, and no linters enforced any style at all. The copy-and-paste changes that Chad had integrated made for a tedious find-and-replace once they had to fix the bugs. And it was all over the app. Therefore fixing things took another two weeks, and there was no end in sight.
In the end, management canceled the whole feature, because it just didn’t work at all for most of the users. They replaced it with integrating their web analytics engine. A radically simpler approach, but it did work right away.
ONLY TWO RULES
There are only two hard rules when doing code review with your coworkers:
- Keep it professional. Don’t. Get. Personal.
- Don’t take it personal.
Remember that you are talking about letters and symbols in files. Nothing more and nothing less. You are doing this to improve the results, the software.
You are not your code!
INDENTATION AS A COMPLEXITY METRIC
If you want to measure the complexity of your software, there is a lot of software, tools and software-as-a-service offerings available. These options can seem daunting and have a lot of onboarding time (the time it takes you to understand how to use them and get meaningful results).
If none of these things work for you, don’t despair. There is a simple way to get a high-level view on the complexity of your software. And it’s language-agnostic. It doesn’t care whether you write CSS, Ruby, Java or something else.
You see, when developers structure their code, they use indentation as a seperation. Some languages/developers use tabs and other spaces. I personally like to use 2 spaces for one indentation step. Others use 4 spaces (that’s common in JavaScript as far as I know). In the end it doesn’t matter, because every indentation increases the complexity by one.
Like this:
def my_function () {
if (this_is_true) {
do_a_thing()
else if (another_thing_is_true) {
if (one_more_check?) {
// we are really far into the rabbit hole right now
do_a_different_thing()
}
}
}
If you count the indentation for this pseudo-example-code (a heavy mix of Ruby and JavaScript, just to make you not try to read the code but understand the concept), you see that the biggest indentation is already at three. I adhere to the rule to never indent SCSS files more than three times. And that might already be too much. SCSS-lint counts these indentations and reports them as errors. You could use the same metric for any other language.
If you or your developers indent code more than 2 levels, there might be a problem lurking that you should investigate.
This check can probably by done by non-developers as well. You just have to trust your eyes and be able to count to 3. Or 4? 8? You can google “Pyramid of doom” and will get a nice view how this can look in its worst case.
Have fun counting indentation!
Yours, Holger
SHOW YOUR WORK
I wanted to add something to the topic from two days ago: Quality in the eyes of your users.
There is a thing I did not mention. A practice that could help you and your team achieve a higher quality of your products:
- Show your work early and often.
- Improve after receiving feedback.
- Repeat from step 1.
Results get better with feedback. It forces you to consider other points of view from your own. In case the input isn’t valid, you will still explain your point of view to the others. Which in turn helps you understand your personal opinion in a more profound, better way. Your team will establish a feedback culture in which it is normal to seek, accept and build on other peoples opinions. There is no reason to avoid that situation. Receiving and giving regular feedback and exchanging opinions builds courage. In your peers, in yourself. It also deepens the team spirit, because your solutions will come from the whole team. Everyone takes part in finding the optimum and recognizes parts of themselves in different aspects/features of the software. The result is shared ownership. And shared knowledge. Which is always good because you depend less on a singular individuum.
Doing feedback rounds early, also makes it easier to change course, should you find it necessary to do so.
And, there is often this dreaded line:
They client asks when they can see something. What can I tell them?
Having feedback rounds enforces a development culture where people create runnable/viewable results. How often do you have it, that a developer sits at their desk for two weeks or more? When the time comes to show what they have created, the following things might be true:
- they are not done yet
- it doesn’t look like the spec
- it does not work reliably or at all
- it does not integrate well with the rest of the product
Early feedback rounds prevent this from happening. When was the last time you showed your work and asked for feedback?
Yours, Holger
INTERFACES
In computing, an interface is a shared boundary across which two or more separate components of a computer system exchange information. (Source: Wikipedia.org)
You develop a web application that has a frontend for the users and a backend for the business logic and the data persistence. (This is a simplification, bear with me for a second.) Your frontend accesses the data from the backend through an API that the backend provides. This is the first interface. It’s right there in its name Application Programming Interface. But let’s ignore that one for another second. How does your frontend consume the API? Did you wrap the calls to the API in its own class in the frontend?
Or do you send GET
/POST
requests to the URLs of the API directly? How does your frontend expect the data to arrive? Will it take simple JSON
, or do you need instantiated classes or objects at your class boundaries?
Now imagine you want to exchange the source of your data. You don’t need the API anymore, because you will provide a local database that already holds all the data. Or you provide the json in text files.
How hard will it be for you to change the source of the data? To make the frontend consume the new source, be it text files or a local database (e.g., IndexedDB)? Does your design allow for an exchange like this?
If you answer no to this question, then you have a problem. You did not specify an explicit contract between your data source and your consumers.
It would be best if you encapsulated the responsibility to fetch data from somewhere into one module/class/object (call it whatever you like) and reuse that. It could even be a family of objects if you consume many different endpoints. And these objects need explicit contracts.
Calling ProjectsRepository.latest(10)
should return 10 Project
objects. You should not know where they came from. Now your ProjectRepository
might internally call ProjectsEndpoint.latest(10)
or something else. It might do something like File.read("./projects.json").take(10)
(This is supposed to be pseudocode 😉). You shouldn’t need to care. But you should be able to change it easily.
Yours, Holger
QUALITY IN THE EYES OF YOUR USERS
I bet that most people reading this won’t have UAT or QA. So what could you do to still achieve quality in the eyes of your users?
Yours users will spend more time with your software, like it and recommend it more, when they are happy using it. If we’re honest it might even be enough to make them not dislike the software. There is so much crap software out there, that people use to get their job done, that the bar is pretty low.
So let’s imagine for a moment, that you want to exceed that goal and make your users happy. What are ways to achieve that if you cannot do User Acceptance Testing?
Here are a few thoughts:
- Let your developers speak to users when planning and architecting the software. Your developers should try to empathise with your users and understand their problems when using the software. Or better: They should understand the pain that the users try to solve when using your software. After all, they don’t buy it because it’s pretty but because they want to use it to get things done. If your developers understand that pain and can see it through the eyes of the user, they are much more able to create a viable solution to that problem.
- Make your team use the software themselves during a longer period. That way they can experience the problems themselves and will be much more motivated to improve the solution. Of course, this might not be possible for products that are totally unrelated to your field. How should your team use a hospital facility management software, right?
- Let your developers work in support for one day/week. This might not solve fundamental problems your solution could have. But it could bring developers closer to your users—that are already using the software—and help them find ways to improve the situation.
I am curious if you have other ideas that I might have overlooked.
One thing I am sure of: You have to speak with users or become users or get in contact with users. You won’t improve the situation without changing perspective.
Yours, Holger
TWO VIEWS ON QUALITY
During the last months I wrote a lot about quality and how to develop high-quality software. These letters dealt with topics like linting your code, testing and documenting it. I also wrote about the different perspectives and motives that might exist in your team.
But there is one view that I omitted more or less: The external view of your customers. They expect to receive and use your software. They expect it to be without bugs and to fulfill the role they “hired it for”.
It is not easy to integrate this view into your software development and quality process. Two possible options come to mind:
- User Acceptance Tests (UAT)
- Quality assurance in-house
UAT is the next best thing from deploying/selling your software and receiving feedback. UAT means having real users test your software from end-to-end and gathering their feedback. UAT can help you gain trust from your users. The people taking part in a UAT could be a well-defined group of users from a big company that is one of your clients. If these people test your software and find it performing well, you can gain good advocates for your product. UAT could also be a legal or contractual requirement for your software.
Quality assurance done by a team in-house usually helps companies find problems early and thoroughly. There are ISO certifications for that (ISO 9000). Most companies won’t be able to afford that though. QA is a topic worth a separate email.
I bet that most people reading this won’t have UAT or QA. So what could you do to still achieve quality in the eyes of your users?
We’ll talk about that in the next email.
Yours, Holger
FUNDAMENTALS
I am an expert in writing and working with Ruby and Ruby on Rails. But today I was in a fortunate position to realise something: By now, I am language-agnostic. With one of my current clients, I am working with Node.js and Angular. There’s even some PHP in there. My client knew that I haven’t worked with any of these technologies before. Yet they wanted to have me anyway. Even for a price that was above their initial budget.
I am proud of that.
They wanted me because the language I work with, is almost irrelevant by now. The fundamentals are the same everywhere. When I see an Angular service class (I don’t even know for sure if that’s the right term for that…) that’s 300 lines of code long—I know there is something wrong and that is has too much responsibility. When a constructor for another class calls a different class to set itself up, without that class being injected, then something is wrong!
When a pull request is merged, without answering the questions in its description, and without having a real review, then something is wrong!
I can help my clients in so many ways right now, that I am just really proud and happy about that. Forgive me for boasting about that so much.
So let’s turn to you. I couldn’t have told you all the things I am capable of, three weeks ago. I jumped into cold water and just looked how I could contribute to my client’s success. Turns out, there are lots of ways. Don’t you think you could do the same?
If you work in this industry for a while, you can share amazing amounts of expertise and experience with your peers. If you just entered the field and are still learning the fundamentals, you probably already have experience in a (totally unrelated?) field of work. Let us know about that, and how we could translate concepts from there into our field. Even if that’s not obvious right away.
People are amazing. And if you and your team are able to step away from the stressful work that you have to deal with every day, just for a few moments or hours—I bet you have a lot to share with each other. It happened (again) today for me. And tomorrow it might happen for you.
Yours, Holger
TAKING NOTE
Today I want to share a small little idea with you. An idea that can have grave consequences if misregarded:
When you schedule a meeting with your team, also share with the team who is responsible for taking minutes/notes. One person has to be responsible for that.
And they should share it with the team afterwards and ideally post it to the Wiki or wherever you store your team’s knowledge. Make clear well before the meeting starts, who is responsible.
If you fail to do that, nobody will be responsible. People will leave after the meeting concludes and noone will remember everything that has been said. If you’re lucky a few will remember the key points. Good luck having successful projects that way.
Schedule meeting, appoint someone to take notes and make these available for every team member (and potential clients). Everything else is doomed to fail.
Yours, Holger
EVOLVE
Since I strongly believe that you can only achieve high-quality work if you trust your teammates, I am trying something today. I trust you.
I will show you a skeleton in my closet.
A few years ago, I worked on an Open Source Content Management System in Ruby on Rails (a OSCMSiRoR 😂). This system is still used in production to this day. The team and I developed it for clients and kept reusing it. Back then I and the others didn’t know a perfect way to develop a CMS. We had been users of other Ruby CMSs but found them inadequate for our use-case. And that’s when you decide to roll your own. 😶
It was designed as a Rails Engine, so it could easily be included into other Rails Apps (Active Admin and Devise work like that as well). I didn’t know as much about software design and architecture back then, as I do now. Every time I look at the source code, I want to rip it apart and redo it. Apply my knowledge and make things better. Looking from the outside in, it seems easy to have small wins that improve the project. The reality is that the apps that use the CMS in production are too heavily bound to it. You cannot just change code in the engine because you would run into trouble in your client apps. I’ve tried.
This is a lesson in itself: You have to decouple your apps from the engines that they use.
What was the single biggest error we made back then when we designed it? We wanted it to work well with all kind of apps. It was supposed to be flexible to be used with Rails apps. But we did not foresee that we would want to redesign the underlying engine at any point in time.
Side-note regarding quality: Above all else, we had too few tests. Changing things without proper test coverage is bound to go wrong.
What would I recommend doing differently nowadays? The idea to have an underlying CMS that works with any kind of app and provides management capability for any kind of content you could throw at it is still a good idea. First of all I would provide an API with a strong contract. Then you could test against the API and it could evolve and things still would work. As long as you fulfill the contract. The content is only provided via this API. The users of your engine won’t ever have a way to access content directly. Second, I would use a document-based database. It lends itself beautifully for this task and you don’t need a relational database for that. Save your content as JSON. Save your attachments/media-objects in there as well.
This email is getting long so I will make a cut here. My laundry list for things to improve or do differently is longer than what I hinted at above. I am dreaming of creating this CMS at some point. Because I can and because I’d like to make it better than last time. You probably know that feeling. If I ever get around to doing it? I don’t know. 🤔
Anyway, I promised to show you my skeleton, so here it is: [https://github.com/5minpause/Goldencobra]
Dare to show me your skeletons?
Yours, Holger
FRUSTRATION
Over the weekend I had (kind of) a conversation with a good friend. The topic revolved around doing the work on software projects, and how that is sometimes harder to do in a right way. Because of external factors, or because of company policy. In essence, this creates frustration. Probably nothing new there for you.
It may be that I describe things in a too positive way for you, here. Perhaps you read my letters and think to yourself, that things don’t work like that in the real world. Maybe you don’t have enough freedom in your projects to be able to care for quality in a way that would satisfy you? If that’s the case, I would like to learn about that. Tell me about your frustrations and the things that hinder you from doing your work. Don’t be afraid to share. I’ll keep everything confidential.
Still, I will continue with my mission to increase software quality and to tell about that world in which software projects are finished on time and budget, with high-quality code and best practices. I do know from experience that this world exists. And even if we cannot get there every day, do not lose track of the goal. If there are even single days, where you can come close to that, these are good days. And striving for raising software quality in your projects will make them better eventually. Constant dripping wears away the stone…
Yours, Holger
HOW TO TRAIN FOR A MARATHON
If you want to run a marathon, you have to train for it. Very few people can do that without deliberate training. You have to run for many kilometers consistently and do speed and interval training in between. If you let your training slip, it means your performance on race day will be worse.
If you want to deliver high-quality software on release day, you need to measure and work on the quality of your software every day. If you let it slip and don’t take care of issues, they will pile up, Technical Debt will increase, and your quality will suffer.
So, how’s your training going?
Yours, Holger
MEASURE IT
I believe in improving the quality of your software projects. If you want to improve something, you have to measure it first. That idea was introduced by Peter Drucker, the famous management book author.
Now if I ask you, what metrics you could measure about your code quality, would you have an answer?
You could measure the average complexity of your classes. Or the churn of your classes (how often they or their content changes). This tells you about spots in your project that you have to keep a close eye on.
There are tools that help you with that. Make sure to measure consistently to get a picture of how things change.
Do you know what the average, or worst, complexity on your last project was? Do you know your current value? Can you compare those and interpret the impact these numbers have on the outcome of your projects? This could be development taking longer, or higher count of bugs.
But you have to measure to know.
If you need assistance in setting these things up, let me know.
Yours, Holger
CODE QUALITY & SECURITY AUDIT
I spent the day at a new client’s office. They hired my to do a complete code quality and security audit for their website and shop system. They are rebuilding and relaunching it. The app is built using Ruby on Rails.
The client asked for my expert opinion about the general code quality as well as specific hotspots like PayPal integration. I will create multiple pages of in-depth analysis and recommendations on how to improve the project.
Starting this project today consumed all of my attention, thus you get this letter now. It’s evening here for me in Berlin and I couldn’t be happier with how the day went. There were points in my past where co-workers snared at my thoroughness and me being (over)precise. It turns out these are very good attributes to have when it comes to an audit like this.
Yours, Holger
ONE METRIC
From the feedback I got for my questions and letters regarding the quality of software projects, I can tell you one metric software developers look for.
Test Coverage
Well, that was no real surprise, was it?
Let me tell you another metric:
Documentation
Can you guess who cares for that? Users of your software. They don’t care for tests. But they want to know how to use the thing they paid for. (Even if it’s OSS they do pay for it: With their attention and time.)
Project managers on the other hand might care about both metrics. Most of the time, I’d wager, they care even more about planning and risk management of the project. As I am married to a wonderful wife who works as a great project manager, I’ll verify this statement tonight 😆. (I’ll report back)
The person authorizing the budget might care the most about the costs. And yes, the price (in 💵💶💷💴) people have to pay for your results is a quality metric of itself.
My point is this: While there are many different aspects for the quality of a project, which one you should put a priority on depends on your target audience.
Yours, Holger
LET THE COMPUTER HELP YOU WITH THAT COMMENT
Commenting code and documenting it has been a topic in these letters already. I linked to resources on how to write docs etc. For the future, this might not be necessary anymore. Because you can have a machine write the comments for you. There is a research project done by Chinese researchers Xing Hu, Ge Li, Xin Xia, David Lo and Zhi Jin named “Deep Code Comment Generation”.
This is their introduction:
In software development and maintenance, developers spend around 59% of their time on program comprehension activities. Previous studies have shown that good comments are important to program comprehension, since developers can understand the meaning of a piece of code by using the natural language description of the comments. Unfortunately, due to tight project schedule and other reasons, code comments are often mismatched, missing or outdated in many projects. Automatic generation of code comments can not only save developers’ time in writing comments, but also help in source code understanding.
You might be wondering what results they achieved:
Here’s a method they used it for (the method is abbreviated and not shown in full in their abstract) public static void sort(Comparable[] a){ int n=a.length; for (int i=1; i < n; i++){ Comparable v=a[i]; int lo=0, hi=i; while (lo < hi) { … } … } assert isSorted(a); }
This method sorts. I deducted that from its name. Now, here is the comment written by a human:
Rearranges the array in ascending order, using the natural order.
And this is what the computer generated:
Sorts the array in ascending order, using the natural order
:spooky:
Another method:
public boolean contains(int key){
return rank(key) != -1;
}
The human version:
Is the key in this set of integers?
The machine-version:
Checks whether the given object is contained within the given set.
I like the machine-generated more!
If you ever wrote these comments yourself, you know how quickly they are outdated. Having a machine update these on regular intervals make much sense to me!
Here’s the link to the paper: Deep Code Comment Generation
Yours, Holger
TIME WELL SPENT
Yesterday I went to an exciting event. The topic was “Can Artificial Intelligence synthesize software?”. The company Seerene organized the event. I haven’t heard about them before, but they are just what I like. They analyze code and projects for optimization potential and defects. I started the conversation with them, let’s see what comes out of it.
Perhaps you have heard of the machine-learning software that can make your holiday pictures look like a Picasso? That’s called Becasso, and that’s done by the people I visited yesterday. It’s a cool achievement to transform a picture into something that looks like a Picasso painting (or just a cool painting…).
Text is more straightforward for machines to understand than pictures. They can recognize patterns more easily. At least that’s my understanding. And everyone here listens to me, right now. So just let us pretend I am right for a second. Cool. Two programmers write code in two different styles. If you and I write the same Ruby program, it will look different. But—if the problem domain is well defined and smallish—it won’t look completely different (most of the times). It should be possible then, to have a machine-learning program that can take my code and make it look like your code. Transform my style into yours. Or vice versa. Or take a style guide, we both decided on, and transform our code into code that conforms to the style guide. Automatically.
I haven’t said this would be useful! Of course, there are problems. There always are. What happens, when somebody has to modify that code. Write a new feature… Will the algorithm change the style again? Can the third developer even understand the code the machine wrote?
And what about belletristic? Could I have a program that turns my letters to you into something like it was written by Hemingway? (See what I did there? I subconsciously made you associate my letters with belletristic, ha!)
Software Engineering will be transformed in a lot of fundamental ways in the next 20-30 years. See you around. 😉
Yours, Holger
DON'T BUILD A FIVE-STAR HOTEL
When you want to go on vacation, somewhere far away, where you haven’t been… How do you decide for the hotel? What language speaks to you on the hotel‘s website? What images convey to you that this might be a good hotel? Do you only follow suggestions by a friend? Do you care about the vicinity to tourist attractions or important sights? How did they get your attention?
If you only book 5-star hotels, what qualities do they provide, that others don’t? In case you stay the night at a bed-and-breakfast, what made you choose it?
Think about that for a minute.
Now let’s turn to your projects. What could you do, to get people notice and choose you from a pool of similar projects? What characteristics do you care about? And would it make sense to optimize for those, to attract people similar to you? If you do the project for someone else, do they share your views? Would they rather you optimized for something else entirely? Perhaps that would make their project an even bigger success on their eyes?
I am curious what your thoughts are right now.
Yours, Holger
RISK LIST
Imagine you are doing a software project. It is mostly going like planned. Things happen. You anticipated them and prepared for them. But there are days when unexpected things happen:
- Stack Overflow is down, and your developers suddenly aren’t as productive as usually 😜
- Slack is down, and communication is halted. Everyone freaks out, and no work gets done.
- Your hoster has problems with their energy and their emergency energy, and servers stop and reboot. You have to take care of this.
- all kinds of things…
What would happen, if you made a list of these things that occur and wrote down how long these took / their impact on your projects? You could also write down what expected risks you already had planned for and their possible impact. Start to make these visible, too.
I bet your list would grow rather long. I also bet it would give you some nice things to talk about with your stakeholders when you plan the next project or feature.
Yours, Holger
CYCLOMATIC COMPLEXITY
To achieve high quality in your team’s code, you should use tools like a static analyzer. These analyzers give you lots of metrics. One is the cyclomatic complexity. A very reduced definition is, that the more complex your methods are, the higher the cyclomatic complexity. A high complexity results from many different paths the program can take while running your code.
Many conditionals (if
/else
) or branches in your code lead to higher complexity.
But why does the complexity matter? I want to give one quite simple reason, that entices a developer to reduce the complexity. It is not because the program is harder to reason about (that’s also true!). Every possible path through your code increases the number of test cases the programmer has to write. It makes sense: If there are three possible paths, the program can take to reach the end of the method, you have to write at least three test cases to be sure everything works. Factor in that you probably will have different inputs to your methods, and the number of test cases increases quickly—because you have to test every path for every possible input. And it gets worse if your method depends on changing states or mutable data…
If you want to make your life easier when writing your tests, then decrease the complexity of your methods. Easy as that 😜
Yours, Holger
HOW TO PAINT A FENCE
If you paint a fence, you need to make sure to prepare the wood. Take coarse-grained sandpaper and sand the old paint. You have to take it off the wood completely. Once you are done with it, you should use a primer and put it onto the wood. Let it dry for a few hours. After the primer has dried, you take your color and apply it thinly. Let it dry for another 6 hours. The next step is to apply the color again and let it dry again. Afterward, you can decide whether you need protective paint/lacquer, to guard against weather conditions. That depends on your location.
If you are in a hurry, you can skip any of the steps and just paint the fence. Of course, that paint will only last you for a few months or perhaps years—if you are lucky and live in an area with “benevolent” weather. But most of the time, you will have to redo you fence soonish and incur at least the same costs for the paint and the time it takes you.
If it’s worth doing your project, it’s worth doing it right.
In case you paint fences, please don’t ask me 😅. But if your software project could need some help, let me know.
Yours, Holger
PS: Today marks the two-month anniversary of me writing daily. 🎉 Thanks for inviting me into your inbox. It’s a pleasure.
PLANNING FOR TECHNICAL DEBT
Do you know the term technical debt? Wikipedia describes it as “a concept in software development that reflects the implied cost of additional rework caused by choosing an easy solution now instead of using a better approach that would take longer.” (https://en.wikipedia.org/wiki/Technical_debt) This is certainly a correct definition, but there’s more to it. We’ll get to that shortly.
Yesterday I wrote
Anyway, it’s important to take care of quality right from the start of the project. Don’t fall for the idea of redoing it later. Refactorings are common, useful and will happen, but don’t plan for them from the beginning.
My good friend Tino brought to my attention, that I did not mention an important fact: (paraphrased by me)
Good planing also accounts for planned technical debt, instead of accumulating technical debt during the project because of factors like the cost of the project, fear of delays and bad decisions.
Thanks, Tino!
So why should you plan for technical debt (TD from here on)? A low TD approach is commonly perceived as superior. But, accumulating TD might be beneficial under certain circumstances. This could be that you plan for a very short release to attract early adopters or because you want to be first-to-market in a heavily contended market, or with a new feature. Another point why TD might make sense in your project is the following: TD always has a certain risk associated with it. The risk could be increased costs in maintenance of this part of the application. Now imagine that you create a part of your app, where customers can get in contact with you and receive first-aid in using the software—like a help-desk. You know that, at some point in the future, you will outsource this whole part of the app to a third party who will take complete, good care of your users. Now you can transfer the whole risk of this part and the TD associated with it, to an outside player. They are experts in this thing and won’t use your help-desk module but their own software. So you don’t have to worry about it while creating it, and you don’t have to worry about maintaining it in the future.
This, again, makes it clear why a good plan is crucial for the success of your project and for the quality of your work.
Yours, Holger
STANDING IN FOR QUALITY
If you read these letters for a few issues, you might have already noticed that I like quality in software engineering. I try to optimize for quality and enhancing the quality of a project leads to more successful projects and more satisfied clients. If you care for the quality it can lead to situations where you have to stand your ground to achieve the goal of increasing the quality (or your processes or your products). Because doing high-quality work also increases the costs of a project. And it’s rare that managers don’t care for the cost of a project.
A good thing to have in those discussions are case studies about successful IT projects—and what made them successful. An external partner that explains the business case why quality matters would be helpful, as well.
Anyway, it’s important to take care of quality right from the start of the project. Don’t fall for the idea of redoing it later. Refactorings are common, useful and will happen, but don’t plan for them from the beginning. If your design and architecture plans for the project were faulty or of low quality from the start, there is not much you can do later on. Be realistic about the time it will take to create a well thought-through design for your application. Factor in that you might have to create a small poc (proof of concept) to test and compare different approaches if you lack the experience.
Don’t let someone else rush you to do these things. Explain to them that you save time in the long run. What’s the saying?
Weeks of programming can save hours of planning
Yours, Holger
ALL YOUR DATA ARE BELONG TO US
The latest Chrome beta (version 70) introduces changes to the Shape Detection API and the Web Authentication API.
The Shape Detection API consists of three APIs: A Face Detection API, a Barcode Detection API and a Text Detection API. Given an image bitmap or a blob, the Face Detection API returns the location of faces and the locations of eyes, noses, and mouths within those faces. To give you rudimentary control of performance, you can limit the number of returned faces and prioritize speed over performance.
They cannot (yet) compare faces and recognize known faces in the browser. Give it a year. Soon browser plugin creators are able to scan the photos you upload to Facebook and identify the people you had fun with last night. If you think I am exaggerating, please wait for the next paragraph.
The Credential Management API, enabled in Chrome 51, defined a framework for handling credentials that included semantics for creating, getting, and storing them The Web Authentication API […] allows web applications to create and use strong, cryptographically attested, and application-scoped credentials to strongly authenticate users. Also enabled by default are macOS’s TouchID and Android’s fingerprint sensor via Web Authentication. These allow developers to access biometric authenticators through the Credential Management API’s PublicKeyCredential type.
(Emphasis added by me)
The Web Authentication API draft from 12 September 2018 has a section on Privacy Considerations.
Biometric authenticators perform the biometric recognition internally in the authenticator - though for platform authenticators the biometric data might also be visible to the client, depending on the implementation. Biometric data is not revealed to the WebAuthn Relying Party; it is used only locally to perform user verification authorizing the creation and registration of, or authentication using, a public key credential. A malicious Relying Party therefore cannot discover the user’s personal identity via biometric data, and a security breach at a Relying Party cannot expose biometric data for an attacker to use for forging logins at other Relying Parties.
(Emphasis added by me)
… “depending on the implementation”… I use my fingerprints to access my laptop and used to use it for my phone. I trust Apple. This is my decision. I wouldn’t trust Chrome and web developers to keep my biometric data safe.
There is no point here. Today I have nothing clever to say. Only, I slightly worry what oversight there will be for this data. I know the draft says different, and it seems unlikely, but: When will we see the first headline in the news that a database for the website of StartupCo was breached and, among stolen the data, were some biometric datasets.
History shows that the more ways there are for things to go wrong, the surer it is that they go that way.
Keep safe.
You, Holger
PS: You perhaps recognized the pun in the headline. If not, you can read about it here: All your base are belong to us. Excuse my nerdishness 😉
PPS: One more for the German readers: Nerdish by nature 😇
ALL YOUR DATA ARE BELONG TO US
The latest Chrome beta (version 70) introduces changes to the Shape Detection API and the Web Authentication API.
The Shape Detection API consists of three APIs: A Face Detection API, a Barcode Detection API and a Text Detection API. Given an image bitmap or a blob, the Face Detection API returns the location of faces and the locations of eyes, noses, and mouths within those faces. To give you rudimentary control of performance, you can limit the number of returned faces and prioritize speed over performance.
They cannot (yet) compare faces and recognize known faces in the browser. Give it a year. Soon browser plugin creators are able to scan the photos you upload to Facebook and identify the people you had fun with last night. If you think I am exaggerating, please wait for the next paragraph.
The Credential Management API, enabled in Chrome 51, defined a framework for handling credentials that included semantics for creating, getting, and storing them The Web Authentication API […] allows web applications to create and use strong, cryptographically attested, and application-scoped credentials to strongly authenticate users. Also enabled by default are macOS’s TouchID and Android’s fingerprint sensor via Web Authentication. These allow developers to access biometric authenticators through the Credential Management API’s PublicKeyCredential type.
(Emphasis added by me)
The Web Authentication API draft from 12 September 2018 has a section on Privacy Considerations.
Biometric authenticators perform the biometric recognition internally in the authenticator - though for platform authenticators the biometric data might also be visible to the client, depending on the implementation. Biometric data is not revealed to the WebAuthn Relying Party; it is used only locally to perform user verification authorizing the creation and registration of, or authentication using, a public key credential. A malicious Relying Party therefore cannot discover the user’s personal identity via biometric data, and a security breach at a Relying Party cannot expose biometric data for an attacker to use for forging logins at other Relying Parties.
(Emphasis added by me)
… “depending on the implementation”… I use my fingerprints to access my laptop and used to use it for my phone. I trust Apple. This is my decision. I wouldn’t trust Chrome and web developers to keep my biometric data safe.
There is no point here. Today I have nothing clever to say. Only, I slightly worry what oversight there will be for this data. I know the draft says different, and it seems unlikely, but: When will we see the first headline in the news that a database for the website of StartupCo was breached and, among stolen the data, were some biometric datasets.
History shows that the more ways there are for things to go wrong, the surer it is that they go that way.
Keep safe.
You, Holger
PS: You perhaps recognized the pun in the headline. If not, you can read about it here: All your base are belong to us. Excuse my nerdishness 😉
PPS: One more for the German readers: Nerdish by nature 😇