Weekly Dev Tips cover image

Weekly Dev Tips

Latest episodes

undefined
Sep 2, 2019 • 6min

Interface Segregation

Hi and welcome back to Weekly Dev Tips. I’m your host Steve Smith, aka Ardalis. This is episode 55, on the Interface Segregation principle. Interface Segregation Principle This week's tip is brought to you by devBetter.com. Sponsor - devBetter Group Career Coaching for Developers You can find help and advice all over today, from twitter to Stack Overflow to various Slack communities. These are great, but if you need more, if you need someone you can count on when you reach out for advice on code or your career, check out devBetter.com. Read the testimonials. Join risk free and see if it's for you. Not only will you learn from me, but if you stay for a while you'll grow and begin to be a mentor for others, gaining valuable confidence and experience. I've watched it happen. Show Notes / Transcript Returning back to the next SOLID principle, this week we're on the I as in Interface. Yes, it's the Interface Segregation Principle! Or ISP for short. Let's start by defining what this principle says. ISP states that no client should be forced to depend on methods it does not use. That's it. You can think of ISP as basically suggesting that you should prefer small, cohesive interfaces to large interfaces. In episode 49, which hopefully you already heard because you're listening to these in sequential order, we talked about the Single Responsibility Principle. These two principles are related! If you have classes that have only one responsibility, they're likely to expose a small, cohesive interface. That might be worth diving into a bit more. I'm guessing that when some developers, especially C# or Java developers, hear about ISP, they immediately map the word 'interface' to the interface type and keyword in these languages. That's not wrong, it's just not fully right, either. The public methods and properties a class exposes are its interface, even if it doesn't implement any interface defined separately. And ISP applies to implicit class interfaces just as much as it does to explicit interface definitions declared with the interface type. If you keep this in mind, it may make it easier to see how SRP and ISP relate, since SRP doesn't make any mention of interface types, only classes. The previous principle we discussed, Liskov Substitution, also relates to ISP. If you have a small, cohesive interface on a class, then when you decide to inherit from it you only have a few methods to worry about. If you have a massive number of methods, and your subtype is only concerned with a subset of them, it's much more likely that you won't fully implement all of the class's methods, potentially leaving some methods to throw NotImplementedException. Thus, it's easier to follow LSP if you first follow ISP. What's the point of having a smaller interface instead of a larger one, though? What's the down side to having fewer, larger classes with many methods on them? Certainly there's an argument to be made, and many have, that it makes it easier to find methods when you don't have so many different classes to search through to find them. The goal of ISP is to reduce dependency between types and especially between components in a system. The more types that depend on a particular type, the more difficult that type is to change. The more inertia it has in the system. If you have a class in your application that's used by 100 other classes, how likely are you to make major changes to its design, compared to one that you just wrote that has literally no other classes using it yet? Of course it's easier and WAY less risky to change classes that have few references to them. Let's say you want to change something fundamental about how that class that's used by 100 other classes works. One way you could do that would be to create a new instance of that class's interface or abstract base class, but then you'd have to implement all of its methods. Odds are, there are a bunch of them. That's not going to be easy - so instead you might just add some more conditional logic to some of the methods. Maybe add a few more method parameters to some methods. Maybe add a couple of new method overloads. And guess what? The problem just got bigger. The class just got bigger. The inertia just grew. By having a small interface and being focused on a small set of functionality, ISP-following classes are easier to change an easier to replace. By being small, they're easier to subtype or implement, making it easier to build systems that are modular. You find a class that has two methods and you want to change how it works in some situations? Just write a new class, implement the two methods, and swap it in where appropriate. Prefer writing new code to change legacy systems rather than modifying existing code. By following ISP, it's easier to replace classes with different variants that implement the same interface, which results in more loosely coupled and modular designs. These designs are easier to maintain and easier to test. You can learn more about ISP and the rest of the SOLID principles from my courses on Pluralsight, linked from this episode's show notes on weeklydevtips.com/episodes/55. Show Resources and Links devBetter SOLID Principles for C# Developers SOLID Principles of Object Oriented Design -and the DRY Principle Refactoring for C# Developers 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
Aug 26, 2019 • 7min

Customize Key Mappings in Visual Studio with Kendra Havens

Hi and welcome back to Weekly Dev Tips. I’m your host Steve Smith, aka Ardalis. This is episode 54, on customizing key bindings in Visual Studio with guest Kendra Havens. Customize Key Mappings with Kendra Havens This week's tip is brought to you by devBetter.com. Sponsor - devBetter Group Career Coaching for Developers Need to level up your career? Looking for a mentor or a the support of some motivated, tech-savvy peers? devBetter is a group coaching program I started last year. We meet for weekly group Q&A sessions and have an ongoing private Slack channel the rest of the week. I offer advice, networking opportunities, coding exercises, marketing and branding tips, and occasional assignments to help members improve. Interested? Check it out at devBetter.com. Show Notes / Transcript This week's guest tip is from Kendra Havens. Kendra is a program manager at Microsoft on the .NET and Visual Studio team, where she focuses on the Visual Studio testing experience and productivity tools. She does videos on .NET, VS Code, and Docker and is a frequent conference presenter as well. In fact, we last met up at a recent DevIntersection conference where we were both presenting, and I invited her to share a favorite tip on the podcast. The nature of describing a visual tool in a podcast is challenging, so I have a link to a video in the show notes if you want to follow up afterward. Welcome, Kendra! Thanks, Kendra! I'll post a link to a video showing how to do this in the show notes for anyone that wants to see it. Show Resources and Links devBetter Kendra on Twitter Visual Studio Productivity Tips - Keyboard Command Mapping 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
Jul 29, 2019 • 6min

