Tuesday, September 28, 2021

Pragmatic Programmer : Chapter 5 - Bend, or Break

 This is one of the chapters in the book that causes it to be a bit slower. There’s a lot of concepts and obvious pieces to this chapter for an experienced developer, but they’re good for newer developers and ideas to be reminded of.

  1. Decoupling- Anyone who has worked on an older, tightly coupled project knows how difficult refactoring significant components out can be. The best option is to never get to into the trap of having the rigid structure. It takes practice and an occasional glance at your dependency diagrams. The idea of asking versus telling is a concept that I also need to work on myself, I've had a pattern of asking, and I need to get away from that.
    Additionally, wrapping things into an API, like global variables, is something that seems obvious, but I don't see many developers willing to do.
  2. Juggling the Real World - We get a set of four strategies that help with event driven development. The book continues to talk about different states and how to handle in those scenarios. I think its a great introduction to the observer pattern and pubsub, but wish there was more detail to it. The problem is that this book doesn't go into super fine details like the implementation of that. It gives you a jumping off point.
  3. Transforming Programming - The basic idea is that we often overcomplicate things. We should be trying to reduce how we think of our methods as input and output. The architecture in the way we do it is just another tool in how we can handle the different objects and methods. 
  4. Inheritance Tax - Interfaces, Delegation and Mixings/traits are key pieces to avoiding the Inheritance Tax. I believe that the use of polymorphism is important, and so do the authors. Creating a protocol with the interface allows a separation of concern, and allows you to program against the interface.
  5. Configuration - The older I get, the more I love configuration. Historically, I used to set a lot of variables in configuration files. I abstracted those into its own class so I could write automated tests against them. Then it hit me, for most of them, I can hit the database on application start to populate them, or potentially refresh the variables without having to do a code deployment. And today, I take advantage of Key Vault -  It allows so much in terms of flexible behavior in your code that you don't realize until you have a mature application.

Wednesday, September 22, 2021

Pragmatic Programmer : Chapter 4 - Pragmatic Paranoia

Development is hard. You can do everything right, and according to spec, how the client wants, and still have it be wrong. Designs and requirements change. You rely on third parties, and other people's tools. The reality is no one is on their own and has to do the best that they can, with what they can. How we go about doing that is a set of strategies on their own.

  1. Design by Contract - The idea of design by contract seems almost common sense when we say it, but often we find that we don't do that.  Breaking down our tasks into specific methods, with contracts and pulling out any sort of set up or validation for the method is an excellent approach. It makes the code clear and concise.  How you get there will depend on your situation. Can your framework handle something like pre and post processing? How about Guards? It is important to apply what you can when you can.
  2. Dead Programs Tell No Lies - A poorly named chapter, I believe this goes to my idea of exceptions are for exceptional situations. The message here is that you do not want to corrupt or compromise the results of your application. Crashing it will prevent problems from happening further down the line.
    For example, if I wrote a method that calculates the total cost of an item (item cost + sales tax), and failed to calculate the sales tax, I should just throw the exception. Just returning the item cost will cause problems down the line. Fail early and don't mislead your users.
  3. Assertive Programming - There are times in our code base where we can get into a situation that we know we shouldn't be in. For example, if in our system we only enter in authors once they have a book, and a query that retrieves the books by said author doesn't have anything, we know there's a problem and can detect the error.
    How you handle said assertions is important, but it should not cause an internal exception. It should be logged and the development team should be notified.
  4. How to Balance Resources - This is a problem that many developers run into early on. Proof of concepts are built, and don't reveal resource cleanup. Closing a connection to a database, locking a record, closing a stream to a file all should be handled in the code. Do not wait for garbage collection to do this for you. What happens if garbage collection isn't called? What happens if that record in the database isn't released? 
    It causes problems down the line for others once you get some sort of significant load on your system.
  5. Don't Outrun your Headlights -We've all been on projects with high aspirations. It will change the entire organization! But first, File -> New. It is important to be realistic with your expectations of the application, but the ambition is good too! It helps motivate the developers.
    The problem becomes that projects change. Technologies and demands change. Management changes and so do demands. One of the best thing about the agile process is it takes away ultra long term goals and makes the more immediate become the focus. Do what you need to get done, and nothing more. If work wasn't part of your commitment, don't spend time on it just yet.

Pragmatic Programmer : Chapter 3 - The Basic Tools

 I started my coding days by doing HTML in notepad. I had a WYSIWYG, but the reality is it wasn't coding. I didn't understand what it was really doing. Once I started being able to code HTML myself, I had so much of a better understanding of why a WYSIWYG was built the way it did, and what kind of features I should expect.  So I was writing the mark up, but the WYSIWYG editor was a tool. Great for some things, but not the best for others. 

