Weekly Dev Tips cover image

Weekly Dev Tips

Latest episodes

undefined
Apr 1, 2019 • 3min

Work Alone with Mystery Guest

Hi and welcome back to Weekly Dev Tips. I’m your host Steve Smith, aka Ardalis. This is episode 45 on working alone with a mystery guest. Working Alone Show Notes / Transcript This week's show was recorded on 1 April 2019 with a special guest who has chosen to remain anonymous. I'm a developer with a regular day job, but at night I do freelance work in the shadows. I mostly right wrongs committed (to source control) by other developers, so the people who use their software can sleep better at night. I work alone, and have a secret identity to protect those closest to me. And because I signed a strict employee agreement with my day job and I don't want them to find out about my moonlighting activities. My tip to other developers: work alone. After years of working with other team members, I can tell you it's for the best. My team members at my day job are like my personal nemesis. There's this one guy who doesn't take the work seriously enough. He refuses to follow team conventions. Half the time it seems like he's intentionally trying to blow up our code. He should probably consider changing roles to testing. I'm constantly fighting with this joker. Then there's another dev I work with - I swear he thinks writing impossible to understand code is his ticket to job security. Most of the code he writes, even if it 'works', is like a riddle, wrapped in a mystery, inside an enigma. I think he gets a kick out of seeing if the other developers on the team can figure out his clever code. I don't have time for his games. When I'm not fighting with these two, it seems like as soon as I'm able to add a cool feature to our code, we're closing in on a ship date and the product manager puts a freeze on new features. If 'Mr. Freeze,' as we call him, weren't involved, I'm sure I could get a few more features into the product for each version. Even when I'm not having to deal with this group, I have to compete with another dev who thinks he's a gift to the team. I think he prefers to work alone, too, or at least he doesn't like to work with me. His work is always superb, which grates on me partly out of jealousy, but also because when he's out sick (he has really bad allergies), there's nobody but me to stand against the rest of the team. At night, working alone, I can do my best work. Hiding behind a bitmask, I knock out issues in client projects before they see me coming. I don't always follow the rules, but I get the job done. I may not always deliver the code teams want, but I give them the code they deserve. Ok... well thanks for that tip... uh... I'm batdev Show Resources and Links devBetter That’s it for this week. If you want to hear more from me, go to ardalis.com/tips to sign up for a free tip in your inbox every Wednesday. I'm also streaming programming topics on twitch.tv/ardalis most Fridays at noon Eastern Time. Thank you for subscribing to Weekly Dev Tips, and I'll see you next week with another great developer tip.
undefined
Mar 25, 2019 • 7min

Work From Home Tips with Andrew Lock

Hi and welcome back to Weekly Dev Tips. I’m your host Steve Smith, aka Ardalis. This is episode 44 with some guest tips on working from home that I hope you'll find useful. Working From Home Tips Sponsor - devBetter Group Career Coaching for Developers Are you a software developer looking to advance in your career more quickly? Would you find a mentor and a group of like-minded professionals valuable? If so, check out devBetter.com and read the testimonials at the bottom of the page. Sign up for a risk free membership if you're interested in growing your network and skills with us. Show Notes / Transcript This week we have a special guest, Andrew Lock, who like me does a lot of work with ASP.NET Core. Andrew, why don't you go ahead and introduce yourself for our listeners, and then just go right into the tips you'd like to share. Hi, my name's Andrew Lock, I'm a developer and author of the book ASP.NET Core in Action. I live in Devon in the UK but I work for a company in London. I work 100% remotely, which is becoming more and more common in the dev community, But one question I hear a lot is "how do you stay focused when you're working from home all day?" That's one of those questions where the answer is going to depend a lot on the particular person. Many people who haven't worked remotely before remember the occasional time they "worked from home" and worry about all the distractions that are around you: the TV, kids running around, all those little chores that need doing. So how can you cope with all this, and actually be productive when working from home. I thought I'd share a few things that I've found work for me. You might find some of them work for you too, but don't worry if they don't! Have a dedicated work area A really important part of working from home for me is having a dedicated work area. We have a spare bedroom with a desk and that's where I work when I'm working from home. There's two parts to this. First it's important to have a comfortable chair and a desk that's the right height for you, to avoid fatigue and injuries. So no slumping on a sofa with the laptop! Secondly, it separates my life into Work and Home. If you work in the same rooms as you relax and do other things in, it can be easy to get distracted. When I'm working, I'm in the office and it's a lot easier to get into that working mentality. This also helps when you have other people in the house, as it's easy to say "if I'm in the office, I'm at work". It's worth mentioning that some people find that even with this approach, being at home all day is still too distracting, and they like to completely separate their work time by going to a shared working area, or a coffee shop. Personally I find that far more distracting, but it might work for you. Routine As well as having a dedicated work area, I find routine to be extremely useful. Whether you're able to follow a fixed routine or not will likely depend a lot on your specific job and your living situation, as well as other commitments, but I find any structure you can add to your day helps. It's all part of getting into the "I'm at work now" mentality, and trying to shut off other distractions. Of course, just because you're following a routine and working in your office, doesn't mean that you should be head-down working the whole time. Far from it! In fact, it's very easy to lose track of time when you're working from home, and be sat still for hours. Not only is that bad for you physically, I find it's actually detrimental to my productivity in the long run. The first few weeks of working remotely, I felt so productive in the morning. I would get my head down, code for several hours, and feel like I was really going strong. By the time it got to the afternoon however, I was drained, and unable to focus for the rest of the day. Instead, I find I can stay productive for a whole day by ensuring I take a lot of small breaks. In particular, I often use the Pomodoro technique. There's lots about this approach on the internet, and there's various apps you can use to follow it, but I'll give a brief summary of how I apply it to my day. The Pomodoro technique The Pomodoro technique involves working in relatively short, timed blocks. So I set a timer for 25 minutes, and focus 100% on the task at hand. When an alarm goes off I take a 5 minute break - make a cup of tea or coffee, check my emails, anything really. When the break timer goes off, I get straight back to working again for another 25 minute block. After 5 blocks of working, I take a longer 30 minute break - get some lunch or go for a run - before settling down to another 5 blocks of work. If you haven't tried it before, I strongly suggest giving the Pomodoro technique a go. Adjust the timings to what works for you. I was sceptical at first, but I've found it helps me stay focused for a whole day, without burning out in the afternoon. In fact it's the approach I used to write my book while also working a full time job, and I don't think I would have managed that without it! IT can feel unnatural at first to break up those long coding sessions, but it really pays off in the long run. Don't beat yourself up The last thing I want to mention is the feeling that you're being unproductive when you're working from home, even if you aren't! Something I struggled with a lot initially was the feeling that everyone assumed I wasn't working hard when I was at home. So I felt like I had to go above and beyond to show that I was - by not taking breaks, or working longer than the hours I was paid for. I'm sure this is how a lot of people think when they start working remotely, but I really encourage you to fight against it. When I was working in an office, I wasn't working 100% of the time. In fact, I was way less productive in the office, so try not to beat yourself up. Take breaks. Don't overwork yourself, and try and add some structure to your day - it's far more sustainable, and you'll probably find you're more productive than you ever thought you could be. Thanks for inviting me on Steve! You're very welcome - thanks for sharing your advice with us! I've added links to the resources you mentioned to the show notes at weeklydevtips.com/044. Show Resources and Links devBetter See Visualizations and Subscribe to WeeklyDevTips in YouTube Andrew Lock blog Andrew Lock on Twitter Pomodoro Technique ASP.NET Core in Action on Amazon That’s it for this week. If you want to hear more from me, go to ardalis.com/tips to sign up for a free tip in your inbox every Wednesday. I'm also streaming programming topics on twitch.tv/ardalis most Fridays at noon Eastern Time. Thank you for subscribing to Weekly Dev Tips, and I'll see you next week with another great developer tip.
undefined
Mar 18, 2019 • 6min