Liskov Substitution

Hi and welcome back to Weekly Dev Tips. I’m your host Steve Smith, aka Ardalis. This is episode 53, on the Liskov Substitution principle. Liskov Substitution Principle This week's tip is brought to you by devBetter.com. Sponsor - devBetter Group Career Coaching for Developers Need to level up your career? Looking for a mentor or a the support of some motivated, tech-savvy peers? devBetter is a group coaching program I started last year. We meet for weekly group Q&A sessions and have an ongoing private Slack channel the rest of the week. I offer advice, networking opportunities, coding exercises, marketing and branding tips, and occasional assignments to help members improve. Interested? Check it out at devBetter.com. Show Notes / Transcript We're in the middle of the SOLID principles this week, with the only one who is named after an individual. The Liskov Substitution Principle is named for professor Barbara Liskov, who teaches computer science at MIT. She gave a conference keynote some years ago in which she defined substitutability in object-oriented systems, essentially stating that one type could be considered substitutable for another if there were no situations in which the original type worked but the new one did not. The typical definition used today is that subtypes should always be substitutable for their base types. If this isn't the case, it likely means you have the wrong inheritance relationship, or your interface isn't cohesive enough, or there is some other code smell you should consider addressing through refactoring. So, although it isn't mentioned in the name, LSP is all about inheritance hierarchies. That's the first thing to remember. Many developers, myself included, learned about inheritance with the aid of the IS-A relationship. That is, you can consider using inheritance to model a problem if there are two related concepts and one IS-A more specific version of the other. You might have a Car class, with an SUV subclass. Or an Animal class with a Mammal subclass. These work because an SUV is a car and a mammal is an animal. Sometimes, though, you might have an IS-A relationship, but it's not sufficient and it leads you down the wrong OO design path. The classic geometry examples involve squares and rectangles and circles and ellipses. A square is a rectangle; a circle is an ellipse. But take care if you try and use inheritance to model them, since depending on how you do so you could introduce breaking changes into your application. Imagine if you have applications using your Rectangle type that assume they can independently set the height and width of the rectangle. Then someone introduces the Square type that inherits from Rectangle and implements height and width properties so that setting either one will set the other, too. This ensure the resulting type is always a square. But it also means that a method that takes in a rectangle and modifies its height and width to different values will break, because the first value set will be silently overwritten by the second. Another classic example involves birds. What if your base bird type includes methods like Fly and properties like Altitude? Then, someone introduces subtypes for Ostrich and Penguin. Trying to substitute these in to methods that expect certain behaviors from Fly and Altitude is likely to cause problems. The problem here is that the initial assumption that all birds can fly was inherently flawed. In business software, we don't usually worry about birds or squares, but we often model things like policies, accounts, orders, etc. and often there are different varieties of these concepts. You'll know when you're violating LSP when you see code that shouldn't care about the specific variety of something, but has to run a type check to do its work properly. A method takes in an Account, and then checks to see if Account Is PremiumAccount, for instance. This signals an LSP violation, and can usually be corrected with a refactoring that shifts behavior up or down the inheritance tree. Pretty much the only place where you might have a conditional on the specific type of an instance of a class is in a factory method that's responsible for creating that specific type. Otherwise, the Replace Conditional with Polymorphism refactoring is your friend. Use it to eliminate excessive conditional logic from your code by making proper use of inheritance in your object model. Obviously examples of these principles are tougher to describe in a podcast than in video, so to see them in action check out my courses on Pluralsight on the SOLID principles. I just produced a revised course for 2019, but my original SOLID principles of object-oriented design course is out there as well and uses different examples, so you might get benefit from seeing both of them. You'll find links to both in this episode's show notes. Show Resources and Links devBetter SOLID Principles for C# Developers SOLID Principles of Object Oriented Design -and the DRY Principle Refactoring Fundamentals 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
Jul 22, 2019 • 7min

Continuous Testing Continuously with Guest Al Rodriguez

