Skip to content

Add C++ refactoring examples (C++23/26)#118

Open
chibi-dogs wants to merge 9 commits into
RefactoringGuru:mainfrom
chibi-dogs:add_cpp_examples
Open

Add C++ refactoring examples (C++23/26)#118
chibi-dogs wants to merge 9 commits into
RefactoringGuru:mainfrom
chibi-dogs:add_cpp_examples

Conversation

@chibi-dogs
Copy link
Copy Markdown

Summary

This PR ports some of the existing examples in Java to C++. I have added before and after examples for the following 3 techniques:

  • Extract Method
  • Extract Method – Isolate Switch
  • Substitute Algorithm

All examples compile when tested with clang trunk and using C++26. The before files are a direct, idiomatic C++ translation of the Java originals. The after files apply the refactoring and additionally adopt several modern C++ idioms where I felt appropriate.

Design decisions & deviations from Java originals

I was having trouble porting some of the solutions to C++ since many things that may be considered idiomatic in Java don't necessarily have 1 to 1 mappings in C++. I made the following decisions:

Substitute Algorithm

  • before: raw if-chain returning "" on failure — true to the Java original
  • after: replaces the chain with std::ranges::find_first_of over a static constexpr std::array<std::string_view>, and returns std::optional<std::string> instead of an empty string sentinel.
  • Rationale: empty-string-as-failure has no idiomatic equivalent in modern C++ so I used std::optional. I think that using ranges find_first_of is really nice since it expresses the algorithm's intent quite clearly.

Extract Method – Isolate Switch

  • before: raw loop + switch on an enum, applying a discount factor
  • after: replaces the switch with std::variant + std::visit over typed discount structs, each holding a static constexpr double factor; total is computed via std::ranges::fold_left
  • Rationale: C++ has no pattern matching to the best of my knowledge unless you just use if/else with strings. I therefore decided to use std::variant + std::visit which also would fit Replace Conditional with Polymorphism quite nicely.

Extract Method (basic)

  • std::print might not work for older versions of C++ and certain compilers.
  • std::cout << std::format() << std::endl would work even for older versions of the language and compilers so it might be a better choice. But I decided to go ahead with std::print since the name carries the intent a lot better in my opinion.

Notes

  • Targets C++23/26 (std::print, std::ranges::fold_left, std::ranges::find_first_of, std::span)
  • Added [[nodiscard]] when appropriate even though it adds some "noise". I added it to the signature of all functions that return values since looking at clang tidy complaining about it was stressing me out 😅

Happy to discuss these design decisions! 😄

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant