🧳

package by featureに関する記事や書籍のまとめ

2023/10/30に公開
1

最近、package by featureに関する記事やスライドが増えてきたように見受けられます。
この概念に対する調査、考え方、考察について、私の理解をまとめておこうかと思います。

今回は、簡単な説明と、起源と思われるものと参考記事をまとめます。
主に記事紹介をしつつ、合わせて関連概念を列挙します。

記事紹介だけで結構な量になったので、メリット・デメリット、実践方法等はまた別の記事を書く予定です。
[追記]

package by featureって要するにどういうこと?

アプリケーションのコードを、技術的な分類ではなく、機能や関心ごとにまとめて配置しよう!という設計(あるいは単にフォルダ分割の方法)の名称です。

簡単な例

技術的な分類(package by layer)
services, models, repositoriesといった、技術的なレイヤーの単位で分けられています。

package by feature
対して、こちらは、user, book, review, orderといった、オンライン書店アプリの機能に基づいて分類されています。

各々の比較、メリット・デメリット、導入や移行方法など、いろいろ考える範囲はあるのですが、主張としてはただこれだけで、難しいものではないと感じられるのではないでしょうか。

画像内テキスト

package by layer

online-bookstore/
├── services/
│   ├── UserService.ts
│   ├── BookService.ts
│   ├── ReviewService.ts
│   └── OrderService.ts
│
├── models/
│   ├── UserModel.ts
│   ├── BookModel.ts
│   ├── ReviewModel.ts
│   └── OrderModel.ts
│
├── repositories/
│   ├── UserRepository.ts
│   ├── BookRepository.ts
│   ├── ReviewRepository.ts
│   └── OrderRepository.ts
│

package by feature

online-bookstore/
├── features/
│   ├── user/
│   │   ├── UserModel.ts
│   │   ├── UserService.ts
│   │   └── UserRepository.ts
│   ├── book/
│   │   ├── BookModel.ts
│   │   ├── BookService.ts
│   │   └── BookRepository.ts
│   ├── review/
│   │   ├── ReviewModel.ts
│   │   ├── ReviewService.ts
│   │   └── ReviewRepository.ts
│   └── order/
│       ├── OrderModel.ts
│       ├── OrderService.ts
│       └── OrderRepository.ts
│
名称について

記事によって、各々の名前が微妙に異なる名前も見受けられます。今回は「package by feature」と呼びます。

前者
 - package by layer
 - package by type
 - 技術駆動パッケージング

  • ...

後者

  • package by feature
  • folder by feature
  • ...

誰がいい始めた?

明確な起源は不明ですが、おそらくJavaでの開発の際の設計のプラクティスとして言及されたものが最初と思われます。

また、そこから派生して、同種の概念はいろんな書籍や記事から述べられているようです。

コードをたくさん書いていれば同種の概念を複数の人が思い至る可能性も十分ありそうで、起源を定めるのは難しそうな印象があります。

直近でpackage by featureという名前でよく言及されるようになったので、この単語がより普及して、この手法に関する議論が集めやすくなれば良いなと思っています。

記事や書籍一覧

Java関連

package by featureの「package」はJavaでの開発での実践から由来しているようです。

Googleのindexによると、javapractices.comの記事は2006年からあり、私が知る限りで「package by feature」という名前が登場する最も古い記事です。
http://www.javapractices.com/topic/TopicAction.do?Id=205

他のJava文脈っぽいものです。

https://codepipes.com/presentations/feature.pdf

https://phauer.com/2020/package-by-feature/

有名どころ

エリックスエヴァンスのドメイン駆動設計

エリックスエヴァンスのドメイン駆動設計、第五章の中の「インフラストラクチャ駆動パッケージングの落とし穴」の節でも、同種の概念が述べられています。
原著が2003年出版であるので、同種の概念自体は古くから認識されていたのではないか、と思います。

書籍内では、「package by feature」という名前は出てきませんが、技術駆動(インフラストラクチャ駆動)でまとめる場合での問題点について述べられています。

出版年で考えると、上のJavaの記事よりも古いですし、もしかしたら、他のもっと古い言及は見つけられるかもしれません。
また、この書籍自体も、4GL系の言語に対してJavaが流行り始めた時代のものであったはずです。

Screaming Architecture

Screaming Architectureも、同種の概念と言えると思えます。
こちらは2011年です。
「叫んでいるか?」という観点が直感的で面白いですね。

先程のonline-bookstoreの例だと、user, book review, orderという名前は、オンライン書店アプリの構成要素に何があるのかを"叫んで"いるというわけです。
対して、services, models, repositoriesは、実装都合の話であり、そういったことを叫ぶべきではない、ということです。

ソフトウェアアーキテクチャの基礎

上2つと比べて新しめです。
ソフトウェアアーキテクチャの基礎の8.2.1 アーキテクチャの分割 あたりにも、この分割についてまとめられています。技術による分割とドメインによる分割が紹介されています。

Angular

Angularのstyle guideを書いた人による記事です。
https://www.johnpapa.net/angular-growth-structure/

そのスタイルガイドにも、Folders-by-feature structureという節があります。
https://angular.io/guide/styleguide#folders-by-feature-structure

日本語の記事、スライド

割と最近のものです。

https://speakerdeck.com/teppeita/hurontoentonoteirekutorishe-ji-si-xiang?slide=8

https://speakerdeck.com/77web/ta-ren-gahayakudu-merukodowoshu-ku-tameni?slide=16

https://qiita.com/honey32/items/dbf3c5a5a71636374567

https://zenn.dev/pandanoir/articles/d74d317f2b3caf

その他

2021年以降で探すとかなり多くの記事があるようです。

凝集性を交えながら述べられています。
https://medium.com/sahibinden-technology/package-by-layer-vs-package-by-feature-7e89cde2ae3a

https://medium.com/expedia-group-tech/package-by-feature-not-by-layer-5ba04a070003

group by featuresという名前と、Screaming Architectureを踏まえて述べられています。
https://dev.to/profydev/screaming-architecture-evolution-of-a-react-folder-structure-4g25#discussion-of-the-featuredriven-folder-structure

.NETの例。Angularの記事を引用しています。
https://medium.com/c2-group/simplifying-projects-with-a-folder-by-feature-structure-3a13cff2d28c

https://dev.to/sathishskdev/part-2-folder-structure-building-a-solid-foundation-omh

https://maestros.io/structure-by-type-vs-feature

バックエンド周辺

バックエンド周辺だと、モジュラーモノリスが近しい概念になると思われます。
この言葉自体は、マイクロサービスに対する揺り戻しの文脈も含めて使われているようです。

Railsでは、packwerkが有名なようです。

https://speakerdeck.com/shshimamo/monorisitukurailsapurikesiyonwo-moziyuramonorisuheyi-xing-siteiru-notenoshi-li
https://speakerdeck.com/shunsugai/railsdemodular-monolithwoxuan-ze-saretayu-she-nizhi-wen-sitainge-noyi-wen

Laravelでの実践紹介
https://zenn.dev/tyamahori/articles/c78838c4374656

フロントエンドで流行りはじめている?

最近の言及は、フロントエンドにおけるフォルダの整理方法として多いような気がします。
(ただし、これは私の主軸がフロントエンドであるからというのが大きそう)

バックエンドでもこの分割方法は便利であろうと想像しますし、実際いくつかリンクも張りました。

これは想像ですが、
バックエンドの場合は、そもそもフレームワークがpackage by layerを前提として普及しているものが多いのに対し、
フロントエンドは、以下のような理由で普及しやすいのかもしれません。

  • ファイルの配置方法にデファクトスタンダード、権威に相当するものが無いことと、
  • 最近だとNext.jsのApp Routerのように、フレームワークがpackage by featureが可能な仕組みになっていること
  • バックエンドと比べると、変更に対する心理的な障壁が少ない?

ツイートレベルの言及

https://twitter.com/VasiliyZukanov/status/1153583630138130432

"Package by feature" (or, after @unclebobmartin, "screaming architecture")

と書かれています。既に記事一覧で紹介したように、Javaの文脈で2006年からpackage by featureがあり、後にアンクルボブが2011にScreaming architectureという記事を書いています。

https://twitter.com/MinoDriven/status/1148960876201836546

https://twitter.com/adelie_pf/status/1627265417428504577

https://twitter.com/pomber/status/1633791118168006656

ツイートは私がたまたま見かけたものを貼っているだけなので、他にも同種のものも見つかるかもしれません。

キーワード一覧

package by featureと関連すると思われるキーワードを並べておきます。
上記の記事の中で触れられてるものとそうでないもの、どちらも含みます。

  • screaming architecture
  • 凝集、結合(cohesion, coupling)
  • modular monolith
  • 関心の分離(separation of concerns)
  • colocation

どのようにコードを分割配置するかというのは普遍的な話題であり、それが様々な条件や観点で、色々な概念の名称がつけられている、と理解すると良いのではないかと思います。


この記事の前身のメモ: https://scrapbox.io/miyamonz/package_by_featureの紹介事例

関連する情報がありましたら、コメントで教えていただけたら幸いです。

Discussion