A Dependency Injection Story

Hi and welcome back to Weekly Dev Tips. I’m your host Steve Smith, aka Ardalis. This is episode 43, with a quick story about dependency injection. A Dependency Injection Story Sponsor - devBetter Group Career Coaching for Developers Are you a software developer looking to advance in your career more quickly? Would you find a mentor and a group of like-minded professionals valuable? If so, check out devBetter.com and read the testimonials at the bottom of the page. Sign up for a risk free membership if you're interested in growing your network and skills with us. Show Notes / Transcript A few years and several businesses ago, my wife and I ran an online ad business, Lake Quincy Media, that served banner ads on software developer web sites like W3Schools, www.asp.net, and ASPAlliance.com. I wrote the original ad serving software for the company, and over the years as we grew we built a team and rewrote it a couple of times. We were using ASP.NET, what would now be called web forms, at the time I first really understood how to use dependency injection. I still remember exactly how it happened, and it dramatically changed how I looked at structuring my object-oriented applications from that point forward. Backing up a bit, I'd learned about and bought into practices like automated testing and continuous integration some years earlier. These practices were not as widespread as they are today, especially in the Microsoft development space, but we were using them at Lake Quincy Media to good effect on our ad server software (which also included publisher and advertiser portals, etc.). We were using a CI server called Cruise Control which included a nice system tray tool called CCTray that would pop up a notification and play a sound any time the build failed or was fixed. It worked great and problems that broke the build were quickly addressed by our small team. However, the application was architected using a traditional N-Tier architecture that was the recommended approach at that time. This meant that the ASP.NET application depended on the business logic application which in turn depended on the data access layer that called the database. Tests of the business logic required a test database, and so our tests ran SQL scripts that reset the database to a known good state before every test. Running several hundred of these tests took about 5-10 minutes on the build server as a result, which wasn't ideal. The point is, we were using automated tests, but our architecture was forcing us to rely more on integration tests rather than unit tests. This background leads to the next part of the story. I remember distinctly trying to write a test for a method that dealt with saving new banner ad media files once they were uploaded to the server. The method in question needed to save the file, perform some work on the file, and then based on some other factors, call some other methods. I was trying to write tests for this, but I was forced to write tests that actually dealt with the file system, and these were very painful. A configuration file was required to specify the upload path, this path wasn't the same between servers and developer machines. Sometimes the file would be locked and tests would fail, or someone would check in a different version of the config file with the path set wrong, and the tests would fail. It was quite brittle, and the files access really wasn't what was being tested - the conditional logic of the method was. By chance I was chatting with my friend and fellow MVP and Iraq war veteran, Jeffrey Palermo as I was struggling with this. He hopped on a screenshare with me and showed me how to change my business-level class so it wasn't working directly with the file system. Instead, he created an interface that included the required file operations like save and rename file, and moved the actual logic for working with the file system into a new class that implemented this interface. Then he created an instance of the interface in the business-level class, which was set by the constructor. However, in our test code, he showed me how to create a fake implementation of the file interface, which we could have the tests configure to return whatever kind of result we needed for the test case we were validating. This was huge! It literally blew my mind and changed how I thought about and wrote code from that day forward. Aaron B., who recently joined my tips mailing list, prompted this tip with his question, "What is one thing you wish you knew when you first started your development career?" and this is what I thought of. Thanks, Aaron, and thanks again, Jeffrey, for showing me this awesome technique for reducing painful coupling in software applications. Needless to say, armed with this technique and a desire to learn more about the related SOLID principles, my tests quickly started to emphasize unit tests wherever possible instead of intregration tests for everything. Our builds started to get faster, and we found tests were quicker and easier to write as well. This was over ten years ago now, but I wish I'd learned it much sooner in my career, and I hope sharing it here will help some of you. If you have a story you'd like to share about something you learned later in your career that you wish you'd learned sooner, go to weeklydevtips.com/043 and leave it as a comment. Thanks! Show Resources and Links devBetter See Visualizations and Subscribe to WeeklyDevTips in YouTube Clean Code on Amazon That’s it for this week. If you want to hear more from me, go to ardalis.com/tips to sign up for a free tip in your inbox every Wednesday. I'm also streaming programming topics on twitch.tv/ardalis most Fridays at noon Eastern Time. Thank you for subscribing to Weekly Dev Tips, and I'll see you next week with another great developer tip.
undefined
Mar 4, 2019 • 9min

