Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Working with Android legacy code

Working with Android legacy code

Daniel Rotenberg

September 09, 2018
Tweet

Other Decks in Technology

Transcript

  1. The app takes forever to load anything if it loads

    it at all... Don't like how you don't have the option to use the mobile site they force you into using their slow app.. Sticking with the desktop service... How about put my money to good use and fix your app Here our journey began
  2. public Integer isOk(Object obj){ if (obj instanceOf Image){ Image objectAfterCasting

    = (Image) obj; int a = objectAfterCasting.created; int b = objectAfterCasting.fileSize; int c = objectAfterCasting.width; int d = objectAfterCasting.height; if (a> 968876155 && (b * 1024 >9 || b *1024 < 7) && ((c>300 || d>1000) ||c>d*2)) { objectAfterCasting.status = 2; .... errorHandler(6,obj); // another 60 lines of code!! You’re probably thinking of..
  3. Poorly written program, legacy code actually describes a code base

    that is no longer engineered but continuously patched How does the Community define Legacy code?
  4. “Code without unit tests” (Michael Feathers, Working Effectively with Legacy

    Code) How do the TDD developers define Legacy code?
  5. • Hard to maintain, improve, and expand Why is Legacy

    code challenging? • Difficult to read and follow
  6. • Stable • Secure • Feature Rich • High Performance

    Telegram Paradox • Confusing Names • God Activites • Huge Methods • Magic numbers VS
  7. • A (false) sense that a small addition to an

    already complicated logic, won’t make a difference Why do good developers extend messy code? • Broken window theory • More effort to fight existing state
  8. • Legacy code is better to be removed and avoided

    • Good developers write messy code I Hope that you’re convinced that:
  9. private void storeSelection() { new Thread() { @Override public void

    run() { android.os.Process.setThreadPriority (android.os.Process.THREAD_PRIORITY_BACKGROUND); // do some logic storeProblemSelection(); RecentBook recentBook = book.toRecentBook(); runOnUiThread(() -> recentTbsRepo.addBook(recentBook)); } } }.start(); } Legacy code @ Chegg
  10. @Override public void handleMessage(Message msg) { switch (msg.what) { case

    BookDataManager.ON_FAILED_SOLUTION: // Some logic if (msg.obj != null) { error = msg.obj.toString(); if (error.contains("Authenticate")) { // Some Logic } else { showSolutionsNotFoundError(PROBLEM); } } // ~ 15 Different states, Multiple Error states, Complex tangled logic } Legacy code @ Chegg
  11. “the process of changing a software system in such a

    way that it does not alter the external behavior of the code yet improves its internal structure” What is Refactor?
  12. • Increase code complexity during the process Why developers don’t

    refactor code? • Different Problems In code Highly Coupled • Dead lines
  13. • Legacy Code == Tech Debt How to Convince The

    Manager To Refactor? • Debt is usually reasonable only with low interest
  14. • Each test can cover a small increment of functionality

    • Small and ugly changes can be done to make the new tests run • Tests are run very Often • Many teensy-weensy steps make up the refactoring TDD Refactor Approach and Agile Practices
  15. Wait, Refactor messy code to… ? • Robust • Stable

    • Testable • Modular • Easy to Extend • Simplicity • Readability • Modularity • Layering • Design • Efficiency • Elegance Good Code Is
  16. • Small Git commits to the rescue Minimize Refactoring Risk

    • Code Review: two minds greater than one
  17. • Separation of Concerns “Good code is testable code. By

    that I mean it’s not code that has tests, but it’s at the very least code that you can write tests for.” Mike Nakhimovich What Common For All Android MVx Architectures? • Unit Testable code • Android classes logic free
  18. • Break to small methods Simple rules and advices for

    systematic refactor • Delegate • Give meaningful name
  19. public interface SolutionsContract { interface View{ void testView(); } interface

    Presenter{ void test(); } } Step 1: Architecture (MVP)
  20. public class SolutionsPresenter implements SolutionsContract.Presenter { private SolutionsContract.View view; @Inject

    public SolutionsPresenter(SolutionsContract.View view) { this.view = view; } @Override public void test() { view.testView(); } } Step 1 : Add Presenter “Skeleton”
  21. protected void loadChapters() { if (mBookDataManager.getChapters() == null) { Logger.d("chapters

    are NULL, request from server"); mBookDataManager.requestChapters(); return; } Logger.d("Chapters exist"); handleLoadedChapters(); } Find relative small method
  22. protected void loadChapters() { if (mBookDataManager.getChapters() == null) { Logger.d("chapters

    are NULL, request from server"); mBookDataManager.requestChapters(); return; } Logger.d("Chapters exist"); handleLoadedChapters(); } Break and Extract : Small Method
  23. private boolean chaptersLoaded(BookDataManager bookDataManager) { if (bookDataManager.getChapters() == null) {

    Logger.d("chapters are NULL, request from server"); bookDataManager.requestChapters(); return false; } return true; } Break and Extract : Meaningful Name
  24. public interface SolutionsContract { interface View{ void testView(); } interface

    Presenter{ void test(); boolean chaptersLoaded(BookDataManager bookDataManager); } } Delegate : First Add the method signature to “Contract”
  25. public class SolutionsPresenter implements SolutionsContract.Presenter { .... @Override public boolean

    chaptersLoaded(BookDataManager bookDataManager) { if (bookDataManager.getChapters() == null) { Logger.d("chapters are NULL, request from server"); bookDataManager.requestChapters(); return false; } return true; } } Delegate : Now the Same code moved to Presenter
  26. @Override public void onPickerItemSelected(int pickerType, int index) { bookDataManager.indexChanged(pickerType, index,

    (type) -> { switch (type) { case CheggPicker.CHAPTER: loadChapters(); break; case CheggPicker.PROBLEM: loadProblems(); break; Gain More Simplicity And Readability
  27. You spoke, we listened. In this update: · Load time

    improvements. So you can access Textbook Solutions sooner. · Bookmarking. Now you can access and manage your bookmarks from the app! Have feedback? We’d love to hear from you. [email protected] Release What’s New Section
  28. The app takes forever to load anything if it loads

    it at all... Don't like how you don't have the option to use the mobile site they force you into using their slow app.. Sticking with the desktop service... How about put my money to good use and fix your app Fixed loading issues I had previously with the app appreciate the follow up End Of The Journey
  29. "I am not a great programmer - just a good

    programmer with great habits." - Kent Beck. Simple Good Code Habits • Code style conventions • Small methods • Good Naming