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

Refactoring Domain Objects with Scalafix

Refactoring Domain Objects with Scalafix

2023/04/15 ScalaMatsuri 2023 - Day1
Scalafix を用いたドメインオブジェクトのリファクタリング

Tweet

More Decks by Naoki Aoyama - @aoiroaoino

Other Decks in Programming

Transcript

  1. Agenda ❖ Introduction ❖ What / Why using Scalafix? ❖

    Case studies ➢ Leakage of behavior through the copy method ➢ Merging inherited class and typed patterns ❖ How to refactoring with Scalafix ❖ Conclusion アジェンダ。Scalafix を使うモチベーション、事例、実際にリファクタリングを行 う際のコツなどをお話しします。
  2. Challenge in modifying domain object We’re developing using DDD. Several

    years have passed since the release, and domain objects are being reviewed and modified. The domain layer code is used from many places. A single modification often affects dozens to hundreds of places. However, we cannot stop making modifications just because they have a wide scope of impact. 弊社のアプリケーションも例外ではありません。しかし、影響範囲が広いから といって修正の手を止める訳にはいきません。
  3. Challenge in modifying domain object It is always important to

    maintain code quality through refactoring of domain objects. We want tools that can give warnings through static analysis and perform safe and quick rewrites. いつだってドメインオブジェクトのリファクタリングを通してコードの品質を保つ ことが重要です。素早く安全に行えるようにしたい。
  4. What / Why using Scalafix? ❖ I often see discussions

    about adding or creating custom rules for Linting functionality, whether provided by official or third-party sources. ❖ Regarding Refactoring functionality, I often see discussions about providing migration tools for library-side changes that are incompatible. => Today, the main topic is writing disposable rules for Refactoring. 静的解析ルールやライブラリのマイグレに関する話題も多いですが、今日は 特にリファクタリング機能に注目します。
  5. What / Why using Scalafix? IDE's refactoring feature is very

    capable. ❖ It's incredibly convenient to work with just mouse clicks or keyboard shortcuts without having to write any code. ❖ On the other hand, it can't handle corner cases that involve complex conditions. Using scripting languages to apply methods such as regular expressions or string replacement is also convenient. ❖ Bulk replacement for specific patterns is very powerful. ❖ However, there is a risk of incorrect rewriting due to the inability to interpret the semantics. IDE のリファクタリング機能は優秀だが複雑なケースには対応できない。文字 列置換は強力だが意味論を解釈できず誤った書き換えが不安。
  6. What / Why using Scalafix? ❖ Matching for the rewriting

    target can be done against the abstract syntax tree provided by Scalameta. ❖ With sbt plugins, it is possible to integrate seamlessly with the build tool. ❖ The convenience of Patch objects that integrate refactoring and static analysis result notification. Scalafix は書き換え対象のマッチングを AST に対して行う。sbt とのシーム レスな連携、Patch オブジェクトの使いやすさ。
  7. What / Why using Scalafix? Scalafix is suitable for refactoring

    domain layers including domain objects. ❖ Manually rewriting many places carries the risk of degradation or omissions and should be avoided. ❖ In reality, knowledge of domain objects tends to leak out and become boilerplate code. ❖ Since it is widely used, writing rules and performing bulk replacements is cost-effective. Scalafix はドメインオブジェクトのリファクタリングと相性がよい。構文(意味論) での絞り込みによる安心安全、一括置換のコスパなど。
  8. 1. Leakage of behavior through the copy method 追加された deprecatedCopy

    へ、一括で対象となる旧シグネチャの copy メ ソッドをリネーム。
  9. 1. Leakage of behavior through the copy method deprecatedCopy に置き換える自作ルール。SemanticRule

    を用いてレシー バの型を特定し、対象の copy メソッドを確実に判定している。
  10. 1. Leakage of behavior through the copy method 結果的に after

    のコードへ修正することができた。
  11. 1. Leakage of behavior through the copy method ➔ It

    feels good that so many changes can be made from just a few dozen lines of custom rules, including some manual changes. ➔ Refactoring while maintaining a state where compilation and testing are successful can be quite challenging. ➔ If possible, let's keep the copy method private. 😂 コンパイル/テストが成功する状態を維持しつつ書き換えるのはなかなか大 変。できれば copy メソッドは隠そう。
  12. 2. Merging inherited class and typed patterns FooItem, BarItem は

    Item の子クラスで、それぞれ異なる振る舞いを持って いたがドメインモデルの変更に伴い Item に統合されることに。 abstract class Item class BarItem class FooItem
  13. 2. Merging inherited class and typed patterns アイディア勝負? FooItem, BarItem

    オブジェクトを作り unapply メソッドを追 加。Extractor pattern に書き換えた。
  14. 2. Merging inherited class and typed patterns 対象の Typed pattern

    を Extractor pattern に書き換える自作ルール。この ままでは再び Typed pattern が追加されてしまう可能性が残る。
  15. 2. Merging inherited class and typed patterns Patch.replaceTree を Patch.lint

    に書き換え、対象だったコードが今後追加 されたらエラーにするようなルールとして追加した。
  16. 2. Merging inherited class and typed patterns ➔ The code

    that was originally written and discarded became a rule for Lint as is. ➔ We added background information and reference links to the error messages to guide users. ➔ It is one of my favorite examples in this project. 😆 Patch オブジェクトが上手く抽象化されてるおかげで実現。書き捨てコードが そのまま Lint ルールに。お気に入りのケース。
  17. How to refactoring with Scalafix ❖ Imagine the final completed

    code. ❖ Imagining patterns becomes easier by manually rewriting the code once. ❖ Deepen your understanding of the AST. Tools like explorer or scalameta-ast are useful. ➢ https://astexplorer.net/ ➢ https://xuwei-k.github.io/scalameta-ast/ リファクタリング後の最終系をイメージする。一箇所でも手で書き換えると対 象範囲やパターンが掴みやすい。AST の理解も深めよう。
  18. How to refactoring with Scalafix ❖ Plan the order of

    rewrites carefully. ❖ Always maintain a state where compilation and testing are successful. ❖ Efficient progress depends on how many targets for bulk changes can be created. 最終系に至るまでの手順を検討する。各ステップで常にコンパイル/テスト可 能を維持。どうしたらより多く一括書き換えできるかのパズル。
  19. How to refactoring with Scalafix ❖ Keep custom rules for

    rewriting simple. ❖ Avoid complex rewrites and break them down into steps. ❖ It is important to make the rules themselves easy to review. ルールはできるだけ簡素にし、煩雑な条件でのマッチや複雑な書き換えは手 順を分けるなどして避ける。ルール自体もレビューしやすくする。
  20. Conclusion ❖ Scalafix is a highly suitable tool for refactoring

    domain objects. ❖ Introduced an example of using Scalafix for refactoring domain objects. ❖ Writing custom rules on the fly is convenient for refactoring. ❖ The learning curve is not cheap, but it is an incredibly useful tool for maintaining Scala applications. 弊社でのリファクタリング事例を紹介し、上手く進めるための Tips をまとめ た。Scalafix は最高のツールなので積極的に活用しましょう。