Tools make our lives easier and make our workflow better. What we can automate, we should. How we automate different tasks can vary by need, environment, output, etc. But one thing is clear - as we add more tools to our toolbelt, we become more powerful.

  1. The Power of Plain Text - Plain text is amazing. I understand it, and so do you. I've always said that the best code is the code that a junior developer can go in, and make sense of. This goes for data as well. If something is easy to understand, it is going to be easier to troubleshoot and use in the future.
  2. Shell Games - Recently, I started using PowerShell and the Azure CLI for some Infrastructure as code maintenance tasks. It makes things so much easier to automate. I don't have to log into the portal, click around and risk breaking something. Instead, I can just call my script with a few parameters and I'm all set.
    As I work with more systems, PowerShell will become incredibly beneficial to me. While there is a learning curve, once you get it, you've got it.
  3. Power Editing  - Becoming Fluent in your editor is so important. I program mostly in C# and use ReSharper. There are so many keyboard commands and shortcuts that I've already forgotten more than the average developer has ever learned. I keep the keymap up at my workstation and try to highlight specific ones that I am trying to learn. And because I use the IntelliJ mappings, when I work in IntelliJ for a Java project, I already know a lot of those mappings.
    The key thing is, I'm more efficient with this in my coding environment, so it saves time and money.
  4. Version Control - Everything is under version control. This is something I'm trying to do. I set up private repositories on GitHub for some of my projects. No one needs to see them, but I can always refer to them.  I intend to make more reusable libraries that I can take advantage of things I've coded in the past. Perhaps I turn these into packages.
    Point is, by keeping everything, and showing how you got to its current state is incredibly valuable. It shows your progress with the application and as a developer. The part I struggle with is things like contacts, memos and communications - That may be overkill. There's probably better tools for such a thing.
  5. Debugging - Debugging could have a chapter by itself. It has a good amount of content, but there's so much there to help developers solve problems. They should be used. They need to be practiced. Learn how to use breakpoints, conditional break points, logging. I personally want to learn how to read more memory dumps.
    Perhaps the biggest piece that was mentioned in this section was "Don't assume it- Prove It". I agree with this but I have a few different ways of saying this. I prefer the saying of, "It isn't that I think you're lying, it is just that I don't believe you." Users don't give great details in their reports and many times they're inaccurate. It is always best to not trust the user (in more ways than one).
  6. Text Manipulation - I don't know any text manipulation languages. I see how they can be valuable for sure though. I worked on a project that was basically managing different XML files, and there were constantly times where I had written an entire C# application to manipulate XML files into some other type of data. Again, anything that can be automated should.
  7. Engineering Daybooks - Daybooks are awesome and help me so much. They remind me how we got from A to D, who was in meetings, and different architecture ideas from discussions. I've found that it helps to take the notes from a meeting, and then share them with the team via email to make sure everyone is on the same page and that your notes are accurate.
    Taking notes is a skill though. Putting a word down in the corner to look into means nothing if you can't comprehend it. I think this is also something that we could go into more detail down the road.

Wednesday, September 15, 2021

Pragmatic Programmer : Chapter 2 - A Pragmatic Approach

 The Pragmatic Approach talks about the steps for architecting and planning how to do your development. At times these chapters can seem like a hodgepodge of subjects, but when you consider all of these steps before you start developing, they can be some of the most basic and important steps in development. 