Hi and welcome back to Weekly Dev Tips. I’m your host Steve Smith, aka Ardalis. This is episode 52, on feedback loops and continuous testing with guest Al Rodriguez. Continuous Testing Continuously This week's tip is brought to you by devBetter.com. Sponsor - devBetter Group Career Coaching for Developers Need to level up your career? Looking for a mentor or a the support of some motivated, tech-savvy peers? devBetter is a group coaching program I started last year. We meet for weekly group Q&A sessions and have an ongoing private Slack channel the rest of the week. I offer advice, networking opportunities, coding exercises, marketing and branding tips, and occasional assignments to help members improve. Interested? Check it out at devBetter.com. Show Notes / Transcript This week's tip is on how to be more productive by reducing feedback loops. Our guest is Al Rodriguez. Al is a multiclassing wizard spending most of his time using .NET wherever possible but levels up in other tools to get the job done. Take it away, Al: Hi. I'm Al Rodriguez and I'm here to talk to you about Continuous Testing. One way to improve development productivity is to reduce the time of your feedback loop. A classic example of this is application startup time to validate a UI change. A 3 minute wait for an application to build and startup feels like an eternity when you've only changed a background color. This is why some tools exist to hot reload only the part of the application that has changed. Thus reducing the time that you, a busy developer, have to wait. We see tools like this all over the development space to reduce the feedback loop time. One example is inside our Text Editors. If you miss a semicolon or misspell a variable name, you immediately get feedback in the form of a red squiggly underline. Another example of this is a Continuous Integration pipeline. Once you check code in, a pipeline is invoked to build your application, run any tests it needs to, and alert the team if there are any issues. All three of these examples I've mentioned have wildly different feedback times because they're for very different types of tasks. But lets move on and talk about unit tests. The common loop I see when working with unit tests is to write the test, then click the button to run it. It's a very manual process. The feedback loop there is usually a couple of seconds. Short and sweet. As time goes on you'll change some code and eventually click the button to run the tests again. But which tests? All of them? One class at a time? The individual tests you think are impacted by your changes? Even worse, what happens if you forget to run the tests? Now you're checking code into source control that hasn't been fully tested. What does the feedback loop look like in that situation? Best case scenario, the tests are run after a few changes are made. Worst case scenario, they're not even run. And that's just you. There's also the scenario of people on your team who don't think to run the tests. On a project with historically low, or no, tests, the idea of running them doesn't cross your mind because it's not part of the normal flow. So new code could have broken the tests, and since they weren't run, no one will find out for a what may be a few weeks. That's fun and all. But you know what's better? What can reduce that feedback loop? What you said is right, sure, but the answer I was looking for is: Not clicking the button. Or more accurately, not having to click the button. Having a tool that will run your tests for you. Continuous Testing is when you have a tool to run your tests as soon as the they are created, changed, or any code impacted by a test has been changed. And if that's not continuous, I don't know what is. Which would be a problem. So if that's not what Continuous means, please let me know. I can't have another situation where I go years using a word wrong. That would be unfortuitous. Other benefits of Continuous Testing tools include a UI element to show the current state of the code under test. For example, when looking at your code there is a visual indicator inside your IDE to show you each line of code that has any failing tests, or if there are no tests for that line. Which is a great reminder that you need to write those tests. If you want to get started with Continuous Testing there are several options depending on your choice of tooling. In the .NET space you can use the Live Testing feature built-in to Visual Studio Enterprise. If you don't have an Enterprise license, another great tool is NCrunch. You can only get NCrunch by purchasing a license, but it's cheaper than upgrading to Visual Studio Enterprise. Which is the reason I use it for my own personal projects. Finally, if you're working with .NET Core you can use the dotnet CLI command: dotnet watch test The watch command listens for file changes. Once a file has changed, the test command is run on that folder. Note that this isn't as efficient as the previous tools because it re-runs all of the tests, not just the ones that have related changes. If you're in the javascript realm you can do something similar with npm's watch package. Using the command npm run test --watch will continually run your test task whenever files change just like we saw with dotnet. In summary, do what you can to reduce your feedback loop with automated tests. And that's all I have to say on this topic. If you'd like, you can find me on twitter under the handle @ProgrammerAl, that's P-R-O-G-R-A-M-M-E-R-A-L. Or you can find me interviewing people on their side projects on the Developer Side Quests podcast. Now go forth and forget where that Run Tests button is. Or even better, remove it from your IDE if that's an option. Thanks for letting me ramble on your show Steve. Back to you! Thanks, Al! Great tips! It's great that CLI tools make it so easy to set up this continuous feedback loop, even for developers who don't have access to great commercial tools like VS Enterprise and NCrunch. I hope a few listeners will give continuous testing a try, and if they have any questions or feedback, leave it on the show's page at weeklydevtips.com/episodes/52. I've also added links to the resources covered this week. Show Resources and Links devBetter NCrunch Al on Twitter 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
Jun 10, 2019 • 5min

Open Closed

