
Explore refactoring to design patterns by starting from the problem domain, transforming a complex subtitle generation tool into a maintainable solution that uses design patterns.
Explore how incremental growth creates poorly factored code that's hard to maintain, then follow a live refactoring toward cleaner design, including captions and subtitle handling.
Identify how to refactor a large parse function into smaller, cohesive parts, cleaning text, breaking sentences and long lines, and estimating duration, without changing its behavior.
Identify concrete refactoring targets to make the captions building process flexible and extensible, introducing a captions builder and applying decorator, strategy, and visitor patterns for output formats.
Explore how to refactor an existing, operational application toward design patterns, preserving behavior while improving internal design to accommodate future features.
Discover why proper naming and namespace organization matter in refactoring to patterns, aligning class names like subtitles with business concepts to improve domain readability and maintainability.
Refactor a console application by defining separate namespaces for presentation, domain, and infrastructure, adopt the model-view-presenter pattern at the top, and blend domain-driven design patterns with a pragmatic design.
Refactor the project structure by introducing presentation, domain, and common namespaces, moving domain-related classes, applying MVP with a domain model, and renaming the root namespace to SubtitlesConverter.
Learn why refactoring tools like ReSharper and Visual Studio are essential for project-wide changes, updating namespaces and using directives, and find all references to ensure code still compiles.
Learn to name classes after domain concepts, improving readability and maintenance, as you rename captions to subtitles and CaptionLine to SubtitleLine using refactoring tools like ReSharper for consistent scope-safe updates.
Explore naming strategies for related classes like LineBreaker and SentenceRules, then refactor to Breakers and organize extension methods in a common namespace with EnumerableMinimum and WithMinimum or WithMinimumOrEmpty.
Explore how to name classes and structure namespaces while applying model-view-presenter and domain-driven design, isolate infrastructure concerns, and prepare for behavior extraction with strategies for decoupling.
Identify hard-coded function calls and decouple them by making each transformation explicit, then apply the strategy pattern to turn algorithms into interchangeable objects for runtime variation.
Learn how to refactor a tightly coupled cleanup call into the strategy pattern by extracting an interface and a LinesTrimmer class, then decouple callers with an Execute method.
Explore implementing stateful strategies by converting concrete operations into interchangeable text processor strategies with a shared ITextProcessor interface, using the Execute method and keeping strategies short-lived for safe, flexible refactoring.
Learn how the null object pattern acts as a strategy within the strategy pattern to make optional steps in text processing, enabling a do-nothing strategy that preserves correctness.
Explore refactoring tactics by applying the strategy pattern to decouple callers from callees, using null strategy for optional processing and preparing wrappers for future flexibility.
Refactor a short text-processing pipeline by modeling a chain of processors and applying composite or decorator patterns to unite equally typed strategies.
Explore the composite design pattern by treating a group as one item to sum price, tax, and weight, using composition functions and strategies to hide complexity behind a single interface.
Explore building a pipeline of text processors by chaining strategies with a composite pattern, implementing an ITextProcessor interface and using a LINQ-like aggregate to execute all transforms.
Understand the drawbacks of the composite pattern, including how it can create tree-like structures and hidden complexity, and learn how to maintain a linear pipeline when appropriate.
Discover the decorator pattern by wrapping an object with additional behavior that the caller doesn't see, including discounts and taxes, while preserving the same interface.
Learn to wrap text processors with the decorator pattern, using a ChainedProcessor and a Then extension method to chain ITextProcessor objects while purging null objects.
Move functions to objects to enable manipulation and processing through an interface, using composite and decorator patterns to wrap objects and support chainable text processing, leading to the builder pattern.
Identify the need for a builder to simplify constructing timed text and subtitles, refactoring the parse method into a SubtitlesBuilder that orchestrates the complex building process.
Learn how to prepare the ground for the builder by refactoring a complex text-to-subtitle process into discrete, timed text objects and a duration-aware pipeline.
Extract a SubtitlesBuilder to build valid subtitles objects and accumulate text for the final build. Refactor to use strategy-based text processing with DoNothing, Chain, and Pipeline patterns.
Learn how to structure namespaces to prevent circular dependencies across domains, models, and text processing, and keep implementations organized with a clear, directed dependency flow.
Explains how the builder pattern wraps complex object construction, enables declarative demands and a valid build order, with a text-parsing example and a warning about premature introduction.
Identify and remove infrastructural concerns from the domain by refactoring towards design patterns, moving file system access and parsing logic out of domain boundaries to improve maintainability and flexibility.
Introduce an infrastructure layer to decouple the domain from low-level concerns, and define simple data loading and saving interfaces for dependency injection.
Isolate infrastructural code by extracting a text file reader into its own class and interface, so the subtitles builder relies on a read method and a null object for empties.
Move infrastructural code to the infrastructure layer, decoupling domain from file system with a text writer interface and a concrete implementation, demonstrating mvp and domain-driven design benefits.
Isolate infrastructure code with inversion of control and dependency injection so the consumer defines interfaces and swaps implementations at run time, while presentation and infrastructure depend on the domain layer.
Identify domain rules and convert them into small, isolated objects that collaborate at run time. Explore a rule engine that splits text into sentences and selects the shortest output.
Replace the engine with explicit, autonomous rule objects and an evaluator that selects and executes polymorphic rules to produce zero or more results.
Replace raw rule specifications with concrete rule objects and a two-way splitter, turning rule specs into reusable rule classes. Remove old specifications as the engine adopts concrete rules.
Wraps a sequence of rules into a single composite rule, revealing a common strategy signature with splitters and supporting the shortest left wins approach.
Wrap a two-way splitter into a multiway splitter with an adapter, applying the rules pattern and rule composition to create a maintainable sentence-breaking solution.
Explore the rules pattern, a strategy-like approach that encapsulates business rules in single rule objects and, with composite and adapter patterns, removes complexity from domain classes.
Learn how to detach formatting logic from a domain model by applying a design pattern for unrelated behaviors, using mixins and extension methods, with practical notes from the subtitles example.
Introduce the visitor design pattern to add a behavior to a class hierarchy via a visitor object and per-class visit methods.
Explore extending the visitor idea to structural inspection of complex objects, including composition and run-time structures, by visiting inner parts in a defined order.
Implement a structural inspection visitor to format subtitles for srt output within a refactored subtitles model, renaming subtitle line to TimedLine and enabling the Accept method.
Implement the concrete visitor to write subtitles in SRT format using a text writer and append lines, managing index. Demonstrate the visitor pattern turning behavior into objects for runtime selection.
Discover the visitor pattern to extend a class with new behavior without modifying it, and explore structural inspection, a variation that traverses an object's internal structure with concrete visitors.
Extend the rules system by refactoring the two-way splitter into a composite of rules using the decorator pattern, factory functions, and a null object, improving maintainability and extensibility.
Push the rules system to its extreme by composing small, single-responsibility text transformations that split lines into sentences and trim endings, via the composition root for subtitles.
Introduce timed texts with offsets and update subtitles to process blocks with offsets, using state encapsulation and the visitor pattern to keep domain and infrastructure clean.
Design patterns turn text processing into a system of rules and rule objects. Well-separated, decoupled classes enable easy feature additions and localized changes.
Learn when to apply design patterns like strategy, composite, decorator, builder, visitor, and rules, and how they fit with MVP, DDD, and dependency injection for flexible, maintainable code.
This course begins with examination of a realistic application, which is poorly factored and doesn't incorporate design patterns. The demo application converts text into subtitles for videos, which makes it quite useful in practice. Yet, it is nearly impossible to maintain and develop this application further, due to its poor structure and design.
That is the point at which the course begins. As demonstration after demonstration will unfold, we will refactor this entire application, one function and one class at a time. During refactoring, many design patterns will fit into place almost without effort. By the end of the course, you will know how code refactoring and design patterns - one coding practice and one design practice - can operate together and help each other create great design.