On Learning TDD and LISP with Uncle Bob Martin

Hi and welcome back to Weekly Dev Tips. I’m your host Steve Smith, aka Ardalis. This is episode 42 - the answer to life, the universe, and everything - with some guest tips on learning TDD and Lisp. Learning TDD and Lisp This week we have a special guest. He is the author of the books Clean Code, The Clean Coder, and Clean Architecture, all of which I think should be required reading for professional software developers. Robert C. Martin, aka "Uncle Bob", is here to share a couple of tips for software developers. You'll find him online at @unclebobmartin on twitter and at cleancoder.com. We'll jump right into his tip after this quick word from this week's sponsor. Sponsor - devBetter Group Career Coaching for Developers Are you a software developer looking to advance in your career more quickly? Would you find a mentor and a group of like-minded professionals valuable? If so, check out devBetter.com and read the testimonials at the bottom of the page. Sign up for a risk free membership if you're interested in growing your network and skills with us. Show Notes / Transcript Ok, so without further ado, please welcome Uncle Bob to WeeklyDevTips! ... Thanks so much, Bob! Structure and Interpretation of Computer Programs was actually the first computer science text book I had in college, in a class that used another Lisp variant, Scheme. I've added links to the resources you mentioned to the show notes, which you'll find in your podcast client or at weeklydevtips.com/042. Show Resources and Links devBetter See Visualizations and Subscribe to WeeklyDevTips in YouTube Uncle Bob on Twitter CleanCoder.com Clean Coders Videos Structure and Interpretation of Computer Programs on Amazon Structure and Interpretation of Computer Programs free PDF Clojure as a Dialect of Lisp Clean Code on Amazon The Clean Coder on Amazon Clean Architecture on Amazon That’s it for this week. If you want to hear more from me, go to ardalis.com/tips to sign up for a free tip in your inbox every Wednesday. I'm also streaming programming topics on twitch.tv/ardalis most Fridays at noon Eastern Time. Thank you for subscribing to Weekly Dev Tips, and I'll see you next week with another great developer tip.
undefined
Feb 25, 2019 • 7min

Sprints Versus Continuous Flow

Hi and welcome back to Weekly Dev Tips. I’m your host Steve Smith, aka Ardalis. This is episode 41, in which I'll talk about the difference between sprint and iteration-based software processes compared to continuous processes. If you’re enjoying these tips, please subscribe in your app. You can leave a rating and better yet, a comment in your app, too. I also accept subscriptions to @WeeklyDevTips on twitter and comments and requests for topics there or in the show comments, too. Thanks for all of your support! Sprints Versus Continuous Flow Sprint and iteration-based processes are stepping stones on the path from waterfall toward continuous flow. In this episode we'll make some comparisons to build and integration processes to demonstrate this. Sponsor - devBetter Group Career Coaching for Developers If you're not advancing as quickly in your career as you'd like, you may find value in joining a semi-formal career and technical coaching program like devBetter.com. devBetter is a small group of motivated developers meeting every week or two, and staying connected in the meantime via a private Slack community. I answer questions, review code, suggest areas in which to improve, and occasionally assign homework. Interested? Learn more at devBetter.com. Show Notes / Transcript I've been a fan of continuous integration, or CI, for many years. When I was first getting started in professional software development, CI was still new and unproven. Some of my first consulting engagements had me working on teams where there was a team member who was the designated integrator. Their job was to understand how to put all the components of the application together so that the app could be deployed. This was a major ordeal every couple of months when a deployment needed to be made. In the 1990s, automated builds started to become increasingly popular. Tools like Ant, and later in .NET NAnt, were growing in popularity. Automated builds started to enable periodic scheduled integrations. Instead of having someone manually integrate and deploy the system every few months, these automated tools enabled weekly integrations, providing much more rapid feedback. Eventually, the frequency of these builds increased from weekly to daily (or more typically, nightly), and finally to the extreme of continuous integration. Continuous integration builds and tests the application every time a change is made to the application's source control. It's hard to get much better than continuous integration, but there are still a couple of nice features that can and have been added. Today, I most of my projects use continuous integration, but continuous integration by itself doesn't prevent developers from breaking the build by checking in broken stuff to the main branch. Two features that tools like Azure DevOps and GitHub support now are the ability to run builds on pull requests and the ability to restrict merging pull requests so that they require a passing build before they can be pulled in. Adding in these two features eliminates the vast majority of broken build scenarios, ensuring the main branch of the application remains in a working state at all times. So, what does this have to do with sprints? Before we had XP iterations and Scrum sprints, most software development used some kind of waterfall-like process. Iterations, such as they were, were quite long: months and sometimes years. Iterative development approaches popularized by agile software development recommended much shorter iterations, with many developer organizations shifting to 2- or 4-week iterations. Each iteration, the team would estimate the backlog, prioritize the work, plan out the iteration or sprint, commit to the plan, get work done, test it, try to deploy it, and potentially hold a retrospective about the iteration. It's not uncommon to look at iteration-based agile and compare it to a series of mini-waterfalls. The analogy from infrequent deployments to more frequent integrations is an easy one to see. So, with integrations, there's an obvious spectrum of increased benefit associated with increased frequency. There aren't many dissenting voices crying out that continuous integration is a waste of time and we should only build software once a month. The feedback benefits of CI over even daily builds is quite clear. So, if you see a certain amount of benefit when going from long-term waterfall delivery to 4-week iterative delivery, it should be obvious that this benefit will increase further if you go from 4-week to 2-week. But most teams stop there. The reason why most teams never shorten their iterations below 2-week sprints is because of the pain involved in some of the required ceremonies that are tied to the sprint. I literally saw this happen last week, when a client initially planned on 1-week sprints but dropped back to 2-week sprints because there were too many meetings to make 1-week sprints work. The issue is that the ceremonies eat into time to actually get work done. For instance, a reasonable retrospective probably takes an hour. Investing an hour every 2 weeks may seem reasonable, but what about every week, or every day? Estimating and prioritizing the backlog is a similarly painful part of most sprint plans - would it make sense to do it more often? This may sound crazy if you didn't listen to last week's episode yet, but give it some thought. Here's the thing - these ceremonies aren't strictly tied to delivering software. You could increase or decrease your sprint cadence, and still have monthly retrospectives. The same is true for prioritizing work. You can still do it every two weeks while your sprints are one week long, if you want. You can even do it literally just-in-time as things are pulled from the backlog. Imagine how quick sprint planning sessions would be if they only had to choose the next item the dev team would start working on? You could do that 10 times a day with an email exchange if the product owner made it a priority. Once you realize that really long iterations, like traditional waterfall, are not great, and shorter iterations are better, you should be able to make the jump to continuous flow pretty easily. If there are things that make this too painful, then listen to the last episode, and do those things more often. Or, realize they're not in the critical path to delivering software, and stop tying them to your software delivery cadence and schedule them on whatever cadence makes sense for your team. Show Resources and Links devBetter If It Hurts, Do It More Often See Visualizations and Subscribe to WeeklyDevTips in YouTube That’s it for this week. Next week we have a special guest as Robert "Uncle Bob" Martin will provide a couple of tips - be sure to check back for that. If you want to hear more from me, go to ardalis.com/tips to sign up for a free tip in your inbox every Wednesday. I'm also streaming programming topics on twitch.tv/ardalis most Fridays at noon Eastern Time. Thank you for subscribing to Weekly Dev Tips, and I'll see you next week with another great developer tip.
undefined
Feb 18, 2019 • 8min

