Every developer is familiar with Pull Request, however recently I came across another useful practice – “sTool Request”. sTool request is a simple and powerful practice yet some, especially junior developers, hesitate to use it; at least I noticed the behaviour in my team and so it is a good time to talk about it.
Unless your team is practicing pair programming, everyone tends to work alone and often the only time you get to see work of another developer is at Pull Request time. While it is generally a good thing, there are few drawbacks:
Effort has been expanded – sunk cost bias has already kicked in
Work is completed – physically & physiologically – let’s move on to the next thing
Code has settled – mistakes are more expensive to fix
In case a bug is discovered at a later point, it is harder to figure from the original developer – rarely anyone remembers details of decision making and code several weeks back.
sTool Request can help remedy those issues to some degree, at the very least it is cheaper to brainstorm/discuss questions, issues and ideas prior to producing code, and/or at any point during the work. So here goes my proposal to a team:
“Got a question or a doubt? Perhaps you want to bounce ideas around? Ask a team member to grab a stool/chair, sit down and help you out. Use the momentum to have a rich conversation and/or debate. Don’t wait for PR (Pull Request), refactor card, or a bug report. We are all on the same team, working together to deliver team’s goal, improve quality and learn new things.”
I would love for people to pair program, but in the absence of the practice, it is useful to invoke “sTool Request”, summon a developer and work things out. There are so many times I though to myself: “if only a developer have asked prior, he wouldn’t have made those mistakes and also learned a ton from the experience”. It is harder to learn retrospectively, it is better to learn in the moment.
“Adding manpower to a late software project makes it later.”
Brooks’s Law
Sooner or later every developer learns about Brook’s Law, for me it was later, but still better than never. After the encounter and countless references to the book on the internet, I decided to read it for myself and see what it’s all about.
The original book came out in 1975 and the latest revision in 1995. I think it is important to set expectations right, and accept that the author wrote a lot from that perspective – good old days when the industry still debated “if-else block” vs “goto statement”. In addition, the book isn’t an easy read, lot of technologies/terminologies aren’t familiar to me and that made it harder to follow. However I don’t think any of that should be a showstopper, I say: “push through”!
Opinions are like assholes – everyone got one and I’m no different. However I’m really struggling to express my thoughts on this book. On one hand the book is quite insightful, on the other hand, for the lack of better word – irrelevant. On one hand human behaviour didn’t significantly change since 1975, on the other hand business did. Let me give you an example from my personal experience: 45 years after the book has been published, managers still think that adding new developers to meet a three-month deadline is a solution. Never mind that a good developer typically needs more than three months to even get up to speed on our projects. However, adaptation of scrum (or alike) methodologies and business acceptance of small value-adding iterations has changed the way developers schedule and deliver code. There is no more hiding, in every sprint something of a value must be developed, demoed and shipped.
I can grumble, agree and disagree with the author on several points, but I think it is meaningless and unfair. I think the book should be taken for what it is, and not some sort of a guide from the days long gone to the present generation. Nevertheless, perhaps some people must read it for the sake of not solving the same old problems, the same old way, that never worked anyhow. Perhaps everyone should read it and understand that not all IT problems uniquely belong to IT industry and an answer is readily available just outside of it. Perhaps I should stop rambling and admit: may be the book didn’t impress me as much as I hoped it would but at least I don’t feel any regrets spending my time with it.
In a nutshell: -: Not an easy read if you aren’t familiar with terminology and technology of the past -: Some irrelevant concepts +: A lot of insight into software industry, some still hold true +: Interesting references and opinions +: Enjoyable, with certain expectations =: I don’t think this book should be atop a reading list. However if you are curious and have time, I wholeheartedly recommend it. Don’t set any expectations, remember the book originated in 1975 and enjoy the essay.
Title: The Mythical Man-Month: Essays on Software Engineering Author: Frederick Brooks Cover:
Notes & Quotes from the book, I couldn’t help myself but to take:
“Solutions to many IT problems already exist in other industries, but IT pro feel and act as those don’t apply.”
“Techniques proven and routine in other engineering disciplines are considered radical innovations in software engineering.”
“Self-Documenting Programs – a basic principle of data processing teaches the folly of trying to maintain independent files in synchronism. It is far better to combine them into one file with each record containing all the information both files held concerning a given key. Yet our practice in programming documentation violates our own teaching. We typically attempt to maintain a machine-readable form of a program and an independent set of human-readable documentation, consisting of prose and flow charts. The results in fact confirm our teachings about the folly of separate files. Program documentation is notoriously poor, and its maintenance is worse. Changes made in the program do not promptly, accurately, and invariably appear in the paper.”
“Long before any code exists, the specification must be handed to an outside testing group to be scrutinized for completeness and clarity. As Vyssotsky says, the developers themselves cannot do this: “They won’t tell you they don’t understand it; they will happily invent their way through the gaps and obscurities.””
“Day-by-day schedule slippage is harder to recognize, harder to prevent, and harder to make up than calamities. The first step in controlling a big project on a tight schedule is to have a schedule, made up of milestones and dates for them. Milestones must be concrete, specific, measurable events defined with knife-edge sharpness. A programmer will rarely lie about milestone progress, if the milestone is so sharp he can’t deceive himself.”
“Cosgrove advocates treating all plans, milestones, and schedules as tentative, so as to facilitate change. This goes much too far— the common failing of programming groups today is too little management control, not too much.”
“Intercommunication is worse. If each part of the task must be separately coordinated with each other part/ the effort increases as n(n-I)/2. Three workers require three times as much pairwise intercommunication as two; four require six times as much as two. If, moreover, there needs to be conferences among three, four, etc., workers to resolve things jointly, matters get worse yet. The added effort of communicating may fully counteract the division of the original task”
“The basic fallacy of the waterfall model is that it assumes a project goes through the process once, that the architecture is excellent and easy to use, the implementation design is sound, and the realization is fixable as testing proceeds. Another way of saying it is that the waterfall model assumes the mistakes will all be in the realization, and thus that their repair can be smoothly interspersed with component and system testing.”
“The first step is to accept the fact of change as a way of life, rather than an untoward and annoying exception. Cosgrove has perceptively pointed out that the programmer delivers satisfaction of a user need rather than any tangible product. And both the actual need and the user’s perception of that need will change as programs are built, tested, and used.”
“First, the man with strong management talent and strong technical talent is rarely found. Thinkers are rare; doers are rarer; and thinker-doers are rarest.”
“The job done least well by project managers is to utilize the technical genius who is not strong on management talent.”
“In tasks that can be partitioned but which require communication among the subtasks, the effort of communication must be added to the amount of work to be done.”
“In tasks that can be partitioned but which require communication among the subtasks, the effort of communication must be added to the amount of work to be done.”
“Failure to allow enough time for system test, in particular, is peculiarly disastrous. Since the delay comes at the end of the schedule, no one is aware of schedule trouble until almost the delivery date. Bad news, late and without warning, is unsettling to customers and to managers.”
“But false scheduling to match the patron’s desired date is much more common in our discipline than elsewhere in engineering. It is very difficult to make a vigorous, plausible, and job-risking defense of an estimate that is derived by no quantitative method, supported by little data, and certified chiefly by the hunches of the managers”
“The fate of WIMP: Obsolescence. Despite its excellencies, I expect the WIMP interface to be a historical relic in a generation. Pointing will still be the way to express nouns as we command our machines; speech is surely the right way to express the verbs. Tools such as Voice Navigator for the Mac and Dragon for the PC already provide this capability.”
“Men and months are interchangeable commodities only when a task can be partitioned among many workers with no communication among them”
“The bearing of a child takes nine months, no matter how many women are assigned.”
A while back I decided to make a progressive web-app and for the fun of it, learn a new framework (Angular 7 at the time, 9 now), language (TypeScript) and to top it all off, challenge myself by test driving the entire thing.
Before I dive into our main thought, a little disclaimer: I’m sort of a full-stack developer; meaning my world rotates around developing microservices with Dropwizard + Java 8, a little bit of front-end with Backbone & Marionette + JavaScript and a little of Oracle on DB side. Uninspiring and outdated, stack is my daily existence. Regardless of stack, I do test drive all of my code, I believe it is a good idea and I have been doing it for a while now.
From the very inception, I decided to test drive my app and to do it only with unit tests and depending on your definition, integration tests. After years of writing, re-writing and maintaining end-2-end tests, I figured one thing only: they are a waste of time and money. So my entire app is test driven by jasmine specs, starting at individual components (or a service) and moving onto a combination of components (how they work together) and culminating with the main component which is mostly in charge of testing navigation through out the app.
Now, to test a component in Angular (to the best of my knowledge and understanding) is to test a template and associate code together as one thing (unit of work). This represents a bit of a challenge, mostly associated with manipulation of UI. Effectively you will be doing a lot of query selections, clicking, and sometimes dealing with async and Angular change detection. Since I get to work on my app few hours per week, I tend to forget (sometimes rather quickly) fine details of writing a component test. Like the saying goes: “if you can’t beat them, join them”, so I gave up on constant rehashing and decided to write my own test helper, which is easy to use and doesn’t need much to remember. For example, find an element with the placeholder value of “name”.
In addition to all of the above, jasmine errors tend to be verbose and not very user friendly. For example if you are trying to query select all elements, which don’t exist (but you assumed they did) and then call a method on a particular one, you will be met with off-putting exception “undefined is not an object”.
TypeError: undefined is not an object (evaluating 'this.findElementsByPlaceholder(placeholder)[0]') in http://localhost:9876/karma_webpack/main.js (line 3909)
I believe we can do better than that. We can wrap “query select all” calls in your own method, check length and if there are no elements then simply throw an error with explanation. For example:
Error: Could not find a placeholder: name in either of tags: placeholder,ng-reflect-placeholder in http://localhost:9876/karma_webpack/main.js (line 3906)
By doing so, you effectively eliminate confusion and save yourself some time (at least I do). So go out there and throw some well-explained exceptions, so you don’t have to guess which object is undefined and why.
Today in the morning I spend couple of hours trying to implement dropdown with filter and “valid only” entry. I started my endeavor with ng-bootstrap dropdown (since I’m working on Angular app), quickly realizing that it will not work since there is no filter option. Next I figured that a typeahead will fit much much better.
Everything worked out very well except for one big caveat: the typeahead does not clear “<input>” field when entry is not valid (not in the list of options). After monkeying with “onBlur” for about 20 minutes, a sane thought occurred in my head: “What am I doing? Hacking? There must be a straight forward way!”.
Last year I read a book “Toyota 14 principles” by Jeffrey K. Liker and learned a few powerful ways in order to get stuff done. Right after I finished the book, I implemented FPB (Family Production Board – which is a Kanban board) using masking tape, permanent marker and sticky notes. The board was a success, as we seem to accomplish more stuff than ever before.
Today I decided to upgrade the board to something a little bit more substantial – an old white board, left over from my previous upgrade. The purpose and means remain the same, however the board now looks a lot better.
After reading and breaking your head for a while, you finally demystified a piece of code and staring at it you wonder: “why does it have to be so complex”? – Has this ever happened to you?