Strangling the Legacy out of an Application
CC Attribution - NonCommercial - ShareAlike 3.0 Unported:
You are free to use, adapt and copy, distribute and transmit the work or content in adapted or unchanged form for any legal and non-commercial purpose as long as the work is attributed to the author in the manner specified by the author or licensor and the work or content is shared also in adapted form only under the conditions of this
Abel, Anders
A ten year old system with a basic architecture from a distant past (.NET 1.0? VB6?). New functionality built throughout the years with the then state of the art technology. On top of that some cosmetics to make the web interface look modern, but in reality the application is rotten on the inside and about to fall apart any day. That’s a common work environment for many developers. But there is a way to get out of it without funding for a complete rewrite. Anders shares his experiences on strangling, a method where a new architecture is built in and around the existing code based, gradually replacing the old rotten code with a shiny new architecture.
 So, welcome. I thought sometimes I think that I'm the only one working with legacy applications, but apparently not. I'm happy you're here. I thought I'd start with some, you know, this is nature. Fresh air, sun, have you heard of it? Okay, well, this is Norway, so it's rain all the time, isn't it? Remember my parents bringing me to vacations in Norway when I was a kid and I said, never more. It was rain, it was cold. Next year we went to Greece instead. So I'm Anders Sjabel. I'm a developer and working as a consultant at a company called Kantoor in Stockholm, part of the telecom computing group. And I've been coding since I was nine and I've written quite a bit of code that was bad code and I hope I've written some good code. I'll say that throughout the talk, if you have any questions, just raise your hand. We'll take them as they come and I'll also save some time at the end for questions and discussions because I think I've got about 1% of the experience of legacy code in this room. 99% is you. So, at the end, I'm happy to have a bit of a discussion. But first looking back, were you all at the keynote? Then Luke talked about the future or rather the time that already is here, but a lot of companies are struggling to understand that time. But do you remember this? This is Visual Basic 6. Forrest designer, code. And this picture, it ends in 98 and going forward. I remember this was actually the first conference I went to. It was a presentation from Microsoft of the new distributed intranetwork architecture where we moved from one tier to tier to tier and it would be so much better. At that time, I believed in it. I'm a bit more seasoned now and I think that the next big thing, it will be the latest and greatest until the next big things come. But back then, I really believed in it. One here that has been working in this kind of context. Do you like it? Just laughs. Well, we'll make a slide detour first and talk about gardening, actually. In our garden at home, we have not that nice old pine tree. It works. It provides the functionality it's supposed to. It provides shade, but the architecture of this application, sorry, tree, I don't like pine trees. I'm thinking of a beautiful big oak instead. So I go have a chat with the garden government or boss, that is my wife. And I say that I think that wouldn't it be better with a large oak here instead of this pine tree? And she says, yes, it would. And you know what? I take that for a yes. So I go ahead, I bring my chainsaw. No more pine tree. I bring this small oak tree instead I get and I plant it and I'm happy. It has this new nice architecture. It's an oak tree. Well it might not be as big as the pine tree, but eventually it will. I imagine just in 20 years, this will be a magnificent tree. And imagine in 100 years when my kids are really old sitting there watching their grand kids play under this magnificent oak, it will be great. So of course I'm happy, I'm proud, I go get my wife. She's not happy. Actually I showed this line to my wife and she said, hey, you can't show that to the devs. They all think I'm stupid. I wouldn't let you bring the chainsaw in the first place. Actually often I showed this line, I can't find my chainsaw anymore. Just disappeared. Well, you're all offing. But I think that this is what we often do as engineers. We have this old application that provides a functionality. It's ugly. It's a pine tree. And we walk to the boss and say, we should rebuild this. Look, we can have this beautiful oak. But then somewhere along the way we prioritize the architecture and the technology and we lose track of the functionality. You won't get much shade out of this. Actually when I prepared these lines about a couple of weeks ago, but then when I was planning my trip here, I checked the timetable for the commuter train to Stockholm to get to the airport. And they had this brand new site. With the boots strappy-based, nice, clean design. But the favorite functionality that I use the site most for to find when there are shutdowns of traffic, I can't find it anymore. That functionality was somehow lost. So what I'm going to talk about today is how to transfer the pine tree to the oak without having to go through the chainsaw moment. But first I would like to look a bit about the business perspective because I know, how many here are developers? Rightly coded. Okay. Anyone who is a boss or manager or responsible for a budget? Okay. Good. No add. So when we have an idea, we of course know that we should replace this crappy O-lock architecture and code. But to do that, we need funding. At least I'm not working for free. I prefer if someone pay my salary, which means someone needs to provide funding. The business drivers for doing anything is either new functionality or that the current maintenance of the application is too expensive. Because roughly the only two things that you will ever be able to use as an argument against your boss to get funding for anything. So well, it comes to an end. They often try to postpone this as long as possible. But in the end, they have to fund a rewrite of the system. And well, what do they do once they've decided that a rewrite is needed? They put a no change policy on the legacy system. And that can last for a long time. I mean, it can last for several years if it's a large project. And then at the end, you have a big bang release where every single change feature that you bring into the rewritten system is an increased risk. This one remedy that is often used in rewrite projects to handle this risk and reduce risk, is to make it one-to-one rewrite. Well imagine for a moment that you are actually managers, I know you're devs, but imagine you're managers and I'm a developer, I'm a sole developer here, I'm trying to sell this rewrite to you. And you know what? If you fund this rewrite, you'll get no new functionality. And it's a one-to-one rewrite to reduce risk. So when we are done, you will have the same sheet to use the interface and the same sheet to functionality. Okay, anyone want to fund my rewrite? But I know some of you are thinking now that, well, at least it's better code because you're developers. So you're thinking it's better code. So while there is some gains by rewriting anyways, but let me tell you, this is one-to-one conversion. So when we're done with the rewrite, we will have the same sheet to architecture. But then we can start working with a new platform, new language to improve. Well this is not a very good way, I think, to do a rewrite. Let's look at a popular methodology for movement for development, agile. That's really mainstream nowadays. What does agile learn to us? What we can learn is that we should reduce risk by using agreements. We shouldn't have a big bang release. And that goes with the same for rewrites or changing applications. We should have early and continued user interaction. And any software development effort should be an evolution, not a revolution. So that brings us into the topic of today, strangling. So if your boss is unwilling to find and bring out the money needed for that complete rewrite, you can use a very fictive means called strangling. Sorry, wrong. I wasn't supposed to show that one. My boss said I wasn't allowed. Well, let's move on to the other strangling. This is a plant. There's a lot of trees in this presentation. I was looking for images for this presentation. There's so many beautiful images of strangler vines out there. Just type it in on Google and try. This is a strangler vine. It's an old tree here. And then this one is using the old tree to grow. It seats itself in the crown of the old tree. And then it roots down to the bottom while still being high up in the air and having access to the sun. The patent strangler application was named by Marthifala after he had visited a forest with strangler vines. So what we do with an application when strangling it is that we start building a new separate application besides the old one. A new separate one with a new architecture just like this trunk. It's in its own trunk. It has some connections to the old application here. But it's an own trunk. We add more and more functionality, more and more trunks. They start to grow together. And eventually we have got rid of the old application, the old legacy code. I think this picture is just beautiful. But this was more of a business section of the talk. So let's look at cost-value comparison. Because when you show this to managers, there's always this question about cost and value. We'll try to go through it quite quickly. First to the left, we have a complete rewrite with a big bang release, which means that we are investing. The blue field here is the cost, the money spent. The orange field is the value gained from the effort. We start rewriting. We're spending a lot of time rewriting until the cut-over date here. And we are accumulating cost. But we are not only accumulating cost, we're actually getting negative value. Because once we have started with the rewrite, there is this no-change policy in place, which means that there will be new business needs that we can't address. There's no-change policy. After a few months, there's something that happens. The business would like the old application, which they are still actively using. They would like it to be changed. And we are not allowed to do it. So now it's a negative value because they won't get the support that they need to the business. It happens again, and we are negative cost. Or in some cases, that's severe that you need to lift the no-change policy. Say, okay, we can change it. And then it gets worse. Because the rewrite team then is effectively chasing the old application. It's a moving target. What you are to replace becomes a moving target. And you will have double cost. You will both have to implement a new functionality in the old legacy system that is hard to work with due to the legacy state of the code. And you will have to implement it in the new system. Then after 12 months, we have the big bang switchover. Do we provide value at the switchover date? Is it a positive value? Well, okay. If you rewrite this application as a big bang release, would anyone here think you could write it and have no bugs? No. Can I hire you? No. We will have bugs, of course. And means we will have even more negative value. So we fixed those bugs. And after 13 months of work, we are back where we started value-wise, we have not produced any value but not incurred any loss. But we spent quite a lot of money. Was it fun? Also all these not realized value, money being spent but not having produced any value yet. That's risk to the business. If we decide that we have to hold the project temporarily or for good, but it might be funding issued, well, we need to work on something else for a while. So let's just hold the project right now and we'll commence in six months. Well then you have all this money spent with no value delivered. If we instead go for the strangling option, we will do some initial behind the scenes work in a month or so, then we will start delivering new functionality, rewritten functionality. And since we are doing a rewrite, gradually releasing it, there's no reason to just do one-to-one rewrite. We can actually work closer with the business and make sure that the functionality we deliver is up to date with the business needs as they are right now. A rewrite with strangling takes substantially longer time. Sorry, wrong button. It takes a bit, maybe about 18 months before we are entirely through it. But look at the cost and value curves. Apart from the start-up phase here, we're delivering value all the time. And then when we are done, we can continue to deliver value but spend less money per month. Wouldn't this strangling be the same as the same graph as it was left only in the smaller iterations? No, I don't think so because when the question was if strangling wouldn't be the same graph as it was left, although small iterations. And I don't think so because here we are first doing a one-to-one lift of the old architecture because we are afraid to change anything to reduce risk. But here, if we replace a certain functionality in the system, there is no need to just make a one-to-one replacement. You can ask the business, how should this functionality look like? Yeah, but often you can't just replace one functionality in the legacy code. You have to replace like a big mess of a screen that takes about six months to rewrite. You don't have to rewrite this. The question with the comment was that you need to replace just a single functionality but you need to replace often a large mess. I'll get back to that when we talk about architecture in a while. How to do that? Because that's one of the challenges with the strangler applications. But to summarize this slide, then we have some behind the scenes work in each only, but then we start to deliver value. And if we compare the two options, we deliver value a lot earlier and time is money for business. The return of investment quote is all usually used by those counting money in the company and it means how fast do I get value for the money spent? And actually, the cost is somewhat lower here than here in the end because once we've rewritten at the entire application, we have to make quite a huge effort to boost the functionality and get that new functionality into the system. And we definitely reduce risk, which is important. So anyone keen on continuing the business talk or should we move over to the text of an architecture? Architecture. Well when we are doing strangling, we can start out nice with a new trunk and then everyone on the team works with a new technology, some Angular here, JS, some EmberJS, some KnockoutJS, some service-hired render days, not MVC. And this is our new application, which is not better. So we need to make sure that we're not ending up in this situation. Anyone recognize it? It's not Alexander Rybak. It's Queen, a song called One Vision. You need a vision of where you are going and you need to make sure that you share that vision with the entire team. We need to know that we have this old application and everyone must make coordinated efforts moving functionality over to the new architecture. That's easy to say, but how do you do it? What do you do when you get this mess of 300,000 lines of messy legacy code that's 10 years old? I did that. It was two years ago I first saw this application and dug into it. This is what I saw. And the first step I did was classifying. But this is the example of an application we'll talk about today. So let's go through the various things. This is a web application. How many are working on web applications? How many are working on other kind of applications, such as rich clients? The example here will be web, but I'll talk a bit at the end of the architecture here about Visual Business 6.6 example as well. So let's look at this architecture. It was written 10 years ago, this application, in.NET 1.0 release candidate something. It was created. And I think that was a good decision because when the application was first written, the knew that.NET was coming. They had the choice, stick with the DNA architecture Visual Basic 6 or use the new.NET architecture. I'm very grateful that they did indeed choose to use the VB6. They used.NET, which meant that we didn't have to change programming languages. But still, it's an architecture that was written in.NET 1.0, no entity framework, no link to SQL, no membership providers, and an architecture heavily influenced by the DNA way of thinking. And also, I think it was written by people reading the book on architecture and software applications, having it open beside the computer. Because it's an splendid example of an anemic domain model. Anemic domain model is an anti-pattern. Anemic is a disease where something is wrong with your blood. So you're just pale and it becomes a vampire or something. And an anemic domain model, it is something that at first sight looks like a real domain model with classes and objects representing the business domain, but when you look closer at it, there's nothing there. They are just data transfer objects. Public properties with status and getters, you can read and write to all the properties and no methods. The behavior is somewhere else. So looking at this application, we had a web project, a website, which contains a number of modules, an authentication and authorization manager, a navigation manager, a state manager, a session manager. As soon as I hear a class named managers, there's some ugly feeling within me. This usually is saying there's something fishy in there. Then we had a lot of web-form pages which used web-form controls. I'll get back to the colors soon. They used some shared web utilities and we had a business logic layer with a facade and the so-called domain objects that called a DB controller used for procedures for database access. We also had a web service using the business logic layer because this is kind of ordering system and most people are using the web interface, but there are some big partners using direct integrations with their order systems. So what do you think the business logic functionality actually resided? Either in the store procedures or the manager thing. That's a good guess. Some of it is in the store procedures. In the code for the web-form pages. That's right. Code behind. Thousands of lines of code behind with all the business logic. Copy pasted. What I did when I first got this pile of stinking rotten code, don't tell my colleagues that I've been maintaining this, that I named the code rotten and stinking, but that's my impression of it, was to try to classify it. And that's the colors. The first thing I did was to identify dead code, the red things here, store procedures that when I brought the database into SQL Server data tools. They had been hand hacking in the production database when they were upgrading. So I brought it under source control through bringing it into SQL Server data tools. And I found a number of still procedures that didn't compile because the procedures didn't match the table definitions or the tables were even gone. Those were obviously not used. Delete. I found a number of web-form pages where the name of the page was underscore old. Well, I did a quick search in the code base to make sure no one actually referenced it, but no. And if I have a web page with a name that is not to be found anywhere in the code base, it can't possibly be used. If you want to be on the safe side, search the web server logs as well. But then delete it. The old code that could be just deleted at first sight is saving a lot of time in the next step. Then I looked through it and found that there are some things in this architecture that are really important. And I need the functionality within my new architecture, but I simply just can't let it be as it is. That's a good question. Why did we start this operation? Maintenance costs was the trigger in this particular case. Maintenance costs are prohibitively expensive when we were wanting to do new things. And also legacy user interface. Web forms are not that nice to work with when the people in the business were used to Facebook and other rich internet applications. So that's what the driver in this case. So what we did, we had some red parts that were just removed. And then we moved on to the what I called yellow here. The data was the web service and the authentication and authorization manager. Those were appointed as candidates for rebuild. We should take the functionality they have and fix them. That's the rewrite, but constrained to certain modules. Then we had some parts of the code were actually quite good. They didn't have that legacy smell over all of them. The black one, the web utilities. Actually I moved some things out to separate project called web utilities with code that I found was, well, it's decent enough. We can just put in an ordinary maintenance mode, which means that there are some refectory needs, but they can be addressed when someone needs to work with the code. The external interface, the API is fine. To be honest, no testing, because I love TDD. I prefer working test driven when I can. But in this case, the code was in such a bad shape that it wasn't even possible to write tests against it. It would require substantial refactoring. So I'm coming back briefly to where we could test. I'll just mention the blue things. Those are frozen. Those are mainly the trunk of the old tree. It's there. It supports the business. It's written on the inside. The code is a mess. But the business is actually right now quite happy with the functionality it provides. And I'm quite happy because there's no change request, so I don't need to look at the code. So I just decided this is frozen. It can be as it is for now, but as soon as someone wants to make a change to the functionality, we should rewrite it. But for now it can just be frozen. And that's a risk reduction. But then, well, what other thing we've been waiting for, the new code. We add the new architecture besides the old one. And here it gets interesting. We put some MVC views into the web project. The MVC views need to be in the actual website. We created a new separate web project or a class library called Web New where we put the MVC controllers and MVC view models. The reason to put this in a separate class library was to make a very clear distinction to all developers. What is legacy code and what is brand new shiny code? In this project, when a zero compiler warning policy, we enabled code analysis with a zero warning policy. We could, we can't hear. You can write tests. You can make sure the code is testable. Whatever quality standards you use and want to use for new code, use it in the new project. And then if we're working in the old project, well, the views are part of the new project. They should be live up to the new standards as well. But when working and you have to do interfacing to this old stuff, well, do it so that it works for now. But this was a really important thing to make the shift in mind for the team that we are in the new code with new rules and new quality measurements. And here we have the old code. We are leaving that behind us. We moved the business logic into a domain model. This time it was a real domain model. I mean, there are methods on the entity objects that actually do things and validate business rules. We brought in entity framework and could get rid of some 100,000 lines of handwritten and partially generated code. There's some SQL script generating C sharp code in this application from the database schema. We could get rid of that using entity framework as a standard product to just get the database access working. And it became way faster because the old handwritten thing did, I did a search once. And brought up SQL server profile to see how many SQL queries were actually executed against the database to do simple search. At 5,000 queries, I started to think, well, this is a lot. At 17,000, well, I went to grab some coffee while it was running. At 37,000, it was complete. My coffee mug was empty by then. We also moved all of the web service that should be the one that should be rewritten and moved it to use the new core library, which meant that it actually used the same business logic rules as the web interface. So in the end, the vision is to get here. Basically we had some issues with integrating partners because previously the web service was basically raw access into the database, bypassing all business validation. When we put this into production, the integration partners had issues because they were used to bypass some business rules. And now we enforced them. Let's talk briefly also about leaving this web application. Web applications are a dream to strangle. Because basically each page is very independent from each other. If you have a Visual Basic 6 client, for example, it's much harder, but it's still doable. One thing you can do is if you have a form, you want to change some functionality in that form, you can write that as a.NET component and wrap it in a COM interface. And then you can use that COM interface from the Visual Basic 6 code. Eventually when you've changed enough of the controls and components of the form into being proper.NET components, you can switch it around. You can make the entire application,.NET native application, but call and certainly isolated Visual Basic 6 components through COM. And depending on what kind of application you have, you have to work with how to find those ways to interconnect the applications. Let's continue. I said at the start that the previous issue that a lot of code was frozen, that was not entirely true. When we start an application, it starts out nice in a straight line. Everyone is working the same. Then someone has an idea. I think my way of doing this is way better than your way. You're wrong. And then you have another idea, but it was not that good idea, so it won't be used at all. So it's just a dead end. And then you're over there. You have your own idea. But what you were doing, I don't really know, but it screwed up. This is what an architecture usually looks like when you get into it. And this is very hard to strangle. So at first start, it is a good idea to do some careful refactoring, trying to find out what was the original intent of the architecture and bring the application back in line with the original intent. So once again have just one way of doing, well, I should use that one, one way of doing things. Then when we are starting working, we should prioritize what should we do first. Which is one important thing is to identify impediments in the old architecture. We are here exploring the code, the wideness of the old code. In the application I showed you, I wanted to do some refactoring to the database schema. So I was out there looking for how the database schema was handled. And finally, I found it and it was deep frozen. The architecture, so much of the code was hard-wired to the structure of the database. So that became the first focus of anything. It was to migrate parts of the code that locked down certain database tables that I wanted to change. Because I definitely didn't want to change any database tables where I still had the old database access code using it. One method that needs to be used is to build bridges, or what I call bridges. If we turn the sample architecture around a bit, we have the old stack to the right, the blue ones, and the new stack to the left, the gray and green. And we need to make sure that these two, these are really separate applications built under one roof. And we need to make sure that they can coexist. We need to bridge them somewhere. In this case, for a web application, it's the layout master making sure that we have the same layout for the entire system to the users. And also menus navigation, we need to seamlessly be able to navigate users from an old page to a new page and back. They shouldn't notice too much whether it's rewritten or not. Then it's also sometimes important to refactor, to isolate behavior. For example, menu generation is sometimes, like in deflection I worked with, copy pasted. There were 137 web form pages and all had their own copy of the menu generation and all have their own copy of authentication and authorization. And all were depending on session, current user, and the current user object stored in the session. And we went checks. So what we did there was to do a quick search in the entire code base and find all those cases and replacing them with a facade current user. So we had one entry point to that dependency, which meant we could rewrite the authentication and authorization while providing a backwards compatible API to the old code, but still using new standard ways of doing it in the new code. So bridges are good. They can be made lean. The other thing you can do is pillars, where you can move not move the function, migrate functionality all the way through the application, but rather you do it asymmetrically. So maybe you plug in the entity framework working under a facade and keep the facade. This is a bad way. I've tried it. Don't repeat my mistake. The reason is bad that when I come to the next step and I want to change the facade and keep the web forms, I need to rebuild the pillars. I need to build them again. For every layer that you step up, you need to build new pillars in the migration. And the pillars are substantially harder to build than the bridges. The bridge is lean construction just gluing together, supporting these two. The pillars need to bear the weight of the entire application ahead, top of it, and to support all the different data, all the different functionality. So don't do this. I'll get back to another example application where one of the reasons that Strangling failed was this. But before, I would like to talk a bit about the future. This is Marty Fowler. I thought I'd show you a picture of him because I got a lot of inspiration from his writing on this. And he thinks, he usually presents himself as a general loudmouth, but I think he's a great thinker. And he says that when designing a new application, you should design it in such a way as to make it easier for it to be strangled in the future. The code we are writing today, or maybe not today, but the code we wrote last week and the code we will write next week is the legacy code of the next years to come. I'm not there yet. I think I'll change jobs before the new things I write now need to be strangled. But if you can provide hooks or think of how should we strangle this, it's good. But I think also that if you have a really good architecture, a layered architecture with separation of concerns properly, then it is easy to strangle in the future. That's it about theoretical architecture. I would like to go into a bit about my experiences doing this. But first, anyone has any questions on more theoretical architecture? Okay. Let's move on. Let's talk about reality. The first system I worked on a few years ago, we came this far. And we had some pillars in the architecture. They are now in the face of studying a new standard CRM system instead. So this is the fate of that system. The reasons I think is that they didn't have the funding needed to go through. Although it's less expensive to do strangling than to do a complete rewrite, it's still expensive. And what we did in this case was to sell to the customer that, well, we can do this new functionality with this new technology, which means it will be delivered faster and it will be better. And it will have better performance than the old things. And we said that, well, you have performance issues in part of the application. Those parts, we can migrate those to new data access and get it working better. But we didn't really tell the whole story to the customer that to gain full advantage of this is a strategic decision that you are to work with this application. You are to maintain it for at least five or more years. You are to spend the money needed to get all migrated. We didn't do that because actually I'm a consultant. We knew that that customer didn't really have that funding. So in hindsight, we should probably have been more honest to the customer, which could have meant that we had chosen another option from the start. The other one is better off. This is the current state of it. One functionality area has been rebuilt. And when we did that, we could, thanks to the new architecture, we could deliver new functionality much faster and much better and improved user experience. It was a bit slow start with the team to get up to speed on ASP.NET MVC that they hadn't been working with before, but then we gained momentum. And also when we, that was a completely new area that we built first, then we rebuilt one area with a much improved functionality. This application is 10 years old and the business driver in this case is that the entire application needs to be reworked. The business has changed so substantially in those 10 years that the application is no longer supporting the business properly. It won't rebuild. And thanks to the straining methodology, we can work closely together with the business, get everyone involved, and make sure that the new functionality or the things that we have rewritten are actually providing new functionality in the way that they need to work, need for working right now. So we are currently discussing long term. We have shown them that this is the way to go. We have delivered value. They are trusting us now that we can do this. So now it's the right time to discuss the long term aspects and how to get through it with everything. Very early on in the project, I asked the customer, if we do this, what is the maintenance horizon that we will have for this project? And they said five, is it okay to say five years? They say five years, yes. This system, we have decided that this system will be living for at least five more years, probably ten, but at least five, which means that every time I have to motivate that we should do anything, I can say that if it repays in five years, it's fine to do it. And in five years, you can get nearly everything to be repaid. And then it's important that this turn into a joint effort with the business and tech rewrite or revamp of the system. It's not just a tech project where we are sitting in a basement coding. So this is actually, it shouldn't be rocket science nowadays with the agile principles. We're getting everyone involved. We have continuous user interactions. We are delivering, not continuous delivery, but we are delivering every month at least with new functionality replacing some parts of the system. Getting actual users on the new system. But then there are some challenges, of course. If this is your application, and this was my application, this won't help. It's still just a pig, even if you put lipstick on it. So it's important to make sure that it's real rewrites all the way through the stack. When you're pressed of time, it's easy to just make a fancy iJax Twitter bootstrap based user interface and still the same shitty back end. That's not a rewrite. And if you do that, you've lost the opportunity to communicate with the users and the customers of the rewrite. Because if the user interface is shitty, the customers and users understand the need for rewrite. If the user interface is shiny and nice, it's much harder to sell the need for rewrite. But actually, in the project I'm talking about, we kept the styling of old pages to make sure that it was very visible to the users that there was a difference. That's part of expectation management. So we didn't want to come into a situation where we had users coming to a page that looks new but had the same old bad back end with bad performance. So now the users can see right away, oh, this looks like my old forms. Well, the menu and other stuff around is revamped. But the actual forms looks old. And it works like the old forms. It's a lot of reloading. It's slow. It's painful. But then you get to the new fresh parts and it fasts and works nicely. Actually in that, we had a meeting where we didn't talk about, we talked about making up not the pig but actually the corpse. So we said we'll make up the corpse of the old system just to make sure that it looks a bit better with a bit larger font in some things that were important for readability, but it still looks like a corpse. It should be looking at the old system. Then another success factor is long-term planning. Agile doesn't mean unplanned or short-sighted. Agile means that you can change your mind when you learn as you go, but you should still have road map, vision, where are you going? That's important. And then the thing that faulted in the first project I mentioned, funding. It's still expensive. But it's less expensive than a complete Big Bang rewrite. And it's less expensive than all other alternatives I know about. And if you just go partly through it and then might have to hold the rewrite for temporarily, you have gained a lot of value so far and you have delivered that value and can use that value that you've gained so far. Then on a personal level, I like challenges. Do you like challenge coding? Is this challenging? It's flat. It's green. Yeah, but, okay, assume that you did assume that took a lot of effort to get here. That's right. But assume that, well, you're from Norway. You don't know what natural flatland looks like, do you? In Sweden, we do have some flat areas, but it naturally looks like this. There's no effort to get there and there's really no effort to build anything on top of that. You could surely mess up anyways, but it's not that much of a challenge. Working with legacy code is much more of a challenge. I find it so much more challenging myself. People are often striving to get to green field projects. I've done that too. That was interesting, but not as challenging. That's about my experiences. We have some minutes left. Actually we'll get close to 10 minutes left, I think. Questions, comments, or personal war stories, or anyone think I'm wrong on something? That's most fun, because then we can discuss. Why should I find your struggling when I know that when you're done with your project, you just don't start all over again? Why should I find my project when I'm done? I'll just start over with the new one. Because it will take a few years to get through, but then you will have a few years of maintenance. I won't start over right away. I think it's easy to get into that position as a developer. We migrated this project to ASP.NET MVC. We just partly through it. But still Angular looks great. We should use web API backend and rewrite the application in Angular. That's when we've just migrated 30% of the functionality. Don't do that. Actually it's important challenge, I think, to make sure that you only have two different sets of architecture at the same time. It's so easy to, we have the old web form-based architecture. We have the ASP.NET MVC architecture. And then we could start with the single-page application architecture. Then we have three different architectures to build bridges between. That's stupid. We should make a coordinated effort to move to a new one. And then we should make sure that the architecture we've chosen is stable enough so that we can just maintain it for three to five years. There was someone else. Yeah? Yes. Yes, the question was about the test during development and that multi-fowler and other authorities in our business claim that you should do tests before refactoring. If we were to do tests in this case, I think it should be on the behavior level, behavior tests, because a unit test, which is often used in test during development, would unit test these parts of the code and test on the way that code is structured. We don't want to keep that at all. We say that, well, it's been working for 10 years. It lacks tests, it lacks a lot of readability of everything, but it's been working. Don't fix what ain't broken. And since we are rewriting the code also with new functionality, we're actually starting all over. We are going to the users and asking, what is the functionality you really want? Not what the system does today. So in that case, if we do test-driven development, and that's a good idea to do, then you should use behavior-driven development and test-driven development on the new business logic and the new functionality. And also in this case, I mean, you are here at a conference. You are the visible matter of the development community. We have some 99% dark matter in the development community that never put their foot here, never read a blog, never do anything besides going to the office at 8, doing the work in the same way they always have done, get for lunch, continue working the same way, and at 5 o'clock they go home. And don't even, well, they might look at a computer for checking Facebook, but no code in the spare time. And when you do such a huge change to team, as this is, moving from web forms, I had people here that had been working in this very system for four or five years, and before that they had been working in other web form systems with the same architecture for maybe, well, they've been working with this for 10 years since it was introduced. Getting them to even start working with MBC, it's a shock to them. And in this case, I chose to focus on getting them up to speed on MBC. And for quality, code quality, we use code reviews. Everything was code reviewed, but I opted out of tests. Mostly. We put some tests on core business rules in the entity layer because there were some complex business rules that were hard to test from the user interface. And then also for testing, I prefer Selenium and using end-to-end tests that are web driven. I think you get a better return on investment there. We have time for one or two more questions. No one. Yeah. Did you run the old and new functionality in parallel? If we run the old and new architecture in parallel, yes, we did, and we do. This is a phase that we're still going through. And we have functionality, parts of the system built in the old fashioned way and parts of the system in the new way. We are, this system has a certain number of user interface flows that you go through where there's an order flow for a certain thing. And the order flow for one kind of goods is, well, say wheelchair. We are changing wheelchair, the wheelchair ordering flow in one step and replacing that. And then we go on to the hearing aid ordering flow. But when we deliver the wheelchair ordering flow, the hearing aid ordering flow is still the same. And still using those. And sometimes we are changing core pages of the application that is an entry to another flow. So you start in something that is rewritten, and then when the flow is diverged, you're diverted to an old flow. It's just to make sure that you understand what state and what session variables and whatever query is doing parameters, whatever that page expects to be present. And then just make sure that they are present and hand them over to the old flow. So that's it for this time. Thank you very much for coming. I would like to remind you just briefly about the rating when you're leaving. And it's the green one you should pick. Nothing else. And also, I'm doing another talk on Friday, the last session of the conference on using the scrum rules against your boss. How to get some peace to work. You're welcome back then. Thank you very much. Thank you.
 So, welcome.  I thought sometimes I think that I'm the only one working with legacy applications, but  apparently not.  I'm happy you're here.  I thought I'd start with some, you know, this is nature.  Fresh air, sun, have you heard of it?  Okay, well, this is Norway, so it's rain all the time, isn't it?  Remember my parents bringing me to vacations in Norway when I was a kid and I said, never  more.  It was rain, it was cold.  Next year we went to Greece instead.  So I'm Anders Sjabel.  I'm a developer and working as a consultant at a company called Kantoor in Stockholm,  part of the telecom computing group.  And I've been coding since I was nine and I've written quite a bit of code that was  bad code and I hope I've written some good code.  I'll say that throughout the talk, if you have any questions, just raise your hand.  We'll take them as they come and I'll also save some time at the end for questions and  discussions because I think I've got about 1% of the experience of legacy code in this  room.  99% is you.  So, at the end, I'm happy to have a bit of a discussion.  But first looking back, were you all at the keynote?  Then Luke talked about the future or rather the time that already is here, but a lot of  companies are struggling to understand that time.  But do you remember this?  This is Visual Basic 6.  Forrest designer, code.  And this picture, it ends in 98 and going forward.  I remember this was actually the first conference I went to.  It was a presentation from Microsoft of the new distributed intranetwork architecture  where we moved from one tier to tier to tier and it would be so much better.  At that time, I believed in it.  I'm a bit more seasoned now and I think that the next big thing, it will be the latest  and greatest until the next big things come.  But back then, I really believed in it.  One here that has been working in this kind of context.  Do you like it?  Just laughs.  Well, we'll make a slide detour first and talk about gardening, actually.  In our garden at home, we have not that nice old pine tree.  It works.  It provides the functionality it's supposed to.  It provides shade, but the architecture of this application, sorry, tree, I don't like  pine trees.  I'm thinking of a beautiful big oak instead.  So I go have a chat with the garden government or boss, that is my wife.  And I say that I think that wouldn't it be better with a large oak here instead of this  pine tree?  And she says, yes, it would.  And you know what?  I take that for a yes.  So I go ahead, I bring my chainsaw.  No more pine tree.  I bring this small oak tree instead I get and I plant it and I'm happy.  It has this new nice architecture.  It's an oak tree.  Well it might not be as big as the pine tree, but eventually it will.  I imagine just in 20 years, this will be a magnificent tree.  And imagine in 100 years when my kids are really old sitting there watching their grand  kids play under this magnificent oak, it will be great.  So of course I'm happy, I'm proud, I go get my wife.  She's not happy.  Actually I showed this line to my wife and she said, hey, you can't show that to the  devs.  They all think I'm stupid.  I wouldn't let you bring the chainsaw in the first place.  Actually often I showed this line, I can't find my chainsaw anymore.  Just disappeared.  Well, you're all offing.  But I think that this is what we often do as engineers.  We have this old application that provides a functionality.  It's ugly.  It's a pine tree.  And we walk to the boss and say, we should rebuild this.  Look, we can have this beautiful oak.  But then somewhere along the way we prioritize the architecture and the technology and we  lose track of the functionality.  You won't get much shade out of this.  Actually when I prepared these lines about a couple of weeks ago, but then when I was  planning my trip here, I checked the timetable for the commuter train to Stockholm to get  to the airport.  And they had this brand new site.  With the boots strappy-based, nice, clean design.  But the favorite functionality that I use the site most for to find when there are shutdowns  of traffic, I can't find it anymore.  That functionality was somehow lost.  So what I'm going to talk about today is how to transfer the pine tree to the oak without  having to go through the chainsaw moment.  But first I would like to look a bit about the business perspective because I know, how  many here are developers?  Rightly coded.  Okay.  Anyone who is a boss or manager or responsible for a budget?  Okay.  Good.  No add.  So when we have an idea, we of course know that we should replace this crappy O-lock architecture  and code.  But to do that, we need funding.  At least I'm not working for free.  I prefer if someone pay my salary, which means someone needs to provide funding.  The business drivers for doing anything is either new functionality or that the current  maintenance of the application is too expensive.  Because roughly the only two things that you will ever be able to use as an argument against  your boss to get funding for anything.  So well, it comes to an end.  They often try to postpone this as long as possible.  But in the end, they have to fund a rewrite of the system.  And well, what do they do once they've decided that a rewrite is needed?  They put a no change policy on the legacy system.  And that can last for a long time.  I mean, it can last for several years if it's a large project.  And then at the end, you have a big bang release where every single change feature that you  bring into the rewritten system is an increased risk.  This one remedy that is often used in rewrite projects to handle this risk and reduce risk,  is to make it one-to-one rewrite.  Well imagine for a moment that you are actually managers, I know you're devs, but imagine  you're managers and I'm a developer, I'm a sole developer here, I'm trying to sell this  rewrite to you.  And you know what?  If you fund this rewrite, you'll get no new functionality.  And it's a one-to-one rewrite to reduce risk.  So when we are done, you will have the same sheet to use the interface and the same sheet  to functionality.  Okay, anyone want to fund my rewrite?  But I know some of you are thinking now that, well, at least it's better code because you're  developers.  So you're thinking it's better code.  So while there is some gains by rewriting anyways, but let me tell you, this is one-to-one  conversion.  So when we're done with the rewrite, we will have the same sheet to architecture.  But then we can start working with a new platform, new language to improve.  Well this is not a very good way, I think, to do a rewrite.  Let's look at a popular methodology for movement for development, agile.  That's really mainstream nowadays.  What does agile learn to us?  What we can learn is that we should reduce risk by using agreements.  We shouldn't have a big bang release.  And that goes with the same for rewrites or changing applications.  We should have early and continued user interaction.  And any software development effort should be an evolution, not a revolution.  So that brings us into the topic of today, strangling.  So if your boss is unwilling to find and bring out the money needed for that complete  rewrite, you can use a very fictive means called strangling.  Sorry, wrong.  I wasn't supposed to show that one.  My boss said I wasn't allowed.  Well, let's move on to the other strangling.  This is a plant.  There's a lot of trees in this presentation.  I was looking for images for this presentation.  There's so many beautiful images of strangler vines out there.  Just type it in on Google and try.  This is a strangler vine.  It's an old tree here.  And then this one is using the old tree to grow.  It seats itself in the crown of the old tree.  And then it roots down to the bottom while still being high up in the air and having  access to the sun.  The patent strangler application was named by Marthifala after he had visited a forest  with strangler vines.  So what we do with an application when strangling it is that we start building a new separate  application besides the old one.  A new separate one with a new architecture just like this trunk.  It's in its own trunk.  It has some connections to the old application here.  But it's an own trunk.  We add more and more functionality, more and more trunks.  They start to grow together.  And eventually we have got rid of the old application, the old legacy code.  I think this picture is just beautiful.  But this was more of a business section of the talk.  So let's look at cost-value comparison.  Because when you show this to managers, there's always this question about cost and value.  We'll try to go through it quite quickly.  First to the left, we have a complete rewrite with a big bang release, which means that  we are investing.  The blue field here is the cost, the money spent.  The orange field is the value gained from the effort.  We start rewriting.  We're spending a lot of time rewriting until the cut-over date here.  And we are accumulating cost.  But we are not only accumulating cost, we're actually getting negative value.  Because once we have started with the rewrite, there is this no-change policy in place,  which means that there will be new business needs that we can't address.  There's no-change policy.  After a few months, there's something that happens.  The business would like the old application, which they are still actively using.  They would like it to be changed.  And we are not allowed to do it.  So now it's a negative value because they won't get the support that they need to the  business.  It happens again, and we are negative cost.  Or in some cases, that's severe that you need to lift the no-change policy.  Say, okay, we can change it.  And then it gets worse.  Because the rewrite team then is effectively chasing the old application.  It's a moving target.  What you are to replace becomes a moving target.  And you will have double cost.  You will both have to implement a new functionality in the old legacy system that is hard to work  with due to the legacy state of the code.  And you will have to implement it in the new system.  Then after 12 months, we have the big bang switchover.  Do we provide value at the switchover date?  Is it a positive value?  Well, okay.  If you rewrite this application as a big bang release, would anyone here think you could  write it and have no bugs?  No.  Can I hire you?  No.  We will have bugs, of course.  And means we will have even more negative value.  So we fixed those bugs.  And after 13 months of work, we are back where we started value-wise, we have not produced  any value but not incurred any loss.  But we spent quite a lot of money.  Was it fun?  Also all these not realized value, money being spent but not having produced any value yet.  That's risk to the business.  If we decide that we have to hold the project temporarily or for good, but it might be funding  issued, well, we need to work on something else for a while.  So let's just hold the project right now and we'll commence in six months.  Well then you have all this money spent with no value delivered.  If we instead go for the strangling option, we will do some initial behind the scenes  work in a month or so, then we will start delivering new functionality, rewritten functionality.  And since we are doing a rewrite, gradually releasing it, there's no reason to just do  one-to-one rewrite.  We can actually work closer with the business and make sure that the functionality we deliver  is up to date with the business needs as they are right now.  A rewrite with strangling takes substantially longer time.  Sorry, wrong button.  It takes a bit, maybe about 18 months before we are entirely through it.  But look at the cost and value curves.  Apart from the start-up phase here, we're delivering value all the time.  And then when we are done, we can continue to deliver value but spend less money per  month.  Wouldn't this strangling be the same as the same graph as it was left only in the smaller  iterations?  No, I don't think so because when the question was if strangling wouldn't be the same graph  as it was left, although small iterations.  And I don't think so because here we are first doing a one-to-one lift of the old architecture  because we are afraid to change anything to reduce risk.  But here, if we replace a certain functionality in the system, there is no need to just make  a one-to-one replacement.  You can ask the business, how should this functionality look like?  Yeah, but often you can't just replace one functionality in the legacy code.  You have to replace like a big mess of a screen that takes about six months to rewrite.  You don't have to rewrite this.  The question with the comment was that you need to replace just a single functionality  but you need to replace often a large mess.  I'll get back to that when we talk about architecture in a while.  How to do that?  Because that's one of the challenges with the strangler applications.  But to summarize this slide, then we have some behind the scenes work in each only,  but then we start to deliver value.  And if we compare the two options, we deliver value a lot earlier and time is money for  business.  The return of investment quote is all usually used by those counting money in the company  and it means how fast do I get value for the money spent?  And actually, the cost is somewhat lower here than here in the end because once we've rewritten  at the entire application, we have to make quite a huge effort to boost the functionality  and get that new functionality into the system.  And we definitely reduce risk, which is important.  So anyone keen on continuing the business talk or should we move over to the text of  an architecture?  Architecture.  Well when we are doing strangling, we can start out nice with a new trunk and then everyone  on the team works with a new technology, some Angular here, JS, some EmberJS, some KnockoutJS,  some service-hired render days, not MVC.  And this is our new application, which is not better.  So we need to make sure that we're not ending up in this situation.  Anyone recognize it?  It's not Alexander Rybak.  It's Queen, a song called One Vision.  You need a vision of where you are going and you need to make sure that you share that  vision with the entire team.  We need to know that we have this old application and everyone must make coordinated efforts  moving functionality over to the new architecture.  That's easy to say, but how do you do it?  What do you do when you get this mess of 300,000 lines of messy legacy code that's 10 years  old?  I did that.  It was two years ago I first saw this application and dug into it.  This is what I saw.  And the first step I did was classifying.  But this is the example of an application we'll talk about today.  So let's go through the various things.  This is a web application.  How many are working on web applications?  How many are working on other kind of applications, such as rich clients?  The example here will be web, but I'll talk a bit at the end of the architecture here  about Visual Business 6.6 example as well.  So let's look at this architecture.  It was written 10 years ago, this application, in.NET 1.0 release candidate something.  It was created.  And I think that was a good decision because when the application was first written, the  knew that.NET was coming.  They had the choice, stick with the DNA architecture Visual Basic 6 or use the new.NET architecture.  I'm very grateful that they did indeed choose to use the VB6.  They used.NET, which meant that we didn't have to change programming languages.  But still, it's an architecture that was written in.NET 1.0, no entity framework, no link  to SQL, no membership providers, and an architecture heavily influenced by the DNA way of thinking.  And also, I think it was written by people reading the book on architecture and software  applications, having it open beside the computer.  Because it's an splendid example of an anemic domain model.  Anemic domain model is an anti-pattern.  Anemic is a disease where something is wrong with your blood.  So you're just pale and it becomes a vampire or something.  And an anemic domain model, it is something that at first sight looks like a real domain  model with classes and objects representing the business domain, but when you look closer  at it, there's nothing there.  They are just data transfer objects.  Public properties with status and getters, you can read and write to all the properties  and no methods.  The behavior is somewhere else.  So looking at this application, we had a web project, a website, which contains a number  of modules, an authentication and authorization manager, a navigation manager, a state manager,  a session manager.  As soon as I hear a class named managers, there's some ugly feeling within me.  This usually is saying there's something fishy in there.  Then we had a lot of web-form pages which used web-form controls.  I'll get back to the colors soon.  They used some shared web utilities and we had a business logic layer with a facade and  the so-called domain objects that called a DB controller used for procedures for database  access.  We also had a web service using the business logic layer because this is kind of ordering  system and most people are using the web interface, but there are some big partners using direct  integrations with their order systems.  So what do you think the business logic functionality actually resided?  Either in the store procedures or the manager thing.  That's a good guess.  Some of it is in the store procedures.  In the code for the web-form pages.  That's right.  Code behind.  Thousands of lines of code behind with all the business logic.  Copy pasted.  What I did when I first got this pile of stinking rotten code, don't tell my colleagues  that I've been maintaining this, that I named the code rotten and stinking, but that's my  impression of it, was to try to classify it.  And that's the colors.  The first thing I did was to identify dead code, the red things here, store procedures  that when I brought the database into SQL Server data tools.  They had been hand hacking in the production database when they were upgrading.  So I brought it under source control through bringing it into SQL Server data tools.  And I found a number of still procedures that didn't compile because the procedures didn't  match the table definitions or the tables were even gone.  Those were obviously not used.  Delete.  I found a number of web-form pages where the name of the page was underscore old.  Well, I did a quick search in the code base to make sure no one actually referenced it,  but no.  And if I have a web page with a name that is not to be found anywhere in the code base,  it can't possibly be used.  If you want to be on the safe side, search the web server logs as well.  But then delete it.  The old code that could be just deleted at first sight is saving a lot of time in the  next step.  Then I looked through it and found that there are some things in this architecture that  are really important.  And I need the functionality within my new architecture, but I simply just can't let  it be as it is.  That's a good question.  Why did we start this operation?  Maintenance costs was the trigger in this particular case.  Maintenance costs are prohibitively expensive when we were wanting to do new things.  And also legacy user interface.  Web forms are not that nice to work with when the people in the business were used to Facebook  and other rich internet applications.  So that's what the driver in this case.  So what we did, we had some red parts that were just removed.  And then we moved on to the what I called yellow here.  The data was the web service and the authentication and authorization manager.  Those were appointed as candidates for rebuild.  We should take the functionality they have and fix them.  That's the rewrite, but constrained to certain modules.  Then we had some parts of the code were actually quite good.  They didn't have that legacy smell over all of them.  The black one, the web utilities.  Actually I moved some things out to separate project called web utilities with code that  I found was, well, it's decent enough.  We can just put in an ordinary maintenance mode, which means that there are some refectory  needs, but they can be addressed when someone needs to work with the code.  The external interface, the API is fine.  To be honest, no testing, because I love TDD.  I prefer working test driven when I can.  But in this case, the code was in such a bad shape that it wasn't even possible to write  tests against it.  It would require substantial refactoring.  So I'm coming back briefly to where we could test.  I'll just mention the blue things.  Those are frozen.  Those are mainly the trunk of the old tree.  It's there.  It supports the business.  It's written on the inside.  The code is a mess.  But the business is actually right now quite happy with the functionality it provides.  And I'm quite happy because there's no change request, so I don't need to look at the code.  So I just decided this is frozen.  It can be as it is for now, but as soon as someone wants to make a change to the functionality,  we should rewrite it.  But for now it can just be frozen.  And that's a risk reduction.  But then, well, what other thing we've been waiting for, the new code.  We add the new architecture besides the old one.  And here it gets interesting.  We put some MVC views into the web project.  The MVC views need to be in the actual website.  We created a new separate web project or a class library called Web New where we put  the MVC controllers and MVC view models.  The reason to put this in a separate class library was to make a very clear distinction  to all developers.  What is legacy code and what is brand new shiny code?  In this project, when a zero compiler warning policy, we enabled code analysis with a zero  warning policy.  We could, we can't hear.  You can write tests.  You can make sure the code is testable.  Whatever quality standards you use and want to use for new code, use it in the new project.  And then if we're working in the old project, well, the views are part of the new project.  They should be live up to the new standards as well.  But when working and you have to do interfacing to this old stuff, well, do it so that it  works for now.  But this was a really important thing to make the shift in mind for the team that we are  in the new code with new rules and new quality measurements.  And here we have the old code.  We are leaving that behind us.  We moved the business logic into a domain model.  This time it was a real domain model.  I mean, there are methods on the entity objects that actually do things and validate business  rules.  We brought in entity framework and could get rid of some 100,000 lines of handwritten  and partially generated code.  There's some SQL script generating C sharp code in this application from the database  schema.  We could get rid of that using entity framework as a standard product to just get the database  access working.  And it became way faster because the old handwritten thing did, I did a search once.  And brought up SQL server profile to see how many SQL queries were actually executed  against the database to do simple search.  At 5,000 queries, I started to think, well, this is a lot.  At 17,000, well, I went to grab some coffee while it was running.  At 37,000, it was complete.  My coffee mug was empty by then.  We also moved all of the web service that should be the one that should be rewritten  and moved it to use the new core library, which meant that it actually used the same  business logic rules as the web interface.  So in the end, the vision is to get here.  Basically we had some issues with integrating partners because previously the web service  was basically raw access into the database, bypassing all business validation.  When we put this into production, the integration partners had issues because they were used  to bypass some business rules.  And now we enforced them.  Let's talk briefly also about leaving this web application.  Web applications are a dream to strangle.  Because basically each page is very independent from each other.  If you have a Visual Basic 6 client, for example, it's much harder, but it's still doable.  One thing you can do is if you have a form, you want to change some functionality in that  form, you can write that as a.NET component and wrap it in a COM interface.  And then you can use that COM interface from the Visual Basic 6 code.  Eventually when you've changed enough of the controls and components of the form into being  proper.NET components, you can switch it around.  You can make the entire application,.NET native application, but call and certainly  isolated Visual Basic 6 components through COM.  And depending on what kind of application you have, you have to work with how to find  those ways to interconnect the applications.  Let's continue.  I said at the start that the previous issue that a lot of code was frozen, that was not  entirely true.  When we start an application, it starts out nice in a straight line.  Everyone is working the same.  Then someone has an idea.  I think my way of doing this is way better than your way.  You're wrong.  And then you have another idea, but it was not that good idea, so it won't be used at  all.  So it's just a dead end.  And then you're over there.  You have your own idea.  But what you were doing, I don't really know, but it screwed up.  This is what an architecture usually looks like when you get into it.  And this is very hard to strangle.  So at first start, it is a good idea to do some careful refactoring, trying to find out  what was the original intent of the architecture and bring the application back in line with  the original intent.  So once again have just one way of doing, well, I should use that one, one way of doing  things.  Then when we are starting working, we should prioritize what should we do first.  Which is one important thing is to identify impediments in the old architecture.  We are here exploring the code, the wideness of the old code.  In the application I showed you, I wanted to do some refactoring to the database schema.  So I was out there looking for how the database schema was handled.  And finally, I found it and it was deep frozen.  The architecture, so much of the code was hard-wired to the structure of the database.  So that became the first focus of anything.  It was to migrate parts of the code that locked down certain database tables that I wanted  to change.  Because I definitely didn't want to change any database tables where I still had the  old database access code using it.  One method that needs to be used is to build bridges, or what I call bridges.  If we turn the sample architecture around a bit, we have the old stack to the right,  the blue ones, and the new stack to the left, the gray and green.  And we need to make sure that these two, these are really separate applications built under  one roof.  And we need to make sure that they can coexist.  We need to bridge them somewhere.  In this case, for a web application, it's the layout master making sure that we have  the same layout for the entire system to the users.  And also menus navigation, we need to seamlessly be able to navigate users from an old page  to a new page and back.  They shouldn't notice too much whether it's rewritten or not.  Then it's also sometimes important to refactor, to isolate behavior.  For example, menu generation is sometimes, like in deflection I worked with, copy pasted.  There were 137 web form pages and all had their own copy of the menu generation and  all have their own copy of authentication and authorization.  And all were depending on session, current user, and the current user object stored in  the session.  And we went checks.  So what we did there was to do a quick search in the entire code base and find all those  cases and replacing them with a facade current user.  So we had one entry point to that dependency, which meant we could rewrite the authentication  and authorization while providing a backwards compatible API to the old code, but still  using new standard ways of doing it in the new code.  So bridges are good.  They can be made lean.  The other thing you can do is pillars, where you can move not move the function, migrate  functionality all the way through the application, but rather you do it asymmetrically.  So maybe you plug in the entity framework working under a facade and keep the facade.  This is a bad way.  I've tried it.  Don't repeat my mistake.  The reason is bad that when I come to the next step and I want to change the facade and  keep the web forms, I need to rebuild the pillars.  I need to build them again.  For every layer that you step up, you need to build new pillars in the migration.  And the pillars are substantially harder to build than the bridges.  The bridge is lean construction just gluing together, supporting these two.  The pillars need to bear the weight of the entire application ahead, top of it, and to  support all the different data, all the different functionality.  So don't do this.  I'll get back to another example application where one of the reasons that Strangling failed  was this.  But before, I would like to talk a bit about the future.  This is Marty Fowler.  I thought I'd show you a picture of him because I got a lot of inspiration from his writing  on this.  And he thinks, he usually presents himself as a general loudmouth, but I think he's a  great thinker.  And he says that when designing a new application, you should design it in such a way as to make  it easier for it to be strangled in the future.  The code we are writing today, or maybe not today, but the code we wrote last week and  the code we will write next week is the legacy code of the next years to come.  I'm not there yet.  I think I'll change jobs before the new things I write now need to be strangled.  But if you can provide hooks or think of how should we strangle this, it's good.  But I think also that if you have a really good architecture, a layered architecture  with separation of concerns properly, then it is easy to strangle in the future.  That's it about theoretical architecture.  I would like to go into a bit about my experiences doing this.  But first, anyone has any questions on more theoretical architecture?  Okay.  Let's move on.  Let's talk about reality.  The first system I worked on a few years ago, we came this far.  And we had some pillars in the architecture.  They are now in the face of studying a new standard CRM system instead.  So this is the fate of that system.  The reasons I think is that they didn't have the funding needed to go through.  Although it's less expensive to do strangling than to do a complete rewrite, it's still  expensive.  And what we did in this case was to sell to the customer that, well, we can do this new  functionality with this new technology, which means it will be delivered faster and it will  be better.  And it will have better performance than the old things.  And we said that, well, you have performance issues in part of the application.  Those parts, we can migrate those to new data access and get it working better.  But we didn't really tell the whole story to the customer that to gain full advantage  of this is a strategic decision that you are to work with this application.  You are to maintain it for at least five or more years.  You are to spend the money needed to get all migrated.  We didn't do that because actually I'm a consultant.  We knew that that customer didn't really have that funding.  So in hindsight, we should probably have been more honest to the customer, which could have  meant that we had chosen another option from the start.  The other one is better off.  This is the current state of it.  One functionality area has been rebuilt.  And when we did that, we could, thanks to the new architecture, we could deliver new  functionality much faster and much better and improved user experience.  It was a bit slow start with the team to get up to speed on ASP.NET MVC that they hadn't  been working with before, but then we gained momentum.  And also when we, that was a completely new area that we built first, then we rebuilt  one area with a much improved functionality.  This application is 10 years old and the business driver in this case is that the entire application  needs to be reworked.  The business has changed so substantially in those 10 years that the application is no  longer supporting the business properly.  It won't rebuild.  And thanks to the straining methodology, we can work closely together with the business,  get everyone involved, and make sure that the new functionality or the things that we  have rewritten are actually providing new functionality in the way that they need to  work, need for working right now.  So we are currently discussing long term.  We have shown them that this is the way to go.  We have delivered value.  They are trusting us now that we can do this.  So now it's the right time to discuss the long term aspects and how to get through it  with everything.  Very early on in the project, I asked the customer, if we do this, what is the maintenance  horizon that we will have for this project?  And they said five, is it okay to say five years?  They say five years, yes.  This system, we have decided that this system will be living for at least five more years,  probably ten, but at least five, which means that every time I have to motivate that we  should do anything, I can say that if it repays in five years, it's fine to do it.  And in five years, you can get nearly everything to be repaid.  And then it's important that this turn into a joint effort with the business and tech  rewrite or revamp of the system.  It's not just a tech project where we are sitting in a basement coding.  So this is actually, it shouldn't be rocket science nowadays with the agile principles.  We're getting everyone involved.  We have continuous user interactions.  We are delivering, not continuous delivery, but we are delivering every month at least  with new functionality replacing some parts of the system.  Getting actual users on the new system.  But then there are some challenges, of course.  If this is your application, and this was my application, this won't help.  It's still just a pig, even if you put lipstick on it.  So it's important to make sure that it's real rewrites all the way through the stack.  When you're pressed of time, it's easy to just make a fancy iJax Twitter bootstrap  based user interface and still the same shitty back end.  That's not a rewrite.  And if you do that, you've lost the opportunity to communicate with the users and the customers  of the rewrite.  Because if the user interface is shitty, the customers and users understand the need for  rewrite.  If the user interface is shiny and nice, it's much harder to sell the need for rewrite.  But actually, in the project I'm talking about, we kept the styling of old pages to make sure  that it was very visible to the users that there was a difference.  That's part of expectation management.  So we didn't want to come into a situation where we had users coming to a page that looks  new but had the same old bad back end with bad performance.  So now the users can see right away, oh, this looks like my old forms.  Well, the menu and other stuff around is revamped.  But the actual forms looks old.  And it works like the old forms.  It's a lot of reloading.  It's slow.  It's painful.  But then you get to the new fresh parts and it fasts and works nicely.  Actually in that, we had a meeting where we didn't talk about, we talked about making  up not the pig but actually the corpse.  So we said we'll make up the corpse of the old system just to make sure that it looks  a bit better with a bit larger font in some things that were important for readability,  but it still looks like a corpse.  It should be looking at the old system.  Then another success factor is long-term planning.  Agile doesn't mean unplanned or short-sighted.  Agile means that you can change your mind when you learn as you go, but you should still  have road map, vision, where are you going?  That's important.  And then the thing that faulted in the first project I mentioned, funding.  It's still expensive.  But it's less expensive than a complete Big Bang rewrite.  And it's less expensive than all other alternatives I know about.  And if you just go partly through it and then might have to hold the rewrite for temporarily,  you have gained a lot of value so far and you have delivered that value and can use  that value that you've gained so far.  Then on a personal level, I like challenges.  Do you like challenge coding?  Is this challenging?  It's flat.  It's green.  Yeah, but, okay, assume that you did assume that took a lot of effort to get here.  That's right.  But assume that, well, you're from Norway.  You don't know what natural flatland looks like, do you?  In Sweden, we do have some flat areas, but it naturally looks like this.  There's no effort to get there and there's really no effort to build anything on top  of that.  You could surely mess up anyways, but it's not that much of a challenge.  Working with legacy code is much more of a challenge.  I find it so much more challenging myself.  People are often striving to get to green field projects.  I've done that too.  That was interesting, but not as challenging.  That's about my experiences.  We have some minutes left.  Actually we'll get close to 10 minutes left, I think.  Questions, comments, or personal war stories, or anyone think I'm wrong on something?  That's most fun, because then we can discuss.  Why should I find your struggling when I know that when you're done with your project,  you just don't start all over again?  Why should I find my project when I'm done?  I'll just start over with the new one.  Because it will take a few years to get through, but then you will have a few years of maintenance.  I won't start over right away.  I think it's easy to get into that position as a developer.  We migrated this project to ASP.NET MVC.  We just partly through it.  But still Angular looks great.  We should use web API backend and rewrite the application in Angular.  That's when we've just migrated 30% of the functionality.  Don't do that.  Actually it's important challenge, I think, to make sure that you only have two different  sets of architecture at the same time.  It's so easy to, we have the old web form-based architecture.  We have the ASP.NET MVC architecture.  And then we could start with the single-page application architecture.  Then we have three different architectures to build bridges between.  That's stupid.  We should make a coordinated effort to move to a new one.  And then we should make sure that the architecture we've chosen is stable enough so that we  can just maintain it for three to five years.  There was someone else.  Yeah?  Yes.  Yes, the question was about the test during development and that multi-fowler and other  authorities in our business claim that you should do tests before refactoring.  If we were to do tests in this case, I think it should be on the behavior level, behavior  tests, because a unit test, which is often used in test during development, would unit  test these parts of the code and test on the way that code is structured.  We don't want to keep that at all.  We say that, well, it's been working for 10 years.  It lacks tests, it lacks a lot of readability of everything, but it's been working.  Don't fix what ain't broken.  And since we are rewriting the code also with new functionality, we're actually starting  all over.  We are going to the users and asking, what is the functionality you really want?  Not what the system does today.  So in that case, if we do test-driven development, and that's a good idea to do, then you should  use behavior-driven development and test-driven development on the new business logic and  the new functionality.  And also in this case, I mean, you are here at a conference.  You are the visible matter of the development community.  We have some 99% dark matter in the development community that never put their foot here,  never read a blog, never do anything besides going to the office at 8, doing the work in  the same way they always have done, get for lunch, continue working the same way, and at  5 o'clock they go home.  And don't even, well, they might look at a computer for checking Facebook, but no code  in the spare time.  And when you do such a huge change to team, as this is, moving from web forms, I had people  here that had been working in this very system for four or five years, and before that they  had been working in other web form systems with the same architecture for maybe, well,  they've been working with this for 10 years since it was introduced.  Getting them to even start working with MBC, it's a shock to them.  And in this case, I chose to focus on getting them up to speed on MBC.  And for quality, code quality, we use code reviews.  Everything was code reviewed, but I opted out of tests.  Mostly.  We put some tests on core business rules in the entity layer because there were some complex  business rules that were hard to test from the user interface.  And then also for testing, I prefer Selenium and using end-to-end tests that are web driven.  I think you get a better return on investment there.  We have time for one or two more questions.  No one.  Yeah.  Did you run the old and new functionality in parallel?  If we run the old and new architecture in parallel, yes, we did, and we do.  This is a phase that we're still going through.  And we have functionality, parts of the system built in the old fashioned way and parts of  the system in the new way.  We are, this system has a certain number of user interface flows that you go through where  there's an order flow for a certain thing.  And the order flow for one kind of goods is, well, say wheelchair.  We are changing wheelchair, the wheelchair ordering flow in one step and replacing that.  And then we go on to the hearing aid ordering flow.  But when we deliver the wheelchair ordering flow, the hearing aid ordering flow is still  the same.  And still using those.  And sometimes we are changing core pages of the application that is an entry to another  flow.  So you start in something that is rewritten, and then when the flow is diverged, you're  diverted to an old flow.  It's just to make sure that you understand what state and what session variables and  whatever query is doing parameters, whatever that page expects to be present.  And then just make sure that they are present and hand them over to the old flow.  So that's it for this time.  Thank you very much for coming.  I would like to remind you just briefly about the rating when you're leaving.  And it's the green one you should pick.  Nothing else.  And also, I'm doing another talk on Friday, the last session of the conference on using  the scrum rules against your boss.  How to get some peace to work.  You're welcome back then.  Thank you very much.  Thank you.