If It Hurts, Do It More Often

Hi and welcome back to Weekly Dev Tips. I’m your host Steve Smith, aka Ardalis. This is episode 40, in which I'll talk about the paradoxical advice, "if it hurts, do it more often." If you’re enjoying these tips, please subscribe in your app. You can leave a rating and better yet, a comment in your app, too. I also accept subscriptions to @WeeklyDevTips on twitter and comments and requests for topics there or in the show comments, too. Thanks for all of your support! If It Hurts, Do It More Often I've meant to do an episode or article on this topic for a while. It's advice I've been giving to my mentoring and corporate clients for years. Let's dive in after a quick plug for this show's sponsor, devBetter. Sponsor - devBetter Group Career Coaching for Developers If you're not advancing as quickly in your career as you'd like, you may find value in joining a semi-formal career and technical coaching program like devBetter.com. devBetter is a small group of motivated developers meeting every week or two, and staying connected in the meantime via a private Slack community. I answer questions, review code, suggest areas in which to improve, and occasionally assign homework. Interested? Learn more at devBetter.com. Show Notes / Transcript I've given the advice "if it hurts, do it more often" for years, but in preparing for this episode I did some research on the phrase to see where I might have picked it up. I found a few articles, including a nice one from Martin Fowler, which I've linked from the show notes. I'll describe my own thoughts and how I usually present the concept, and then add in some of the interesting elements Fowler and others expand upon. "If it hurts, do it more often." On its face this phrase makes no sense. Putting your hand on a hot stove hurts... so, should you do that more often? Of course not. The advice applies to business and software processes, and the implied context is that whatever "it" is, it's something that you need to do as part of your process. You'll find that a list of painful-but-necessary activities involved in shipping working software includes almost every step of building software. Compiling. Integrating. Deploying. Installing. Debugging. Testing. Pretty much all of these activities are much more difficult and painful if you try and do them rarely compared to if you do them all the time. So, if you find yourself looking at your process and making decisions in order to minimize how often you perform some necessary part of your process because it's painful, I'm going to go the other way and say do it MORE OFTEN, not less. There's a scene in the Tom Clancy story Clear and Present Danger in which Jack Ryan is in a briefing with the President, who is having to deal with some scandal involving a friend of his. The President's team are advising him to distance himself from his friend, but Jack speaks up and advises just the opposite. Instead of distancing, go the other way. If the press asks if you're friends, tell them you're LIFELONG friends. Don't give them anywhere to go with it. Everyone is aghast at this advice, but of course the president takes the advice and presumably it works out well for him. I feel just like Jack Ryan when I'm giving the counterintuitive advice of doing things more frequently despite how painful they are. It's only natural to minimize pain, and the obvious approach is avoidance. But this just increases how much pain there is when the task must, eventually be done. When you force yourself to perform part of your process more frequently, the pain decreases dramatically. There are several reasons for this. The tasks becomes more familiar, you gain proficiency, you haven't forgotten what you did last time, and there's been less time to add scope and complexity between steps. All of these natural effects of putting less time between repetitions of the task result in less pain. There are also steps that your team will almost certainly take to reduce pain, like automation. If you have a painful task you do twice a year, it's almost certainly not worth automating. The effort involved in automation will only be recovered a couple of times per year. But if you are performing that same task every month, every week, or every day it very quickly starts to make sense to automate the parts of the process that you can. And once it's automated, the pain drops dramatically. A client I work with used to have very painful deployments. They would only deploy every month or two, and doing so was always a big source of pain. Many team members would come into the office at 4am on a weekday to get ready for the deployment. The goal was to complete the deployment before customers came into the office that day. There were a lot of QA and dev team heroics. Most of the time, he deployment wouldn't be 100% successful, and often 2-3 or more additional small deployments would be required to address issues that were discovered in production. In discussing this problem, my recommendation was, wait for it, to deploy more often. Nobody really was excited by this notion, least of all the team members who were getting up at 4am for these deployment days. I decided to bet on my recommendation with data. The team didn't have a fixed deployment schedule, so there was enough variability that we could capture some statistics and draw some conclusions. I had the team start tracking the number of days since the last deployment, the number of bugs found post-deployment, and whether the deployment was successful, where success meant that it didn't need rolled back and didn't have any major problems. They captured this data, along with trying to deploy a little more frequently, for a number of months. When we reviewed the data, it was clear that there was a direct correlation between failed deployments and number of days between deployments. This made sense, especially when the team reviewed the data and saw that most of the deployments that took place within very small time windows were just fixes to deployments that had just been made earlier that week. These deployments were made during regular business hours because they weren't considered high risk! With this data backing up the recommendation, the team was ready to buy into more frequent deployments. Last year, they doubled the number of deployments they made. It's February as I'm recording this show, and this year they're looking to double that number again, which will require multiple deployments per week. Martin Fowler's article on this topic notes that many of these activities have an amount of pain that increases dramatically as a function of time between repetitions. There's an exponential increase in pain as time increases, and this is why it makes sense to increases the frequency of the task. Not all activities will necessarily have this exponential increase in pain relative to time, but if you suspect part of your process does, see if you can boost its frequency. The most obvious cause of this exponential relationship is complexity. Working with large, complex things is exponentially more difficult compared to a series of small, simple things. This is why pull requests should be small and focus on one thing. It's why methods and classes should be small and focused. And it's a reason why parts of your software process should be pipelines working on small changes rather than huge, stressful ordeals that only happen once in a blue moon. Incidentally, this same concept is one of the reasons I prefer Kanban to Scrum and other sprint-based processes, but perhaps I'll cover that in another episode. Show Resources and Links devBetter Frequency Reduces Difficulty That’s it for this week. If you want to hear more from me, go to ardalis.com/tips to sign up for a free tip in your inbox every Wednesday. I'm also streaming programming topics on twitch.tv/ardalis most Fridays at noon Eastern Time. Thank you for subscribing to Weekly Dev Tips, and I'll see you next week with another great developer tip.
undefined
Feb 11, 2019 • 8min