Hi and welcome back to Weekly Dev Tips. I’m your host Steve Smith, aka Ardalis. This is episode 51, on the Open/Closed principle. Open/Closed Principle This week's tip is brought to you by devBetter.com. Sponsor - devBetter Group Career Coaching for Developers Need to level up your career? Looking for a mentor or a the support of some motivated, tech-savvy peers? devBetter is a group coaching program I started last year. We meet for weekly group Q&A sessions and have an ongoing private Slack channel the rest of the week. I offer advice, networking opportunities, coding exercises, marketing and branding tips, and occasional assignments to help members improve. Interested? Check it out at devBetter.com. Show Notes / Transcript My goal is to have every other tip for the next few weeks focus on one of the SOLID principles. If you're listening in order, which I recommend, you'll note that episode 49 was on Single Responsibility. Thus, here we are with episode 51, talking about the O in SOLID, the Open/Closed Principle. The name of this principle is somewhat oxymoronic. It sometimes reminds me of the classic Star Wars scene where the stormtroopers are chasing Han Solo, yelling "close the blast doors, close the blast doors!" only to find themselves blocked by the doors moments later, crying "open the blast doors, open the blast doors!" What does the principle of being both open and closed mean, really? The full principle says that software entities (no, not those entities - we mean classes, modules, functions, etc. here) should be open for extension but closed for modification. Ok, so what does each of these mean? Open for extension means that it's possible to add to the behavior of the class or method. We can make it do new or different things. Closed for modification means that the class or method itself should not be changed. Imagine that it's inside of a nuget package or its source is otherwise unavailable to modify. If we think about open for extension all by itself, it's a pretty easy one. It's saying some class or method should be open to changes in how it works. We do that all the time. We need to fix a bug or add a feature, we find where the code is that does that work, and we add a few lines to change the behavior. Often this just means adding an if statement or something similar, to account for the new behavior required. This is the typical, obvious way to add behavior to our systems, and generally there's nothing wrong with this approach. But it doesn't follow the open/closed principle, because such code is clearly not closed for modification. Now imagine that the code with the behavior you need to modify is not available to you to edit. How might you change its behavior, then? This might sound like a trick or impossible question, but we do this all the time, too. You change the behavior of classes and functions by changing their inputs. Passing in arguments or modifying data accessed by the class or method, such as configuration files or data stores, are all examples of ways in which you can modify system behavior without modifying source code. And there are some parts of your application that will benefit from being closed to modification, especially the parts that are depended on the most. By following OCP for your most fundamental classes, you'll make changes to them far more rare, which in turn will result in far fewer issues downstream due to updates to them. If you'd like to learn more about OCP, check out my courses on Pluralsight on the SOLID principles. I just produced a revised course for 2019, but my original SOLID principles of object-oriented design course is out there as well and uses different examples, so you might get benefit from seeing both of them. You'll find links to both in this episode's show notes. Show Resources and Links devBetter SOLID Principles for C# Developers SOLID Principles of Object Oriented Design -and the DRY Principle Refactoring Fundamentals 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
Jun 3, 2019 • 7min

Test All The Things with Guest Corey Weathers

Hi and welcome back to Weekly Dev Tips. I’m your host Steve Smith, aka Ardalis. This is episode 50 with some guest tips on Testing All The Things! Test All The Things This week's tip is brought to you by devBetter.com. 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 I'm glad to have a new guest offering some tips. Corey Weathers of Twilio is going to offer his perspective on the importance of software testing. Corey loves .NET and has worked for companies including Microsoft and the US federal government before joining Twilio as a developer evangelist. He works to inspire and equip .NET developer, underrepresented developers, and the Twitch community of developers with the tools they need to build the future of communications. Welcome, Corey! My name is Corey Weathers and I have the privilege and pleasure of being a .NET developer evangelist for a great company named Twilio. I’d like to start this week by saying a big thank you to Steve for inviting me on the Weekly Dev Tips podcast. This week I’d like to talk about something very near and dear to my heart as a developer – software testing. WHY TEST Now you may be wondering why testing. After being a developer for a number of years, I have found the following things to happen pretty consistently – someone usually has a problem and says “hey a developer can fix that”. Hopefully they’ve checked in with a software developer before making that assumption, but that’s not often the case. It’s usually problems like these that turn into use cases, user stories, or requirements. As product development happens, it can also be the case that these stories become more specific, nuanced, and refined in scope. When that happens, it’s not unusual to see more user stories created to cover the new scope that was removed from existing stories. What you end up with is one problem that a developer can fix turning into an ever-expanding list of user stories that become very complicated. Now when we start writing the code for one use case, and more show up, we continue writing more and more code to meet the ever expanding list of requirements and after this, we miss the opportunities to validate the code that we’re building. WHAT DOES TESTING DO So one of the first mantras to remember here is – TEST EARLY. Why? Because when you start early, you get to check one box that is super important – that is, you’re making sure that you’re building the right thing. This allows you to clarify your assumptions and confirm the suspicions you may have but that haven’t already been identified and figured out. Which leads me to the second mantra – TEST OFTEN. If Test Early ensures that you’re building the right thing, Test Often makes sure that you’re building the thing right. By making your code testable, you’ve added so much to your code base: maintainability, a measure of quality, and confidence in that things will work as you’ve both built and expected them to. WHERE DO I START At this point you may be wondering, ok well where do I start? And I realize a number of you may be coming from different starting points. Some of you may be at the very beginning and haven’t written a single line of code; whereas others of you may have an application deploying into a production environment that has poor test coverage. I know that it can be tough to get started. Hopefully this piece of advice should be relevant for you no matter where you’re starting from. My third and final mantra is START SIMPLE Let’s use an example here. For our conversation – let’s assume we have an application that has a user interface, and this user interfaces connects to an API that takes some data and saves it in a database. Assuming everything works as expected, you can start by writing a test for each part of this sequence. So one test can reproduce what happens when you click on the button when rendering the UI; a second test can simulate what happens when the UI calls the API; a third test can confirm that the database actually saved the data; and a final test can simulate all of the steps here by testing this one action with an API and database that looks close to what it will be in the real world. We could probably have an entire conversation as well about making sure you test setting up your application, but if you’re just getting started with testing there’s no need to start there. WHAT DO I DO WITH ALL OF THE TESTS With this suite of tests, you now have 4 tests that you can very easily expand on. You’ve started by testing the simplest path forward and can now add different modifications to this path, like what happens when my computer isn’t connected to the internet and my UI can’t talk to the API. Now here’s where we reach the inevitable – well if I’m just starting out with writing tests and something doesn’t pass as I expect it to, what do I do? Here is where I usually say – this is a good thing. Your test is starting to work. Think about it for a second. If you start writing tests and they start making you ask questions about how your test is working, then you’ll probably end up changing your test a bit so that this question focuses more on your application. This is a win because you’ll learn how to write better tests in the process. Alternatively, if you start writing tests and they make you question how your application is working, this is a win because it’s forcing you to make sure your application is meeting its intended need AND is testable as it is doing so. So write more tests, look for their results, and respond when the results don’t match what you expect. CALL TO ACTION That’s it from me this week friends. Remember TEST EARLY, TEST OFTEN, AND START SIMPLE. If you are interested in following up on testing, take a look at the Art of Unit Testing, written by Roy Osherove. He’s built an amazing body of content to help describe some of the why and how to begin testing. If you’d like to follow up with me, feel free to email me at corey@twilio.com. That’s C-O-R-E-Y@T-W-I-L-I-O.COM. That’s it from me this week. I’ll pass it back to Steve. Great stuff, Corey! Thanks for sharing with everyone. Art of Unit Testing is definitely a good book - I'll post a link in the show notes. Show Resources and Links devBetter Art of Unit Testing by Roy Osherove 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
May 20, 2019 • 6min