Setting the pace and expectations are key for getting the business and development team in line together, so by these simple steps, the teams can function optimally.

  1. The Essence of Good Design - Good design is easier to change than bad design. It sounds so simple, so why don't I think about it more? This is a great way to present to people a way to handle the design of their code and libraries. I should be able to swap out different layers and UIs and not have to worry much about the behavior of unrelated pieces being impacted. 
    In the past, I always used the idea of Automated Unit Tests for keeping abstraction in place, but this is an even better ground rule of handling things that I want to use in the future.
  2. DRY - The Evils of Duplication - Duplication is inevitable when you work on teams. Sometimes people have things out there that you're unaware of, sometimes someone copies and pastes code repeatedly into the codebase - these are things we need to work at preventing.
    The part I found very interesting is that the idea that documentation itself is a form of duplication. It makes sense and I never thought about it that way. It almost feels like if we can auto-generate as much of our documentation as possible, that we could greatly reduce the duplication. 
    This is a new idea to me that I'm going to spend a lot of time thinking about going forward in my development career, and come up with different ways of not having the same information in my documentation and my codebase.
  3. Orthogonality - We're drifting into the idea of the Single Responsibility Principal of Solid Design. I love the analogy of the helicopter levers impacting each other.
    There's a lot of good strategies for handling orthogonality, and it even talks about the singleton pattern which can lend itself to its own challenges. 
    This comes down to small, focused pieces of code. Know what it is doing and have it do just that. If a client can have multiple accounts, those functions need to be separated. If an address can belong to a client and a customer, then they must be separated. If a mailing address can be international or internal, they must be separated. They're going to have different functionalities with different requirements, like postage or customs. Changing postage shouldn't impact internal mail. 
  4. Reversibility - Reversibility and having a flexible architecture is more and more important as technology advances. Containerization is drastically showing that, and abstracting away as much as you can is going to be critical for your codebase. You may have some infrastructure code, data access code, business logic - be prepared for it all to change dramatically.  Make no mistake, this is all about abstraction. 
  5. Tracer Bullets - I use tracer bullets without even thinking about it. Recently with the different variations of .Net Core, and the .Net Framework, its very easy to get confused with libraries and what can reference what. I work with older assemblies and I tie into new pieces that run on linux based machines. Making sure everything can communicate, getting those basic lines of communication in place are critical. 
    Building your project framework, showing the integration, and getting those basic pieces down early are absolutely critical to not having to go back in 6 months and change the foundation.
  6. Prototypes and Post-it Notes - I'm very hesitant to do any sort of prototype in any technical tool. They always seem to end up being used in production or how they were not intended. The business does not care about architecture, just that something is working right now.
    That's why I love the idea of wireframes, post it notes, Power Point presentations and mock ups. They communicate quickly the idea of how something should behave, and they cannot be deployed.
  7. Domain Languages - I don't have a ton of experience with Domain Languages in terms of planning. I've used Given When Then statements, and SQL, but often times, I feel in the planning stages, they can become overwhelming. I'd like to get some more experience with these and understand their benefits a bit more.
  8. Estimating - If naming things is the hardest thing in development, estimating may be number two. Estimating different tasks and  when things will be completed requires so much and often you don't have enough to formulate a proper estimate. You can add in caveats and assumptions, but when those are wrong, and you miss your deadlines, it is my experience that you will pay. The time for estimates, and post-mortems would be better spent ironing out what needs to be done, and actually developing.
    Now that isn't to say all estimation is bad. After all, effort must be distributed appropriately to get the best bang for your buck! I do like the idea of tracking your estimates, and keeping track of how long you spend on different tasks. But again, time consuming.
    I also love the idea of regularly updating the schedule with the code. Being able to accurately project when something is done has value, but things change so fast and frequent, projecting more than a couple of months in advance doesn't seem greatly beneficial to me.

Monday, September 13, 2021

Pragmatic Programmer : Chapter 1 - A Pragmatic Philosophy