Better Code Reviews

Hi and welcome back to Weekly Dev Tips. I’m your host Steve Smith, aka Ardalis. This is episode 39, in which I'll talk a bit about how to make code reviews a little less painful of an experience. If you’re enjoying these tips, please leave a comment or rating in your podcast app, tell a friend about the podcast, or follow us on twitter and retweet our episode announcements. There are millions of software developers in the world; help me try to reach a few more of them with these tips. Better Code Reviews I wrote an article about a year ago about Positive Reinforcement in Code Reviews. It generated a lot of feedback (on twitter if not in the article itself), so I thought I'd dedicate a Weekly Dev Tips episode to the topic. Sponsor - devBetter Group Career Coaching for Developers If you're not advancing as quickly in your career as you'd like, you may find value in joining a semi-formal career and technical coaching program like devBetter.com. I launched devBetter a few months ago and so far we have a small group of motivated developers meeting every week or two. I answer questions, review code, suggest areas in which to improve, and occasionally assign homework. Interested? Learn more at devBetter.com. Show Notes / Transcript I remember my first internship in college working in a professional software development team. It was at a big company not too far from campus. The building was a three story rectangle. The second floor was basically a giant single room - you could see out the windows on all sides. In the middle were cubicles. Hundreds of cubicles. One of these became mine while I worked there. I was given a work computer, a bunch of 3-ring binders full of documentation, and once a week there was a code review that I participated in. I say I participated, but the internship didn't last very long and I spent most of my time fixing relatively simple bugs in C code, along with trying not to fall asleep while working through documentation binders. Thus, during the weekly code reviews, I mostly listened. These code reviews were conducted by the development manager. The week's updates were printed out and marked up by hand with questions and suggestions. From my perspective it was mostly a one-way conversation, though occasionally the more senior developers on the team would have a discussion about the code in question. The reviews weren't particularly insightful to me at the time, but the process itself stuck with me. I understood the intent of the reviews - to up the quality of the code - but the process reminded me more of getting an essay back from a professor marked up in red than of teamwork and collaboration. And the relative infrequency of the reviews meant that, more often than not, the printed updates being discussed were no longer current anyway. A fact that often resulted in discussions about whether it was worth making recommended changes at this point, due to the rework it would require. Over a decade later I found myself working at another company whose developers were required to conduct code reviews. This team's process was slightly different, in that each week a different senior developer took on the reviewer responsibility, and the reviews were done without any discussion or meeting. Once a week, whoever was in the reviewer role would go through the version control history and review all updates made in the last week (since the previous reviewer had done so). Any questions, suggestions, or changes were done in the form of TODO comments and emails, with management mandates that such requests be dealt with in a timely manner. It wasn't unusual, however, for deadline pressure to cause the review queue to build up, resulting in much more work to review or possibly in abandoning reviews for some period in order to get caught up. In both of these cases, there were two major problems with the code review process. First, it didn't happen fast enough. Frequently reviews were looking at code that was days or often more than a week old, which on projects under active development meant that the team had long since moved on by the time the review was taking place. Second, the reviews felt more like the code author was being graded or evaluated than like the team was working together. Fix this. This is a bad name. Come up with something better. You didn't follow the coding standard here. So, what can we do differently today? Here are some quick tips - apply the ones that you think will work best for you and your team. First, do code reviews as early as possible. The earliest way is by collaborating while you're writing the code. I'm a fan of using pair programming especially on mission-critical code, and if you've ever asked for a coworker to take a look at what you're doing to help you out, you understand the value having another team member participating can bring. Code reviews can certainly still be helpful even for code written by a pair, but the pair should catch a lot of problems so early that you may not even realize it. If collaborating while you code is too extreme for you or your organization, the next best thing is gated checkins. Many source control systems support this approach. My favorite at the moment is GitHub, who basically invented the idea and term pull request. A pull request is a conversation that happens about a change before it is made to the main source code branch. Teams I work with today use pull requests and reviews to ensure another team member looks over every PR before it's merged into the project's codebase. Usually the time from "hey can someone look at this PR for me" to someone actually reviewing it is under 10 minutes, because of notifications, Slack channels, and tight feedback loops. Of course, maybe you don't want code reviews to happen more often. Maybe you don't want someone to look at your beautiful code - and maybe call it ugly - right after you've declared it's perfect. Part of that might have to do with how your team reviews code. Code reviews are an opportunity not only to catch and fix problems but also to encourage and recognize the good stuff. Positive reinforcement works, and can help make code reviews less painful and thus more useful, as well as providing another way to get your coworkers to write what you think is better code. If a sincere accolade or positive message seems too cheesy for your tastes, consider easing up on the negativity by asking more questions and helping the author of the code arrive at a better solution themselves. Instead of saying "This code is a mess!" you might say "I'm having trouble understanding this code - could we work to make its intent more clear?" A related approach is to have a face to face or separate IM conversation with the author so you can have a more candid conversation that's not in front of the whole team (or company or world). As a rule it's better to offer praise in public but harsh criticism privately, and in any case it may be that you simply don't have all the information and a quick conversation will save you and the author a lot of trouble. Show Resources and Links devBetter Pair Programming Course That’s it for this week. If you want to hear more from me, go to ardalis.com/tips to sign up for a free tip in your inbox every Wednesday. I'm also streaming programming topics on twitch.tv/ardalis most Fridays at noon Eastern Time. Thank you for subscribing to Weekly Dev Tips, and we’ll see you next week with another great developer tip.
undefined
Feb 4, 2019 • 13min