Single Responsibility Principle

Hi and welcome back to Weekly Dev Tips. I’m your host Steve Smith, aka Ardalis. This is episode 49 on the Single Responsibility Principle. Single Responsibility This week's tip is brought to you by devBetter.com. 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 The Single Responsibility Principle, or SRP, is the S in the SOLID principles macronym. The short version of it is that a class should have only one reason to change. Specifically, the reason referred to here is tied to the application's requirements. Each class should only be required to change in response to a single change in the application's requirements. These requirements typically correspond to real world things. For example, let's say the application needs to display a report for quarterly sales performance. The system's requirements might be that the report be rendered in a browser, that it include all sales for a given quarter grouped by individual sales representative. Either of these requirements might change in the future. Perhaps the reports need to be emailed as PDFs. Perhaps they need to be calculated monthly instead of quarterly or rolled up by sales region. Ideally, the format of the report and the details of how it is calculated should be separate responsibilities of separate classes. Why is SRP important? Back in episode 15, Maintain Legacy Code with New Code, I explain one reason. Every time you change a class, you risk breaking classes that work with it. When a class has multiple responsibilities, it will likely need to change more often. Also, it's likely these responsibilities will be tightly coupled together by the class, making it harder to change them independently and further increasing the inherent risk of changing them. Let's say you have to fix a bug in an application. Would you rather have to work in a single class that literally only does the thing that has the bug in it, or would you prefer to work in a 2000 line long class that does 10 different things, all of which are intermixed in the class's 50 methods and properties? I know which one I prefer. Too often, developers new to SOLID will hear about SRP and misunderstand a bit what a responsibility really is. They might have a class they've carved out from the rest of the application. Something like CustomerManager. They'll happily explain how CustomerManager is only responsible for Customers in the application, and thus is following SRP. But upon reviewing the code, it's clear that CustomerManager is responsible for Customer validation, Customer persistence, and Customer formatting for various user interfaces. It's responsible for notifying Customers when they place orders and oh yeah, it also is responsible for Customers placing orders, as well as managing their orders and their payment providers and their account history. But don't worry - CustomerManager only has one responsibility: Customers! Although I said responsibilities typically map to business requirements, they don't typically map to entities like customers or orders or policies. This is because these entities will often have a lot of rich behavior that can be isolated into separate responsibilities, often with cross-cutting concerns within the application. For instance, how a customer is validated will likely be very similar to how an order is validated. The same goes for persistence and UI formatting and a host of other activities. Each of these is a responsibility, and should be isolated in its own class. Now, it might seem like breaking up big classes into small ones is going to result in a lot more code, but often just the opposite occurs. As you pull cross-cutting concerns like validation, persistence, logging, notifications, formatting, etc. into their own classes, you'll often find ways to standardize the codebase and reuse these classes. A common way to achieve this reuse is through the strategy pattern, which I discuss in episode episode 19. The Strategy pattern lets you move responsibilities out of a class by delegating to other classes, which are often defined as fields or properties on the original class. These fields or properties have their instances set by having them passed in through the constructor, in what's commonly called dependency injection. Dependency injection and the strategy design pattern go hand-in-hand, and are my favorite way to refactor to achieve SRP in classes that I find have too many responsibilities. If you'd like to learn more about SRP and SOLID, check out my newly revised course, SOLID Principles for C# Developers, on Pluralsight. It's a complete update of my original SOLID Principles of Object Oriented Design course that has been in the top 100 for Pluralsight since it was published in 2010. The new one is shorter and streamlined, though it doesn't cover some topics the original course has. The new course also uses Visual Studio 2019 and has all of its course samples on GitHub. Check both of them out and let me know what you think. Show Resources and Links devBetter SOLID Principles for C# Developers SOLID Principles of Object Oriented Design -and the DRY Principle Refactoring Fundamentals 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
May 13, 2019 • 7min

Effective Ways to Accelerate Your Career

