From Legacy Code To STATE OF THE ART DEVELOPMENT

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
state-of-the-art in software development approach is continuous delivery it's widely practiced by some of the most effective software companies in the world and it's a goal for many more continuous delivery works better than any other approach that we know of so far but to operate at the limits that can be achieved one of the tools part of the answer is software architecture not very surprisingly really that software that's designed to be testable and Deployable through automation is more easily testable and Deployable through automation the trouble is that this is not where most organizations start so what does it take to make continuous delivery work in less than ideal circumstances how do you go about adopting continuous delivery for pre-existing Legacy code bases [Music] hi I'm Dave Farley of continuous delivery welcome to my channel if you haven't been here before please do hit subscribe and if you enjoy the content today hit like as well when I talk about continuous delivery I often use examples from projects that I worked on of course this is true because I know those projects best and so I can talk about them in more detail if necessary and with a bit more Authority because I can be sure that what I'm saying is factually correct because I was there the project that I go to most often for these examples is lmax where we built one of the world's highest performance Financial exchanges applying the principles of continuous delivery from day one it was a big success and still today when I describe how we worked and what we did I know that it sounds too idealistic to be true to some people but it is true but this is in part because continuous delivery is a pervasive holistic approach to software development it sounds idealistic because we were starting from a blank sheet meaning that we were able to avoid many of the common constraints that organizations typically impose on themselves continuous delivery is complex to adopt because it's holistic it changes How We Do nearly everything so inevitably the easiest place to start is before you've got anything to undo or to compromise over but how many times do you get to start something completely from new like that not often for most of us so in most organizations the real world of continuous delivery adoption is nearly always more complicated than this completely different from this ideal blank sheet starting point lmax was like a clean room experiment in what was possible so it's a great example of what's possible but most teams don't start from there most teams have pre-existing team structures and processes most have an established development culture and most have pre-existing systems so our big beginning aim from a much more complex starting point usually with less tractable software and organizations who are if you'll forgive me stuck in a rut and not realizing what's possible with different thinking I think that what we're really talking about here is genuinely a paradigm shift continuous delivery is a change in perspective on what software development is and how it works once you've made that shift figuring out how to solve problems in your organization is easier but it's never easy to shift between paradigms in the first place there were Newtonian physicists at the start of the 20th century who were horrified by the implications of Einstein's ideas and arguing against them Galileo was executed for disturbing people's worldview by suggesting that the Earth orbited the sun rather than the other way around people find it hard to change their minds even when they're wrong I can't cover all of this in a short YouTube video but let's look at some of the practicalities of dealing with Legacy code bases in continuous delivery and leave the organizational changes and that sort of stuff for another day perhaps before we do that let me say thank you to our sponsors we're fortunate to be sponsored by equal experts trisentis transfig and Roost all of these companies offer products and services that are well aligned with the topics that we discuss on this channel every week so if you are looking for excellence in continuous delivery and software engineering click on the links in the description below and check them out there are lots of anti-patterns here that can make Legacy code bases problematic in a continuous delivery context let's consider a few an approaches to addressing them perhaps the first thing to think about here is how we tend to think of legacy I think that most of us think of some kind of Burden that we've inherited from others when we think of Legacy in the context of software but the other part of a legacy is that this is something of real value in most cases even if they are problematic in some way Legacy systems are important maybe even vital to the companies that operate them so whatever we need to do to make them nicer more traptable places to work we need to do that with some care and with the aim of keeping the lights on as we make any changes I've already made an assumption here that is that we want to make changes the easiest kind of Legacy system to deal with is one that doesn't need to change at all after all when was the last time you bothered updating the or tcpip implementation knowingly but in most cases not changing things is a pretty risky strategy in most cases the business environments in which our systems operate changes and the technical environment changes too things like new security holes are discovered in our older infrastructure that mean that we must update or run the risk of attack retaining the ability to change things is important not just at the technical level I remember reading an article many years ago about a system used by the Federal Aviation Administration in the United States which was written decades before for some ancient Mainframe they wanted to update it but they'd lost the code worse than that they'd lost the code for the compiler for the language that the system was written into now that's a pretty big Legacy problem so for most systems we need to be able to retain the ability to change things thinking about how your legacy system changes is a very good idea the big problem with any Legacy system in general but certainly in a continuous delivery context is the cost of that change the amount of effort involved in making any changes and maybe even more so the effort involved in making sure that we haven't broken anything in the course of changing things in continuous delivery these two ideas are deeply intertwined we can't really sensibly treat them separately but for now let's look at them separately why is Legacy code hard to change well regular viewers will be getting rather tired of me by now repeating this list but it's because we didn't manage the complexity of the system either when we built it originally or when we maintained it later on this is usually problematic at two different levels the code is messy and hard to reason about and because the code is messy and hard to reason about people stopped trying so over time it's become randomly and highly coupled to other systems and Technologies as well as being messy and hard to reason about we need to stabilize this I won't say fix it because you probably won't get to fix the problems like these completely without completely rewriting the whole system from scratch which though a compelling idea is not always the best choice after all what's the stuff are you making the same sets of mistakes again in the rewrite sometimes rewrite is a good call but it isn't a simple solution or an Easy Choice ever so it pays to be a little skeptical of your motives and honest about the challenges that you will probably face and the advantages that you may gain if you aren't rewriting then how do you approach moving your legacy system to working continuous delivery there's a misconception that continuous delivery only works for small pieces of code in order to do continuous delivery we must divide the work into small micro services this is simply not true and dividing the work up into separate independent Services can be the wrong thing to do improving the modularity of the system is important we must do that modularity does not though equal micro Services there are other easier routes to effective modularity so don't start out assuming that the best way to fix your legacy system is to turn it into a micro services-based system this is a very complex move and you need better reasons to do it than microservices are cool and Legacy systems are hurried I should look to address this change in three parts we want to be able to stabilize things organize our work better and exploit this stable more stable more organized system if our Legacy systems are hard to change because we didn't manage the complexity we need to start managing the complexity what most organizations would like is to automate more of the release process when they look at other companies doing well they effective automated testing is one obvious place thing to Aspire to most Legacy systems don't have good automated tests in fact that's how Michael feathers defines Legacy systems systems without automated tests so we need to add automated tests true but maybe not in the way that most people think I would strongly advise against attempting to retrofit fine-grained unit testing to Legacy code test driven development is important to me for a variety of reasons but primarily because of the impact it has on my design choices it gives me fast feedback on the quality of my design as I'm making design decisions which I value very highly but it's too late for that in a legacy system because you've already made lots of the design choices and presumably you now regret some of them or you wouldn't be calling your system a legacy system at this point you're looking for something different from automated tests so you probably want different kinds of automated tests you're really looking for two things more confidence that new changes do what we think they're doing and confidence that you're safe to release the system as a whole after you've changed it so I recommend four separate strategies first refactoring you need to work to change your legacy system to make it safer and easier place to work strategically it will be nice to decouple your system from others if your database is written to by random external systems it will be very nice to isolate and normalize these these communications but this can be very difficult to achieve by all means do it if you can but if you can't the general the more General route to improving things sounds a lot more tactical than fixing this big ticket item and it is but it's also more practical and may lead you to the point where you can address the more strategic problems later the foundation of this tactical approach is to build up skills and adopt the discipline of continual pervasive approach to refactoring adopts the rule that you will always leave the code in a slightly better state after every single commit tidy the code in the area that you are working use approval tests sometimes called characterization tests to protect you from damaging changes an approval test records the interactions with the system and saves the recording the next time that you run the test it compares the results with the stored results if anything's changed the test fails these tests prove that your refactoring is true refactoring that is that your change preserves the behavior of the system I plan to do a more detailed episode on approval testing let me know if you in the comments if you'd like to see that what you should be doing with your refactoring is working to make the code easier to change in this you're starting to exert better control over the complexity of the system I have a refactoring tutorial where I demonstrate some refactoring techniques in a bad piece of code under the perception of approval testing you can find a link to the to that in the description below too refactor to improve modularity cohesion separation of concerns abstraction and to reduce coupling in the areas that you're working on don't aim for wide scale General improvements avoid the temptation of some Grand improve everything project instead improve things more tactically use techniques like approval testing and refactoring to start building anti-corruption layers between the the code that you want to change and the rest of the system that you don't have time to change at the moment your goal is to allow yourself the freedom to make change safely in small steps in the places where change matters now and to leave the other parts of the code for another day a day when you've got real need for or a reason to change that bit this strategy doesn't directly address the unpleasant coupling to with external systems but it will position you to tackle this more easily when the time's right refactoring is the most important tool in the box when dealing with Legacy systems so grow your skills in this area the next big ticket item to work on is speed of feedback Legacy systems wouldn't be a problem to deal with if we knew straight away when we broke something the reason why these systems are nasty to work on is precisely because we can't tell when we've broken things so the next tool in the toolbox is to start optimizing things to improve the speed and quality of feedback that we can get from our systems we need to improve the visibility into our system so what does this mean feedback and continuous delivery is pervasive we always prefer faster feedback but it takes effort it's an investment in our own efficiency as a team our aim is to fail fast if we've done something wrong we want to detect that as early as we can optimize build systems use good refactoring Ides that will highlight errors in your code as you're typing and that will give you tools that help you to fix it optimize build systems to build your system faster use modern incremental build systems and they can help you to build even vast software projects quickly work to eliminate circular dependencies in builds I once worked with a client whose normal build process was to run the build seven times because the first six would produce broken software because of circular dependencies this was simply a waste of time effort and money every time they built their system adopt a policy of low or even better zero tolerance for such waste when you find a problem like this fix it even if it's expensive to fix in terms of time try to find ways to introduce continuous integration this may sound like a rather extravagant place to start for a legacy system and it is so adopt continuous integration tactically adopt continuous integration for the parts of the system that you change often and that are hidden from the rest of your legacy system via your anti-corruption layers that you worked on earlier this brings us the next of our four foundational ideas testing as I said one definition of legacy system that I like a lot is a system without automated tests because if it had automated tests we'd have much better feedback and much more confidence when we change things right as I've already said I don't recommend attempting to retrofit unit tests as a strategy instead focus on testing for release ability primarily with Legacy systems the best place to start with this is to start automating what you're already doing for a release and adopt the more modern approaches to continuous testing in the areas of the code where you're changing them I use acceptance tests whole system functional tests carried out in a production-like test environment to help to stabilize the release process this is a slightly extravagant claim but if you get this right for roughly the cost in time of one maybe two manual release test Cycles you can automate it all once you've automated it you can start running the test continuously so you get great feedback at the level of am I ready to release all of the time what this takes is a smart approach to separating test cases from how the system works my course on acceptance test driven development Behavior driven development describes this approach in detail there's a link in the description to that too as I said if you get this right the tests them themselves are easy to write and are built on reusable test infrastructure to make them fast to get them working too working to reduce and ultimately eliminate dependencies on manual regression testing is the goal here speed of feedback into the development process is the real Target the need to stabilize all of this will be driven by our need to test and that brings us to deployment if we're writing these kinds of acceptance tests we need to be able to reliably deploy versions of our system to test we need to control the variables and get our system into exactly the state we needed to be in for each test that means controlling the setup of our tests in the test environment isolating tests so that the data that they're changing is only visible to the individual test that it's relevant to and being able to deploy the system repeatably and reliably and ideally quickly so deployment Automation and effective configuration management is another important area to focus on here if you can use modern infrastructure as code tools maybe run your legacy application in containers or automate the deployment with one of the popular deployment tools if you can't do either of those automate it yourself with Version Control scripts and configuration management but it must be automated your goal is a one-click deployment no options no press y to confirm and you're probably going to need to your automated deploy system to support two different use cases a clean deployment from scratch for provisioning largely used to support your automated tests and an update that keeps the data that's already there to support production releases there is of course a lot more to all of this than I can cover in a single short YouTube video I've called out some of my training courses and other resources that I think might help you but I would also strongly recommend Michael feather's book working with Legacy code for anyone that finds themselves in this situation thank you very much for watching and if you enjoy my stuff please do consider supporting our work on this channel by joining our patreon community thank you thank you [Music]
Info
Channel: Continuous Delivery
Views: 22,082
Rating: undefined out of 5
Keywords: legacy code, legacy code base, legacy systems, refactoring, upgrading legacy code, continuous delivery, cicd, cd, legacy code vs continuous delivery, computer science, software engineering, software development, Dave Farley, refactoring legacy code
Id: _gs3MjJBEfs
Channel Id: undefined
Length: 20min 4sec (1204 seconds)
Published: Wed Mar 22 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.