How do you get so much done?

Hi and welcome back to Weekly Dev Tips. I’m your host Steve Smith, aka Ardalis. This is episode 38, in which I'll offer some personal productivity tips. If you’re enjoying these tips, please leave a comment or rating in your podcast app, tell a friend about the podcast, or follow us on twitter and retweet our episode announcements. All these things help increase the reach of this podcast, so more people can benefit from these tips. Getting stuff done Occasionally I get asked questions like this one that came from a LinkedIn connection. He wrote, "how in the world do you accomplish so much? Would love to know the strategy." I'm flattered of course, but it's not the first time someone's claimed to be impressed by how much I get done, so I thought I'd share a bit about my approach. Sponsor - devBetter Group Career Coaching for Developers If you're not advancing as quickly in your career as you'd like, you may find value in joining a semi-formal career and technical coaching program like devBetter.com. I launched devBetter a few months ago and so far we have a small group of motivated developers meeting every week or two. I answer questions, review code, suggest areas in which to improve, and occasionally assign homework. Interested? Learn more at devBetter.com. Show Notes / Transcript So, "how do I get so much done?" Let me start out by saying that I try to be pretty modest. I don't have superpowers. I'm not Bill Gates or Elon Musk, either, with billions of dollars. I don't even have online following of Scott Hanselman or Robert Martin or dozens of others. But I do alright, and I'm willing to share how that is a bit here. First, I made a realization years ago that every day I have 24 hours to utilize. No more and no less (except twice a year because of stupid daylight savings time). I used to say "I don't have time" for this or that. I'm sure I still say that sometimes, but at least in my head I try to remember that what I actually mean is "I choose not to make time" for it. It may be that you're in a position where you literally do not have control over your time, such as if you're in the military or in prison for example. But unless someone is directly controlling your freedom to choose how to spend your time, your use of time is a choice. Embrace that. Next, decide where your priorities are. What do you want out of your life? What does success look like to you. If you're a gamer, you can approach life like a strategy game. What's your strategy? Are you trying to max out income? Optimize for the best possible family? Slide through with as few commitments as possible? For me I'd say I'm following the fairly common strategy of trying to maximize my family's well-being while achieving success in my career. Within that strategy I'm focusing on entpreneurship and maximizing how many others I can help, as opposed to trying to climb as high up a corporate ladder as possible. Not having a strategy just means you're letting someone else choose your moves. Figure out what your strategy is, then figure out if the moves you're making - i.e. the way you're spending your time - is in line with what you think your strategy is. Remember, "How we spend our days is how we spend our lives." (Annie Dillard). Be sure you're spending your time wisely - it's the most precious resource you have. Ok, so that's the high level strategy side of the equation. At the tactical level, there are a few things I do that probably at least make it look like I'm being super productive. First, I minimize my commute. In the past I've had commutes of as long as an hour into work in some city where I then had the privilege of paying an obscene amount of money to park my car every day. Now, I can work from home if I choose or I have about a 10 minute country road drive to my office, which is also just a few minutes from my kids' school so it's often convenient when dropping off or picking up kids (there's no bus so driving them is one of those things my wife and I "get to" make time to do most weekdays). Not having that commute adds up. If I'm spending 10 minutes instead of 60 minutes twice a day driving, that's 100 minutes per day of bonus productivity. Think about that for a few minutes. Now, if we get self-driving cars maybe that commute time can be used productively (or if you're lucky enough to have decent public transportation). But until then I optimize for minimal time wasted on commuting. Another thing I do is minimize time spent on TV. I watch some, but pretty much only with family members as we enjoy time together, or occasionally when working out. I'm not perfect on this front, and recently I've been spending more time than I used to on video games which can suck up at least as much time as binging Netflix, but the idea is to be mindful of how much time you're spending on this and make sure you're OK with it. If you decide it's more time than you'd like to have invested in that, figure out a way to adjust. Also, if you're spending a ton of money on cable, consider dropping that cost in favor of nothing or a much cheaper Netflix or Amazon Prime subscription, which typically costs as much per year as cable with lots of channels does per month. This saves you time and money. Here's a simple, crazy idea. Typing speed. I produce a fair bit of content, between blog posts, podcasts (I script them ahead of time), writing actual code, emails with folks, social media, etc. I'm a pretty fast touch typist. I doubt that I'd set any records, but just last week at a client multiple students in my workshop were impressed by my typing speed (and asked me to slow down, which of course I did). If you want to get more done and you work at a computer keyboard all day then for the love of sanity learn to type faster! It's a skill that is relatively easy to learn and will pay off in no time. Is it the only thing that matters? Is writing software just monkey work where the bottleneck is typing? Of course not. But it 100% definitely helps and I've never once thought to myself "Boy, it sure is a useless skill to be able to type quickly. I wish I'd spent those hours learning to type watching TV instead." Something else I do that maybe you all don't is google stuff constantly. I was streaming last week and someone new hopped into the chat and was like "Oh, I thought this was someone who knew what they're doing but you keep googling basic stuff." I was slightly offended, and that's part of what you get when you watch someone streaming live as opposed to a pre-recorded course like on Pluralsight is you see how they actually work. When I'm actually working, I'm looking stuff up. All. The. Time. I'm googling stuff with my own name in the search to see my own things I've done before. I search for stuff in the ASP.NET Core docs all the time that I wrote myself but which I don't keep rattling around in my head forever. Remember there are two kinds of knowledge: things you know and things you know how to find. Knowing stuff is great. Knowing how to find stuff quickly is great, too. Of course the second one is only helpful if you use that skill, so however long you currently wait before breaking down and searching for a solution, think about reducing that and start searching sooner if you want to get more done, faster. I could go on but I need to wrap this up so we'll end with one last one which is that you need to ship. "Shipping is a feature." and "Perfect is the enemy of good." It looks like I'm productive because I'm constantly producing things. They're not perfect. They usually need work. But they're good enough to get out into the world where others can benefit from them and/or provide feedback that I can use to iterate. Don't feel like you can't start something because you don't have all the details figured out yet. Just get started. And don't wait to publish your 10 page article on your blog because it's not perfect yet. Publish the first 2 pages and call it Part 1. Hopefully at least some of that is useful to you. I'm not a fitness guru who gets up at 5, works out, never eats anything unhealthy, and only works 2 hours a day. I have 4 kids, including 4-year-old twins, and I choose to spend a lot of my time doing things with or for them. That means I need to make my remaining time count, and these are some of the ways I do that today. I'm constantly learning and trying to find ways to be more effective, though, so if you have a tip you'd like to share please leave a comment on the show at weeklydevtips.com. Show Resources and Links devBetter Take a free 1 minute typing test (Steve scored 81 WPM with 97% accuracy as an example) Recording of Steve Walking and Typing at Different Speeds for science! That’s it for this week. If you want to hear more from me, go to ardalis.com/tips to sign up for a free tip in your inbox every Wednesday. I'm also streaming programming topics on twitch.tv/ardalis now. Thank you for subscribing to Weekly Dev Tips, and we’ll see you next week with another great developer tip.
undefined
Jan 28, 2019 • 6min

