!title Using the Adapter Pattern to Decouple Legacy VB Code Ann Condon manages a software development group for a private company (Humboldt Merchant Services) in the financial services industry. Prior to the team’s conversion to Extreme Programming with help from Bob Koss, most of the development had been done in Visual Basic 6, and some of the major applications even had object-oriented characteristics. In addition to XP practices, Bob helped the team learn java and “real” object-oriented programming. Extreme Programming turned out to be an excellent fit with the culture of Humboldt Merchant Services. The first project, which was a complete rewrite in java of an existing application, was going very well. Test-Driven Development proved extremely useful as the new code was extensively refactored during the first few iterations as the team applied their ever-increasing skills in applying design principles and java. But there was a significant problem that the team would have to face sooner or later. The legacy Visual Basic (VB) code would have to be made testable to support required enhancements and bug fixes. A surprise change by a major vendor provided the first opportunity. Humboldt Merchant Services(HMS) had in place a bridge application that used a 3270-emulation Active-X object to send data from HMS computers to the major vendor’s mainframe. The output screens were rearranged and the application needed to be changed to support the new output formatting. Ann went to Bob for help. !|Ann| There aren’t any tests for the code and nobody on the team can figure out how to add tests. Can you provide any guidance?| |Bob|'' Sure. Run, don’t walk, to the book dealer of your choice and buy a copy of my colleague Michael Feathers’ book, Working Effectively With Legacy Code. The book covers a lot of techniques for getting tests in place in legacy code.''| |Ann| Yes, I read it. It’s an excellent book and covers a lot of valuable techniques, but it really doesn’t address the kind of problem we face with our VB code.| |Bob|'' What kinds of problems are you having?''| |Ann| Michael assumes that we’re working in a real programming language like C++ or Java. We need to work with VB. I can’t figure out how to apply the techniques in his book.| |Bob|'' Sadly, I don’t have any experience with VB, so we’ll have to tackle this problem as a team. You supply the VB knowledge and I’ll supply the testing, design, principles, and patterns knowledge. ''| |Ann| Okay, sounds good.| |Bob|'' Is VB Object Oriented?''| |Ann| I’m not sure how to answer that. It has objects, but what does it really mean to be Object Oriented?| |Bob|'' That’s actually a deceptively hard question, let me rephrase it. Does VB have the capabilities of encapsulation, inheritance, and polymorphism?''| |Ann| It doesn’t have inheritance. It is possible to implement polymorphism, I remember reading about this, anyway, but we don’t use it.| |Bob|'' How does it do polymorphism without inheritance? I’m coming from a C++ and Java background where the languages use inheritance to achieve polymorphism. ''| |Ann| I think you have to implement an interface to get polymorphism in VB. But we don’t use interfaces either.| |Bob|'' That’s actually very good news. If we can insert some interfaces into the VB code, we can create Object Seams, like Feathers describes in his book.''| |Ann| Back to the problem at hand: getting tests into our legacy code for our bridge application. It would be great if we could fake out the ActiveX control so that we could test our code without actually having to send data to the mainframe. I’d like to have a testing implementation of the interface to be sure our code is working. | |Bob|'' It sounds like you remember a lot from the XP class. You know how we want the code to be structured so that it’s testable.''| |Ann| Yes, I can visualize it, but I can’t figure out how to write the VB code to accomplish this. So what good will VB having interfaces do us when we don’t have the source code to the to the ActiveX control? We can’t change it to implement an interface. We bought it and all that we can do is use it by calling its functions.| |Bob|'' I’m sure there’s a lesson in there about buying components without the code.''| |Ann| Thanks, Bob (said with sarcasm). Lesson learned. But we can’t go back in time.| |Bob| ''Right. A picture is worth a thousand words so let me sketch out where we are and where we want to go. We have this:''| !img http://butunclebob.com/files/AdapterVBArticle/Drawing1.jpg !|Bob|'' And we want this:''| !img http://butunclebob.com/files/AdapterVBArticle/Drawing2.jpg !|Bob|'' Did I capture what you have and what we want correctly?''| |Ann| Yes you did. But I noticed that you don’t have the 3270 connected to anything. Remember that we don’t have the code and can’t make it implement the new Display interface. | |Bob|'' I want to be sure that we can actually use the Display interface and the FakeDisplay implementation. Is that possible in VB?''| |Ann| Yes, I believe that it’s possible.| |Bob|'' Okay then, for the last piece of the puzzle, we’ll use the Adapter Pattern like this:''| !img http://butunclebob.com/files/AdapterVBArticle/Drawing3.jpg !|Ann| I remember that from one of the talks you gave to the team. The Adapter Pattern solves the problem of converting a message with one name into a method of a different name. That’s not exactly what we have here; the method names are the same.| |Bob|'' Yes, but the methods are in different classes, so you can think of the fully qualified method name as changing. What matters though is that it works. You weren’t able to have the 3270 implement the Display interface so we used the Adapter Pattern to delegate to the 3270. We’ve created a point in ExistingCode where we can change the behavior without further editing of the code. This is an Object Seam like Feathers describes in his book.''| |Ann| Yes, I see that. I have a question though. How does the existing code know whether to call the FakeDisplay for testing or the 3270 when we are in production?| |Bob|'' That’s the whole point of polymorphism. The existing code neither knows nor cares what type of Display it’s using. It is known only as the interface type.''| |Ann| Let me rephrase: how does the FakeDisplay get instantiated for testing and the 3270 when we are in production?.| |Bob|'' That’s the other half of the seam definition. A seam has an enabling point. The TestHarness will instantiate the FakeDisplay and the production code will instantiate the real deal. What I’m calling ExistingCode is manipulating a Display, it doesn’t know the specific type, so it doesn’t care which one is passed to it.''| |Ann| How does it get passed? There are no such things as constructors in VB like there are in Java.| |Bob|'' Can’t I just add an addDisplay() method to ExistingCode and use it to provide the Display it should use?''| |Ann| That should work. I think that I have more bad news that I’ve been trying to find the right time to tell you. The 3270 Emulator is actually a control that must be dropped onto a VB form object. The Display interface must be passed a variant object that will be defined as a VB form object in the implemented adapter interfaces.| |Bob|'' Ugh. Too many VB terms that I don’t understand. Is a VB form a class?''| |Ann| Yes. And it’s central to everything we do in VB. You might say it puts the V into VB.| |Bob| ''Cute. So the 3270 Emulator sits on a Form that is handed to existing code, is that correct?''| |Ann| Yes.| |Bob| ''Does that change the basic idea of the technique that I'm suggesting you try?''| |Ann| I don’t think it does – it’s just a VB thing. I guess it doesn’t matter as much as I thought it would.| |Bob|'' Does it sound like it’ll work?''| |Ann| It looks like it will, but as you’ve said many times, only the code will show if it works or not. I can’t wait to try it.| |Bob|'' Will you buy me lunch first?''| |Ann| Sure, where shall we go?| |Bob|'' When in Eureka, CA., there’s only one place for lunch. Porter Street BBQ. Awesome sandwiches.''| --- !commentForm !* Sun, 1 Jan 2006 03:19:27, day, CAL http://www.heleie.com provide recently info. *! !* Wed, 8 Mar 2006 12:46:20, myself, I am learning the course from Bob right now. *!
Use alt+s (Windows) or control+s (Mac OS X) to save your changes. Or, tab from the text area to the "Save" button!
Grab the lower-right corner of the text area to increase its size (works with some browsers).