Your attitude towards your work makes things very different. Do you have a job or a career? Pragmatic Programmer reminds you that it is a career. Your attitude and behavior shapes your career, setting you up for being a better developer long term.
  1. It's Your Life - I've seen a lot of developers just throw their hands up in the air and not even attempt to make things better. It can be as simple as just getting a nicer mouse for their own desktop. There's a sense of entitlement among many developers, that everything needs to be handed to them in terms of training, or their work environment. That's a shame.

    Take control of your ability to complete your responsibilities, even if that means investing in yourself. The idea of "You Have Agency" is a great way of looking at things and separates craftsmen from workers.
  2. The Cat Ate My Source Code -We all make mistakes. We all find others' mistakes. Ownership of your work, and the mistakes that have been made really changes the attitude and tone of your team. Reaching out for help, alerting others to those mistakes early is key. Perhaps things can be adjusted to still meet the goals. However, when you do make a mistake, do whatever you need to to resolve said mistake. If you need to come up with a list of options to do so, put in extra time, do it. Document it. Be an example of someone you want to work with.
  3. Software Entropy - When I first read this book, I thought this idea was garbage, but the idea really is true. I now recognize this is a bigger picture item.  Bugs need to be documented, and incomplete pieces need to be shown in the code. Finding the right ways of doing that can be difficult though. Fix what you can, when you can.
    When things are broke, you may not be able to fix right away. If you can, go for it. But you need to make others aware of it. It can result in extra testing and requirements gathering. Things didn't get to their current state by accident and there's probably a reason that the problem exists. 
    Just make sure you're going in the right direction.
  4. Stone Soup and Boiled Frogs - Being a catalyst for change can be difficult. Rocking the boat really can upset people who are resistant to change and don't want to do things differently.
    Making those changes is difficult and takes practice. There's always a lot of different factors involved including time, resources, money and long term vision. You may not always be successful, but maybe you can combine ideas with someone else to make things just 1% better.
  5. Good-Enough Software -  The best line of software is one that is not written. I use different libraries all the time, and those bring in bugs. I use other team's NuGet Packages and thus, I can inherit defects from that. It goes on and on. 
    The point is, we have resources available and sometimes the requirements aren't as strict as we come to believe. If the 40 hours it takes to add a feature saves users a total of 10 minutes a year, maybe it isn't worth it. Do the right things from the beginning like Automated Unit Testing, and Continuous Integration where it makes sense.
  6. Your Knowledge Portfolio - Having different tools, different ways of solving problems, knowing about how others solve their problems is huge. I believe that learning things takes a long time, and takes a lot of effort. I'm no longer in college where I can stay up three nights in a row studying and absorb everything I studied. By doing things regularly, and in different ways, you become a well rounded developer with a variety of ways that you can solve problems.
  7. Communicate! - I wish I paid more attention to this earlier in my career. Some of the best training I got in the last 5 years was how to write an email. This chapter reminds me that we're in an age of different generations, and that comes with different communication styles. More experienced technical people may want to talk through something to communicate an idea. I'm a huge fan of a wall of text in an email (that people don't seem to read), while developers fresh out of college seem to lean towards visuals like charts, and videos on things. These are tools, that have their own benefits and flaws. Use all of them, not just one. Pick the right one not just for the context, but your audience.
    Additionally, the idea of code comments being documentation violating the DRY principal is something I had not considered. I've gone all over with my comments in code from being too verbose to non existent. This is something I think deserves to be explored in a deeper sense. 

Pragmatic Programmer : Your Journey to Mastery

I recently was in a meeting where I was reminded of the idea that exceptions should be used for exceptional cases. I thought it was in Pragmatic Programmer, but I've purchased and loaned this book out so many times that I could not find my copy. I talked to another developer about these exceptions, and mentioned the book. They genuinely seemed interested, and I wanted to revisit the book since I was overdue. So I bought the hard cover 20th anniversary edition, and it will not be loaned out. I rather buy one for someone than lose my copy again.

This has been the most beneficial book to my career. I've read it multiple times, and feel called out by it regularly. It refreshes me on keeping focus on my career, and being a better developer. Very quickly, you learn that it isn't just who knows the code the best being a valuable team member, but who can maintain the code, communicate, work together, solve problems and come up with long term strategies. There's minimal code in it, and they're more about strategies to solving the different challenges that come with development.

This is an excellent book, that I recommend for anyone with over a year of development experience. I've decided to make my own cheat notes to come back to from time to time as I read this book. I'm also happy to discuss any of these concepts and ideas. My notes can be found with the Pragmatic Programmer tag. 

Monday, April 10, 2017

Copping Mechanisms - Sleep

Ed Wisniowski wrote a blog post on coping with the difficulties of being a scrum master. He talks about some steps that he takes to keep his professional life from taking over, working with others, and sleeping patterns. It is true that he's got a position that demands a thick skin, and people skills are essential for success.

Perhaps the most unique part of what he's talked about in our industry is the sleep. Anyone will tell you that their job is difficult because of how it can take over, or the individuals they work with. But the sleep portion is something that is quite a bit different at times. Ed's strategy involves making sure he has that uninterrupted sleep. Like Ed, I've interacted with offshore teams. I've skimped out on sleep, or tried to split it into multiple chunks. I may not get the 8 hours I need, but I can get 5 hours here, and 3 later, that counts, right? It doesn't work.

The benefits of sleep cannot be understated. When you're not getting quality sleep, the quality of your life suffers. You're going to get sick, your brain will not function as well, you will be cranky - you get my point. I can remember multiple times where I would show up at work exhausted and unable to solve problems. At the same time, I remember accomplishing surprising tasks in part to being well rested. The sleep also impacts how I interact with others. If I was up late working on an issue, and someone attempts to exchange a pleasant greeting- well, it may not get a great response from me.

I encourage people to get sleep. I encourage them to turn off and escape from the workplace that can be toxic when people give exceeding attention toward it. I have seen people become the "all knowing" individual of a system, and had their vacations interrupted. I've seen people depart from positions because of their schedule. Know your limits. Know where to draw a line, and be proactive in providing options to prevent this from happening. You need to be flexible, yes. But you also need to protect your own sanity.