Debugging Tips

Hi and welcome back to Weekly Dev Tips. I’m your host Steve Smith, aka Ardalis. This is episode 37, in which I'll talk a bit about how I debug problems I find in my code. If you’re enjoying these tips, please leave a comment or rating in your podcast app, tell a friend about the podcast, or follow us on twitter and retweet our episode announcements. All these things help increase the reach of this podcast, so more people can benefit from these tips. Debugging Tip This week's tip is by request via twitter from Bernard FitzGerald (@bernimfitz) who wrote "How about an episode devoted to effective debugging? I think that would be interesting to hear your methodology of tracking down a bug." Well, Bernard, this bug's for you. Sorry, lame beer commercial joke. On that note, here's a commercial... Sponsor - devBetter Group Career Coaching for Developers If you're not advancing as quickly in your career as you'd like, you may find value in joining a semi-formal career and technical coaching program like devBetter.com. I launched devBetter a few months ago and so far we have a small group of motivated developers meeting every week or two. I answer questions, review code, suggest areas in which to improve, and occasionally assign homework. Interested? Learn more at devBetter.com. Show Notes / Transcript Let's talk a bit about debugging. Let me start off with a couple of personal observations. First, I think debuggers are amazing. Having the ability to magically stop time in the middle of your application anywhere you want and see exactly what the state of everything is there is like a super power. It far outstrips using console output and checking a log file or terminal window for logged output like "got here" and "got here 2". Those were dark days. And second, despite how amazing they are, I almost never use the debugger. One tip I give all the time to students in my workshops is that they learn to use ctrl-F5 instead of F5 to launch their applications because it's so much faster. In my experience, 90% or more of the time you're not actually debugging when you launch your application, and in a recent experiment I ran it took about a second to launch an ASP.NET Core app without the debugger and about 10 seconds to do so with it (running on my somewhat old laptop). Those seconds add up, especially when you remember that after a few seconds you're likely to get distracted and go look at your phone or open a browser and start checking email or twitter or something. Not using the debugger helps keep you in the zone and productive. So why not use the debugger to, like, actually debug problems? I do sometimes. But more often I'll write tests. If it's my own application, I probably already have a bunch of tests. If there's some weird behavior going on and no existing test is catching it, I'll try to write a new one that fails because of the bug I'm looking for. Going through this exercise forces me to analyze what the program is doing, what classes are collaborating and how, and in general to have a better understanding of what's going on. If I can't easily write a test to isolate the issue I'm having, then I'll use the debugger. I might even debug from a test, since that's often an easy way to jump right to a particular place in my code that I know is being called with known inputs. From there I'll look at the values of all the relevant variables and arguments and usually that will identify where something isn't set the way I'd thought or assumed it was. Another approach I take is to use some kind of diagnostic tool within the app framework I'm using to provide me with as much data as possible about how the system is working. That might be using a tool like ELMAH for older ASP.NET apps, or an MVC route debugger middleware that shows me every route and how it's configured. I have some middleware for ASP.NET Core on GitHub that will format and render all of the services the application has registered. Things like this can often help provide additional context and information that can eventually help find the source of a problem. Tests aren't the only thing that helps avoid the need for a debugger. Using custom exceptions like I described in episode 7 helps make it obvious what went wrong so you don't need to debug in order to figure out that NullReferenceException. Writing short, simple methods with low complexity, perhaps with the help of Guard Clauses that I described in episode 4 is helpful, too. I actually revisited both of these topics in the previous episode, too. When your code is kept simple and small, problems are generally easily detected. If you're writing 1000 line long methods that require multiple levels of nested regions in them to be comprehensible, I can see how you might need the debugger to sort out what the heck is going on when something doesn't work. What are some other things I'm doing while troubleshooting? I'm not wasting hours focused on finding the problem mano a mano. I'm harnessing the power of a billion people on the Internet to help me. I can record another entire episode just on how to minimize how much time you waste blocked by some problem, and I've written an article on my ardalis.com site called Working Through Roadblocks - A Guide for New Programmers that goes into this as well. Show Resources and Links devBetter ELMAH ASP.NET MVC Route Debugger List all ASP.NET Core Services Working Through Roadblocks - A Guide for New Programmers That’s it for this week. If you want to hear more from me, go to ardalis.com/tips to sign up for a free tip in your inbox every Wednesday. I'm also streaming programming topics on twitch.tv/ardalis now. Thank you for subscribing to Weekly Dev Tips, and we’ll see you next week with another great developer tip.
undefined
Dec 31, 2018 • 5min