Hi and welcome back to Weekly Dev Tips. I’m your host Steve Smith, aka Ardalis. This is episode 48 on Effective Ways to Accelerate Your Career, with guest James Hickey. Effective Ways to Accelerate Your Career This week's tip is brought to you by devBetter.com. 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's tip is brought to you by guest James Hickey. James is a software developer working remotely in eastern Canada. James helps software developers gain traction in their careers with his free email newsletter, "Navigating Your Software Development Career", which I link to in the show notes. He's also the author of an open source .NET Core library called Coravel, which provides advanced capabilities to web applications. James is going to share some tips on accelerating your career. Welcome to Weekly Dev Tips, James! Hi! I'm James Hickey. I'm a senior .NET developer and consultant based in eastern Canada. I'm also the author of an open source .NET Core library you might be familiar with called Coravel. One of the big realizations I had early on in my career was that doing a good job and doing what I was told to do would actually not lead to: Promotions, recognition, becoming really skilled at my craft, and opening up more opportunities. Many developers find themselves comfortable with having an easy and carefree job with minimal responsibilities. Other developers, like myself, have an inner drive, ambition, and passion to be the best that we can be. We recognize that having options means we can support our families better, have more money and resources to help our friends when in need, have the ability to create new businesses that solve important problems in our world, and know that we can inspire others to conquer obstacles in their own lives. Are you one of these developers? Here are some tips for you to accelerate a bit faster in your career! Find Gaps Here's my first tip. Early in my own career, there were times when I would solve a problem and developers who were more senior than I would ask, "How did you that?" One example was when I worked on a large database migration project. My colleagues were building various scripts that could take days to run. When I started building my own scripts, I started using regular expressions in SQL to fetch certain patterns in the data, manipulate it and then store the results. My solutions were taking mere hours to run! I became known as the guy who could migrate these large data sets very well. The senior developers would start coming to me for advice whenever they needed help in this area. Have you ever solved a problem and then been asked questions like these? "How did you do that?" "What did you do there?" "Why did you do that?" This probably indicates that you've found a knowledge or skills gap in your team. You should jump all over that topic and become the "go to" person. You might think that being known as the "regular expression guy" is not that useful. But that's not what people will think. In reality, you will be viewed as someone who can think outside the box. You will be viewed as someone who can solve tough problems. So, when promotion time comes along, guess who will be already on the minds of the decision makers? Connecting With Past Co-workers Here's tip number 2. If you've been in the field for a few years and have worked for a few different companies, then this next tip is for you. One thing I started doing is contacting past co-workers and managers on LinkedIn. First, I will ask them how they are doing. Next, I'll let them know - in a couple sentences - what I've been up to recently. And finally, I'll let them know that I am available to chat with them and help them with anything they need. This is a short and concise way to connect with them on a personal level and let them know that you are just there to help them in any way. Don't expect to be told immediately that your past co-workers have something they need help with. (Although that has happened to me, and I've landed some big opportunities this way.) The main point is to merely put it in the minds of these people that you are available. When they move on to another company and are looking to hire software developers, guess who's going to come to mind first? If you have a history of doing good work and being friendly and helpful to your co-workers, then you will be surprised where this simple tactic can lead! Teaching Have you noticed that the vast majority of the tech leaders you follow have either done public speaking, written books or recorded video tutorials? My final tip will really accelerate your career: teach other developers in public. Start speaking and presenting at user groups, meetups or even conferences. Start writing technical blog articles that address very specific issues developers are facing in their day-to-day work. You could even write a book which can skyrocket your credibility. Or, you could begin recording video tutorials that help developers learn to build software better, use their tools more effectively, and so forth. At the end of the day, simply helping people by teaching them to be better than they were yesterday will always win. Thanks! I hope you found these tips practical and useful! Thanks for letting me steal your thunder for a few minutes, Steve! No problem, Jmaes. Thanks for the great tips. Listeners, I hope you'll sign up for James' newsletter to get more career-oriented tips from James in your inbox. Show Resources and Links devBetter Find James Online 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
May 6, 2019 • 7min

Introducing SOLID Principles