Anders_Abel_-_Strangling_the_Legacy_out_of_an_Application_0_47.png Anders_Abel_-_Strangling_the_Legacy_out_of_an_Application_48_2087.png Anders_Abel_-_Strangling_the_Legacy_out_of_an_Application_2088_3815.png Anders_Abel_-_Strangling_the_Legacy_out_of_an_Application_3816_3863.png Anders_Abel_-_Strangling_the_Legacy_out_of_an_Application_3864_3911.png Anders_Abel_-_Strangling_the_Legacy_out_of_an_Application_3912_3959.png Anders_Abel_-_Strangling_the_Legacy_out_of_an_Application_3960_4007.png Anders_Abel_-_Strangling_the_Legacy_out_of_an_Application_4008_4355.png Anders_Abel_-_Strangling_the_Legacy_out_of_an_Application_4356_4919.png Anders_Abel_-_Strangling_the_Legacy_out_of_an_Application_4920_5171.png Anders_Abel_-_Strangling_the_Legacy_out_of_an_Application_5172_5999.png Anders_Abel_-_Strangling_the_Legacy_out_of_an_Application_6000_8459.png Anders_Abel_-_Strangling_the_Legacy_out_of_an_Application_8460_9323.png Anders_Abel_-_Strangling_the_Legacy_out_of_an_Application_9324_9371.png Anders_Abel_-_Strangling_the_Legacy_out_of_an_Application_9372_10355.png Anders_Abel_-_Strangling_the_Legacy_out_of_an_Application_10356_10691.png Anders_Abel_-_Strangling_the_Legacy_out_of_an_Application_10692_11027.png Anders_Abel_-_Strangling_the_Legacy_out_of_an_Application_11028_11447.png Anders_Abel_-_Strangling_the_Legacy_out_of_an_Application_11448_11603.png Anders_Abel_-_Strangling_the_Legacy_out_of_an_Application_11604_12323.png Anders_Abel_-_Strangling_the_Legacy_out_of_an_Application_12324_12755.png Anders_Abel_-_Strangling_the_Legacy_out_of_an_Application_12756_13691.png Anders_Abel_-_Strangling_the_Legacy_out_of_an_Application_13692_13967.png Anders_Abel_-_Strangling_the_Legacy_out_of_an_Application_13968_14171.png Anders_Abel_-_Strangling_the_Legacy_out_of_an_Application_14172_14243.png Anders_Abel_-_Strangling_the_Legacy_out_of_an_Application_14244_15887.png Anders_Abel_-_Strangling_the_Legacy_out_of_an_Application_15888_16043.png Anders_Abel_-_Strangling_the_Legacy_out_of_an_Application_16044_16319.png Anders_Abel_-_Strangling_the_Legacy_out_of_an_Application_16320_22463.png Anders_Abel_-_Strangling_the_Legacy_out_of_an_Application_22464_25127.png Anders_Abel_-_Strangling_the_Legacy_out_of_an_Application_25128_26387.png Anders_Abel_-_Strangling_the_Legacy_out_of_an_Application_26388_26627.png Anders_Abel_-_Strangling_the_Legacy_out_of_an_Application_26628_26759.png Anders_Abel_-_Strangling_the_Legacy_out_of_an_Application_26760_27263.png Anders_Abel_-_Strangling_the_Legacy_out_of_an_Application_27264_28451.png Anders_Abel_-_Strangling_the_Legacy_out_of_an_Application_28452_28991.png Anders_Abel_-_Strangling_the_Legacy_out_of_an_Application_28992_29675.png Anders_Abel_-_Strangling_the_Legacy_out_of_an_Application_29676_43295.png Anders_Abel_-_Strangling_the_Legacy_out_of_an_Application_43296_48035.png Anders_Abel_-_Strangling_the_Legacy_out_of_an_Application_48036_49943.png Anders_Abel_-_Strangling_the_Legacy_out_of_an_Application_49944_50003.png Anders_Abel_-_Strangling_the_Legacy_out_of_an_Application_50004_50051.png Anders_Abel_-_Strangling_the_Legacy_out_of_an_Application_50052_50099.png Anders_Abel_-_Strangling_the_Legacy_out_of_an_Application_50100_50147.png Anders_Abel_-_Strangling_the_Legacy_out_of_an_Application_50148_50207.png Anders_Abel_-_Strangling_the_Legacy_out_of_an_Application_50208_50255.png Anders_Abel_-_Strangling_the_Legacy_out_of_an_Application_50256_50303.png Anders_Abel_-_Strangling_the_Legacy_out_of_an_Application_50304_50351.png Anders_Abel_-_Strangling_the_Legacy_out_of_an_Application_50352_50399.png Anders_Abel_-_Strangling_the_Legacy_out_of_an_Application_50400_50447.png Anders_Abel_-_Strangling_the_Legacy_out_of_an_Application_50448_50507.png Anders_Abel_-_Strangling_the_Legacy_out_of_an_Application_50508_50663.png Anders_Abel_-_Strangling_the_Legacy_out_of_an_Application_50664_51047.png Anders_Abel_-_Strangling_the_Legacy_out_of_an_Application_51048_51287.png Anders_Abel_-_Strangling_the_Legacy_out_of_an_Application_51288_51527.png Anders_Abel_-_Strangling_the_Legacy_out_of_an_Application_51528_52583.png Anders_Abel_-_Strangling_the_Legacy_out_of_an_Application_52584_53111.png Anders_Abel_-_Strangling_the_Legacy_out_of_an_Application_53112_53975.png Anders_Abel_-_Strangling_the_Legacy_out_of_an_Application_53976_57131.png Anders_Abel_-_Strangling_the_Legacy_out_of_an_Application_57132_59207.png Anders_Abel_-_Strangling_the_Legacy_out_of_an_Application_59208_59747.png Anders_Abel_-_Strangling_the_Legacy_out_of_an_Application_59748_60995.png Anders_Abel_-_Strangling_the_Legacy_out_of_an_Application_60996_61511.png Anders_Abel_-_Strangling_the_Legacy_out_of_an_Application_61512_61583.png Anders_Abel_-_Strangling_the_Legacy_out_of_an_Application_61584_62003.png Anders_Abel_-_Strangling_the_Legacy_out_of_an_Application_62004_64187.png Anders_Abel_-_Strangling_the_Legacy_out_of_an_Application_64188_67775.png Anders_Abel_-_Strangling_the_Legacy_out_of_an_Application_67776_68927.png Anders_Abel_-_Strangling_the_Legacy_out_of_an_Application_68928_69011.png Anders_Abel_-_Strangling_the_Legacy_out_of_an_Application_69012_69143.png Anders_Abel_-_Strangling_the_Legacy_out_of_an_Application_69144_72071.png Anders_Abel_-_Strangling_the_Legacy_out_of_an_Application_72072_72623.png Anders_Abel_-_Strangling_the_Legacy_out_of_an_Application_72624_73499.png Anders_Abel_-_Strangling_the_Legacy_out_of_an_Application_73500_73655.png Anders_Abel_-_Strangling_the_Legacy_out_of_an_Application_73656_74639.png Anders_Abel_-_Strangling_the_Legacy_out_of_an_Application_74640_74783.png Anders_Abel_-_Strangling_the_Legacy_out_of_an_Application_74784_75275.png Anders_Abel_-_Strangling_the_Legacy_out_of_an_Application_75276_78995.png Anders_Abel_-_Strangling_the_Legacy_out_of_an_Application_78996_86639.png Anders_Abel_-_Strangling_the_Legacy_out_of_an_Application_86640_86699.png Anders_Abel_-_Strangling_the_Legacy_out_of_an_Application_86700_87539.png Anders_Abel_-_Strangling_the_Legacy_out_of_an_Application_87540_87746.png