Exceptions and Guard Clauses

Hi and welcome back to Weekly Dev Tips. I’m your host Steve Smith, aka Ardalis. This is episode 36, in which we'll discuss a question I recently received about guard clauses and exceptions. If you’re enjoying these tips, please leave a comment or rating in your podcast app, tell a friend about the podcast, or follow us on twitter and retweet our episode announcements so we can increase our audience. I really appreciate it. Exceptions and Guard Clauses This week's tip is on the topic guard clauses and exceptions. Specifically, whether and when it's appropriate to throw an exception in response to certain kinds of inputs. Sponsor - devBetter Group Career Coaching for Developers If you're not advancing as quickly in your career as you'd like, you may find value in joining a semi-formal career and technical coaching program like devBetter.com. I launched devBetter a few months ago and so far we have a small group of motivated developers meeting every week or two. I answer questions, review code, suggest areas in which to improve, and occasionally assign homework. Interested? Learn more at devBetter.com. Show Notes / Transcript As a bit of background, I described Guard Clauses in Episode 4. If you're listening to these shows in most-recent-first order, I suggest you configure your podcast app to let you listen in order and then start back with episode 1. You'll thank me later. In any case, a guard clause is a check you make at the start of a function or method that throws an exception if some input is not valid. For instance, you could have a function that is supposed to send an email to an email address that's provided as a string argument. If the string is null, it might throw an ArgumentNullException or something similar before attempting to create and send the email. If you like the guard clause pattern, I have a nuget package you can use to easily add and extend them in a consistent fashion in your applications - look for the link in the show notes. Listener Jeremy C. writes: i discovered your podcast recently, and am going through it. I love the Guard class shortcut for happy path. What i noticed, is that this behavior relies exclusively on throwing exceptions rather than what I learned (20 years ago) in school that exceptions are for the unexpected, and if you can reliably prevent throwing an exception, like checking for a null and handling it, you should to avoid the execution cost of exception handling. Is my information just out-dated? :) Perhaps I'm too old of a coder and too many old habits are stuck. It's true that exceptions should not be used for control flow in your applications. That means if it's a normal condition for a function to get a null as an argument, perhaps because that situation means "create a new thing" instead of "do something with this thing", then you wouldn't want to write code that depended on an exception being thrown for its behavior. For example, you wouldn't want to have a try block that tried to work with the object, and then a catch block that caught the NullReferenceException when it was null and created a new instance there. There's plenty of reference material you can find about why this is considered a bad practice. In my opinion there are two main reasons. One is performance - exceptions are far more expensive than if statements so you shouldn't use them where an if statement is more appopriate. This is the main one, and because of it, writing code that leverages try-catch statements for something more than error handling is unexpected. Developers will be surprised to see this approach, which violates the Principle of Least Astonishment. You want readers of your code to be able to immediately understand what it's doing, and surprising them by doing things in odd ways is contrary to that goal. Coming back to guard clauses, the idea is that you're setting up an expectation that under all normal conditions in your application you expect that these arguments will follow certain constraints. If they don't, the program's simply not going to work the way it should. In this case, an exception is the appropriate response and is more elegant than any other solution like returning a boolean value or magic number or null and the caller having to know to check for that result. Thanks Jeremy for the great question! After I answered, he summed it up like this: So the Guard Clause is for the situation of, "I told you the expected inputs, and while I'll protect myself from bad data, I'm not going to make a huge mess of if statements to protect myself, I'll pass the mess back to the code giving me crap." Pretty much. Show Resources and Links devBetter Guard Clauses Principle of Least Astonishment

The AI-powered Podcast Player

Save insights by tapping your headphones, chat with episodes, discover the best highlights - and more!
App store bannerPlay store banner
Get the app