Hi and welcome back to Weekly Dev Tips. I’m your host Steve Smith, aka Ardalis. This is episode 47, in which we'll introduce the SOLID principles. I'll spend a little time reviewing these principles in the upcoming episodes. What are the SOLID principles of object-oriented design? 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 Depending on how long you've been programming, you may have heard of the SOLID principles. These are a set of 5 principles that have been around for several decades, and about 15 years ago someone - I think it was Michael Feathers - had the idea to arrange them in such a way that they formed the macronym SOLID. Prior to that, I think the first time they were all published together was in Robert C. Martin's 2003 book, Agile Software Development: Principles, Patterns, and Practices in which their sequence spelled SOLDI - so close! This same sequence was used in the 2006 book Agile Principles, Patterns, and Practices in C#. So what are the SOLID principles? As I mentioned, SOLID is a macronym, meaning it is an acronym formed by other acronyms. In this case, these are SRP, OCP, LSP, ISP, and DIP. All those Ps at the end of each acronym stand for principle, of course. Listing each principle, we have: Single Responsibility Open/Closed Liskov Substitution Interface Segregation Dependency Inversion You may already be familiar with these principles. If you're a developer who's using a strongly typed language like C# or Java, you should be extremely familiar with them. If you're not, I recommend digging into them more deeply. Applying them can make a massive difference in the quality of code you write. How do I define quality? Well, that's probably a topic I could devote an episode to, but the short version is that quality code is code that is easy to understand and easy to change to suit new requirements. It's easily and quickly tested by automated tests, which reduces the need for expensive manual testing. And it's loosely coupled to infrastructure concerns like databases or files. How do these principles help you to write quality code? They provide guidance. You need to write code that solves a problem, first and foremost. But once you have code that does that, before you call it done and check it in, you should evaluate its design and see if it makes sense to spend a few moments cleaning anything up. Back in Episode 6 - you are listening to these in sequential, not reverse, order, right? - I talked about Kent Beck's approach of Make It Work, Make It Right, Make It Fast. SOLID principles should generally be applied during the Make It Right step. Don't apply them up front, but as I discussed in Episode 10, follow Pain Driven Development. If you try to apply every principle to every part of your codebase from the start, you'll end up with extremely abstract code that could do anything but actually does nothing. Don't do that. Instead, build the code you need to solve the problem at hand, and then evaluate whether that code has any major code smells like I discussed in episode 30. One huge code smell is code that is hard to unit test, meaning it's hard to write an automated test that can just test your code, without any external infrastructure or dependencies like databases, files, or web servers. Code that is easy to unit test is generally easy to change, and code that has tests is also easier to refactor because when you're done you'll have some degree of confidence that you haven't broken anything. In upcoming episodes, I'll drill into each principle a bit more. I've published two courses on SOLID at Pluralsight where you can obviously learn a lot more and see real code as opposed to just hearing me through a podcast. The first one was published in 2010 and so the tools and look were a bit dated. The more recent one is slimmed down and uses the latest version of Visual Studio and .NET Core. There are links to both courses in the show notes - the original one also covers the Don't Repeat Yourself principle. Let me wrap this episode up with a very brief overview of each principle. The Single Responsibility Principle is generally applied to classes and suggests that classes should have only one responsibility, which can also be thought of as one reason to change. Responsibilities include things like business logic, ui logic, data access, and more. Following this principle, you'll tend to have smaller, more focused classes. The Open/Closed Principle suggests that you should be able to change the behavior of your system without changing its source code. This generally relies on some kind of parameter or plug-in capability to provide new behavior to an existing class or service. The Liskov Substitution Principle cautions against creating inheritance hierarchies in which child types are not 100% substitutable for their base types. When violated, this can result in messy code and bugs. The Interface Segregation Principle suggests that classes that use interfaces should use all or most of the interface's exposed members. This then leads to interfaces that are small, focused, and cohesive, much like SRP. Finally, the Dependency Inversion Principle recommends that low-level concerns depend on high level concerns, not the other way around. This means for example that business layer code shouldn't directly depend on data access code, but rather an abstraction should exist that the business code works with and that the data access code implements. At runtime, the data access code will be provided as an implementation of the interface the business code is written to work with, providing loose coupling and more testable code. Show Resources and Links devBetter SOLID Principles for C# on Pluralsight Refactoring Fundamentals on Pluralsight SOLID Principles of Object Oriented Design on Pluralsight (published in 2010) Agile Software Development: Principles, Patterns, and Practices on Amazon Agile Principles, Patterns, and Practices in C# on Amazon 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
Apr 15, 2019 • 9min

On Sleep with Guest Jamie Taylor

