Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Working with c++ legacy code


Published on

Legacy code is the bane of most developers. Even so in C++ where you can find code that was created more than a decade ago.
When a developer needs to add a feature or fix a bug in such codebase he's faced with a problem - how to add code to a mess without creating a bigger mess as well as additional bugs on the way?

In this talk I show what worked for me when working with large, undocumented piles of C++ code, the practices and patterns that I use and how to transform unmaintainable code into code that can be extended and improved.

Published in: Software
  • Be the first to comment

  • Be the first to like this

Working with c++ legacy code

  1. 1. Working with C++ Legacy Code Dror Helper | | @dhelper
  2. 2. Consultant @CodeValue Developing software since 2002 Clean Coder & Test Driven Developer Pluralsight author B: T: @dhelper About.ME
  3. 3. ¯_(ツ)_/¯ What is “Legacy Code”? Covfefe?
  4. 4. No longer engineered – continuedly patched
  5. 5. Difficult to change without breaking functionality
  6. 6. Written by someone else
  7. 7. Legacy code has users!
  8. 8. The good news and bad news There’s a lot of legacy C++ Code There’s a good chance you’re doing it C++ makes it easy to make critical mistakes C++ is a powerful language
  9. 9. Gaining control over legacy code To stop fearing legacy code: 1. Learn what the code does 2. Make sure it keeps doing it! 3. Iterative improvement via Refactoring
  10. 10. This is a unit test (GTest) TEST(HolyGrailTests, WhoWeAreTest) { Knight knight; ASSERT_EQ(“Ni!”, knight.Say()); }
  11. 11. A quick reality check • Code have dependencies • Refactoring == code change • Code change == breaking functionality (78.3%) • Breaking functionality  go home == false
  12. 12. Sensing and Separation public void SendEmailTest() { auto sut = new ... User user; sut->SendEmailToUser(user); // Sensing problem ASSERT??? } void SendEmailToUser(User user) { EmailClient client; // Separation problem client.Send(user.Email, ...); // Important business logic ... }
  13. 13. “My focus is to forget the pain of life. Forget the pain, mock the pain, reduce it. And laugh.” Jim Carrey
  14. 14. The problem - dependencies My Code DB Files Files Files Files Services
  15. 15. The solution – fake/mock objects My Code Fake Fake Fake
  16. 16. Fake objects using Google Mock class FakeRestApiClient :public RestApiClient { public: MOCK_METHOD2(HttpPost, void(string&, string&)); MOCK_METHOD1(HttpGet, string(string&)); MOCK_METHOD2(HttpPut, void(string&, string&)); MOCK_METHOD1(HttpDelete, void(string&)); };
  17. 17. Injecting fake objects into existing code
  18. 18. Not all dependency are created equal Some are harder/impossible to fake Non virtual methods Hard to inherit classes Static method calls Singletons Internally instantiated Heavy classes
  19. 19. Faking Singletons class MySingleton { static std::once_flag onceFlag; static MySingleton* instance; public: static MySingleton* GetInstance() { std::call_once(onceFlag, [] { instance = new MySingleton(); }); return instance; } private: MySingleton(){} }
  20. 20. Friend is your friend class MySingletons; class Rectangle { int width, height; public: friend FakeRectangle; };
  21. 21. Problem: un-fakeable methods • Static methods • Hard/impossible to instantiate class • Non-virtual methods Cannot be inherited == cannot be injected!
  22. 22. Using templates for injection Compile time duck typing a.k.a hi-perf dependency injection • Can fake unfakeables • Can fake internally instantiated classes
  23. 23. Faking Private and Protected Methods classFoo { public: virtualbool MyPublicMethod(MyClass* c){...}; protected: virtualvoid MyProtectedMethod(int a,intb){...}; private: virtualint MyPrivateMethod(){...} }
  24. 24. Faking Private and Protected Methods classFoo { public: MOCK_METHOD1(MyPublicMethod,bool(MyClass*)); MOCK_METHOD2(MyProtectedMethod,void(int,int)); MOCK_METHOD0(MyPrivateMethod,int()); }
  25. 25. Taking control of existing legacy code Legacy code  Write tests Create fake objects Swap dependencies Refactor & cleanup Maintainable code 
  26. 26. Thank you Dror Helper | @dhelper |