
Acquire techniques to refactor legacy code into a well-tested, readable state through a case-study course, refactoring from Java to Kotlin and applying to languages like PHP and JavaScript with IntelliJ.
This domain problem lecture explains how prayer times are derived from sun positions. It guides refactoring a legacy prayer-time codebase, covering conventions, latitude effects, and testing as a first step.
Explore three books to guide refactoring legacy code, including Michael Feathers' working effectively with legacy code, Vladimir Koreshkov's unit testing principles, and Martin Fowler's refactoring.
Set up a Java project with Gradle and Kotlin configuration, configure Java 11, and write the first unit test using JUnit 5 to support refactoring of a prayer time calculator.
Learn how to improve unit test coverage for a prayer time calculator to support refactoring by fixing fixtures, using local dates, and adopting parameterized tests to approach near 100% coverage.
Learn to implement parameterized tests in JUnit 5 for a prayer time calculator, using CSV, value, and method sources with test data and converters to boost coverage.
Explore improving code coverage by adding tests and preparing for refactoring. Remove dead code and unused methods, guided by the agony principle, to reach 100% coverage.
Clean and refactor tests by extracting classes to a converters package, creating constants, and adding helper assertions to improve readability and maintainability of the prayer times calculator tests.
Explore mutation testing to evaluate and improve test quality by mutating code, measuring killed versus survived mutations, and using Pytest with Gradle to generate reports.
Convert the Java file to Kotlin using the shortcut, fix conversion errors, run safety net tests, and refactor by removing unused code and addressing warnings.
Explore why teams refactor legacy code for educational purposes, focusing on improving design, fixing bugs, adding behaviors or features, and optimizing performance.
Remove clutter from legacy code by using descriptive names, refactoring to replace comments, and renaming across the codebase to boost readability and maintainability.
Refactor large Kotlin files by using top level functions and extracting helpers into separate files. Move trigonometric functions to a separate file and use expression body.
refactor primitive obsession by replacing raw ints with enums and dedicated types in kotlin, using time formats and converters to improve type safety and clarify domain concepts.
Refactor by depending on abstract types instead of concrete implementations, swapping ArrayList for List and HashMap for Map to enable safe, performance-aware changes in large codebases.
Split a complex function to improve readability by extracting duplication, breaking calculations into dedicated helpers, and renaming variables for clarity while preserving tests.
Refactor legacy calculation logic by replacing a complex double array with a custom class and a sealed calculation method to clarify parameters for fajr, maghrib, and isha.
Master real-world refactoring techniques to improve legacy code structure and enable new features, while teaching others and helping the next generation of developers.
refactor legacy code by converting state-changing actions into pure functions, passing latitude, longitude, timezone, and julian date as explicit parameters to improve testability and ensure same outputs for given inputs.
Refactor the public API to be developer friendly by extracting classes to separate files and introducing a formatted prayer times object, with tests updated accordingly.
Pair programming pairs two developers on the same keyboard and screen to write code and critique ideas, improving refactoring outcomes and code quality through junior and senior collaboration and reviews.
Extract formatting logic from prayer time calculator into time format utilities and a time format class. Implement 12 hour and 24 hour formats with or without suffix, backed by tests.
Refactor the app's time format to remove duplication, introduce a configurable suffix and a without-suffix option, and consolidate formatting logic into a reusable helper.
Refactor the core logic for calculating prayer times by extracting julian date calculation, introducing a prayer times data class, and replacing arrays with a simpler approach, ensuring tests pass.
Refactor the core logic of prayer time calculations, extract functions, convert to arrays, and test step by step while tackling floating-point precision issues and high latitude adjustments.
Refactor the core logic for prayer times by debugging failing tests, gradually extracting and moving functions, and implementing time adjustments with high latitude methods and calculation parameters.
Refactor the core logic by extracting prayer time calculations into a dedicated class, introduce time offsets, and streamline formatting, while updating tests and public API.
Explore legacy code with scratch refactoring to understand complexity through small, exploratory steps. Refactor by renaming variables, extracting functions, removing clutter and comments, and clarifying time formatting.
Apply techniques from more than 20 videos of a refactoring course to clean up legacy code. Celebrate the course completion and share your honest review to help others find it.
Master The Art of Refactoring Messy Codebases Into a Software Masterpiece and Become the go-to expert for codebase transformations by learning to take messy code as an opportunity to innovate and grow.
But what is legacy code in the first place?
Legacy code refers to software code or applications that were created in the past and have been in use for a significant period. However, such code often poses challenges because it may be outdated, poorly documented, or not aligned with current coding standards and best practices. These challenges can make it difficult to maintain, update, or extend the software, thereby causing potential problems for developers to refactor to make it easy for future work.
In his Amazing book Working Effectively With Legacy Code, According to Michael Feathers, Legacy Code refers to any code that lacks automated tests: To me, legacy code is simply code without tests.
In this course, we will explore practical ways of dealing with legacy codebases. Our approach covers everything from automated tests to detailed techniques for making codebases flexible and enjoyable to work with.
By the end of the course...
You'll spot refactoring signals.
You'll be able to cover legacy code with tests.
You'll master refactoring principles and best practices.
You'll master techniques to improve the test coverage.
You'll identify common code smells and anti-patterns.
You'll confidently tackle complex legacy codebases.
Before You BUY This Course
If you're new to the world of code refactoring and looking for an affordable starting point, we recommend diving into specific books on the subject. Books (less than 60$) such as Refactoring or Working Effectively with Legacy Code provide a cost-effective way to build a strong foundation in refactoring principles, allowing you to learn at your own pace.
Once you're ready to put your knowledge into action on real legacy code, our comprehensive course guides you through practical application and advanced techniques, ensuring you're fully equipped to tackle complex code bases confidently.
What's the Use case?
In this course, we will refactor a codebase that calculates prayer times provided by Prayer Times Organization. We will address the challenges posed by outdated technologies, inadequate code organization, and the need to improve code readability.
With clear objectives in mind, we'll break down the refactoring process into manageable steps, including:
Code analysis.
Test setup.
Modularization.
Extracting meaningful abstraction.
Reducing the clutter.
Emphasizing best practices.
And much more.
The use case presents a good enough complex code to showcase the difficulties you can face when refactoring a real project. By the end of the course, you'll be well-prepared to take on real-world refactoring projects with confidence and expertise.
You can check the preview up in a video for a full explanation of the domain problem, so if that excites you, join now, and let us refactor a messy codebase.
Language Agnostic
This course is designed to be language-agnostic, meaning you can acquire essential principles and techniques that apply universally across various codebases in different programming languages.
While our use cases in the course choose Kotlin, you can still find on the domain problem website other versions that apply to Java, Python, C#, C++, and PHP; the skills and insights you gain are easily transferable to any other language.
We emphasize Kotlin to provide a practical learning experience, but the knowledge you acquire will empower you to excel in legacy code refactoring, regardless of your chosen programming language.