Hi and welcome back to Weekly Dev Tips. I’m your host Steve Smith, aka Ardalis. This is episode 46, with guest Jamie Taylor, aka GaProgMan. On The Importance of Sleep 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's tip comes to us from the UK, where fellow podcast host Jamie Taylor lives. He has a great tip that will help improve your health and productivity. Take it away, Jamie! Hello everyone, I'm Jamie "GaProgMan" Taylor, I'm the host of The .NET Core Podcast, and Steve has graciously agreed to let me share a tip with you all. My plan isn't to talk to you about .NET Core or even development, per se, but I might use them as a background for what I do want to talk about: and that's finding the time to relax and getting enough sleep. We work in a very fast paced industry, it seems like the technology space is constantly evolving. The breakneck pace of our industry can seem overwhelming to most of us, especially if you want to keep up with the latest innovations. I know that I've been guilty, in the past, of saying something like: the moment that you stop learning, you're already a day behind Which, other than being hyperbole, is a bit of a double edged sword. On the one hand, it's a great idea to keep to speed with what's going on; but on the other hand, you need down time. Now I don't care how long you can sit at your laptop, coding into the wee hours of the morning, drinking coffee, Red Bull, Mountain Dew, or whatever your incredibly sugary caffeinated drink of choice is. Eventually, you are going to need some rest and relaxation. And rest is the most important thing. Your body, whether you are aware of it or not, can go for days without food - it would be tough, but it's doable. But you cannot go for days without resting. To quote one UC Berkley article on the subject: As little as one night without sleep is enough to turn a reasonable person into "emotional Jell-O," says Matthew Walker, director of Berkeley’s Sleep and Neuroimaging Laboratory source: https://alumni.berkeley.edu/california-magazine/march-april-2008-mind-matters/your-brain-without-sleep The brain is the most important part of the body for a developer. Without it, we can't function (if you'll pardon the pun). We need the ability to deal with complex business logic, hold several layers of the application's design in our short term memory, and to be able to parse customer requirements. Without a healthy, well rested brain you can't do any of this. In the words of John Silva (host of National Geographic Channel's "Brain Games"): One of the things that happens when you're sleep-deprived is that your ability to regulate emotions goes haywire. Your brain becomes disorganised in its capacity to process information and your sensitivity to information also get scrambled. Regulating emotions is an incredibly important skill to have, and becoming disorganised is quite possibly the antithesis of the state of mind that a developer needs to be in. You need to be able to focus on the task at hand. "But I'm an extremely well motivated go-getter, Jamie. I really don't care." Eventually you are either going to crash and burn, or you're going to need the help of a team of doctors, and possibly a hospital. When you don't rest, you're not just affecting you're physical health, but you're also putting your mental health at risk. Without sleep, you'll be unable to put your thoughts in order, which means that you won't be able to communicate with others, which will lead to you becoming agitated, and that will lead to stress. And stress (or more correctly, "distress") can wreak havoc on your body. We're talking headaches, increased blood pressure, chest pain, heart problems, skin conditions, depression, and anxiety to say the least. So what can we do? Firstly, get up and walk away from your computer. Maybe not, right now. But the next time you get a chance to do so: do it. Take a walk, preferably outside; and if you really must have a coffee, walk to the next coffee shop along - the extra time in the fresh air will really help you. Spend time away from a computer of phone screen, as little as 15 minutes for every 45 will really help. Walk over to the water cooler and have a chat with someone while you get a cup of water. And if you don't have a water cooler, figure out another place to go and to be social - some companies have breakout rooms for this purpose. But what about outside of work? It's so easy to get trapped in a cycle of: Wake up Commute to work Only leave the desk to go to the bathroom or get lunch Commute home Spend all evening working on some personal projects, or staring at your phone So let's use the Japanese idea of Kaizen (which means "improvement") to break that, little by little. I've taken up running in an evening (well, it's more like jogging, because I'm so out of shape). I'll occasionally call my brother and talk with him about everything and nothing, or we'll talk about video games for hours. I attend a number of meetups which are not even remotely to technology related. By spending time away from computer screens and talking to folks, I've found that I feel more balanced, and rested. Remember: we're social beings. But the number one, most important thing, is sleep. And that can be hard to achieve when you're so used to sitting in front of a bright screen for hours. Our brains are tuned to think that bright light equals day time, so when we're surrounded by unnatural, bright lights, we tend to stay awake for longer. Which is why it's sometimes hard to sleep if you end up using a computer, tablet, or mobile phone before you go to bed. Fixing this is super easy: just don't spend all day and night sitting in front of a bright screen. Give yourself a cut off point, say 30 minutes before bed, and don't use a computer, tablet or phone during that period. But if you have to use your computer or phone during that window, know that the white light emitted by these screens contains harsh blue hues, which will make your brain think that it's day time. So just don't use them. Or, if you have to use them, look for apps similar to f.lux, or Red Moon if you're an Android user, or if you use iOS devices then you can use a combination of NightShift and True Tone. What About You Jamie? I occasionally get insomnia, and when it strikes I have a number of ways to rest even when I can't seem to sleep. The very first thing that I do is make myself a cup of chamomile tea. I've always found that it chills me out, and it can really help me to rest. This might not work for everyone, but the combination of a hot drink without caffeine before bed really helps me. You know how some people like to have a cup of hot cocoa before bed? It's the same thing. Then I try to focus on not ruminating on anything - this is the medical term for when you can't sleep because you're thinking about that bug you've been trying to recreate for 3 days. It's hard to do make these thoughts just go away, but just try to put it out of your mind. Thinking about things like this when you're meant to be sleeping isn't going to help you sleep. Trust me. The next thing that I do - and this isn't going to be to everyone's tastes, so feel free to skip over this one - is I practise mindfulness meditation. It sounds unintuitive, but focusing my attention on the breath seems to really help me to relax, which helps lead to me feeling super tired. Again, this isn't going to be to everyone's tastes. I also subscribe to a number of podcasts specifically designed to help me sleep (obviously, Weekly Dev Tips is not one of these podcasts). I used to do this with audio books, especially technical books where the reader doesn't really emphasise any particular parts of the story, but I've since found a number of podcasts which are designed to help you sleep. Sleep With Me is one of my favourite ones. I simply start an episode playing through my phone (at a low volume obviously), lay in bed and close my eyes. Some people that I've talked to about this have said that the sound white noise, or the sound of rainfall can produce a similar effect. In Summary You need to find a way to get rest which works for you. After all, you need good quality rest in order to be productive, NOT the other way around. You cannot be productive without being well rested, and no matter which way you look at it, developers need to be productive. One last thing before I go: take a look into circadian rhythm (I've probably mispronounced that completely). The tl;dr (or too long; didn't read) is that we have a certain number of states when we sleep: light sleep, deep sleep, and REM sleep. The deeper your sleeping state is when you wake up, the more groggy you'll feel when you do wake up. There are apps that you can get which will attempt to measure which sleep cycle you are in, and try to wake you while in a light sleep cycle as your alarm time approaches. This can leave you feeling less groggy, and less like you need that first cup of coffee in the morning. Now, I'd like for you all to get some good quality rest. And thank you Steve for allowing me to share this tip with everyone. Thanks, Jamie! Show Resources and Links devBetter Your Brain Without Sleep Sleep With Me podcast Circadian rhythm 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.

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