UGA Boxxx

つぶやきの延長のつもりで、知ったこと思ったこと書いてます

【Design System】デザインシステムに関するインタビュー記事

デザインシステムの構築と運用に関するインタビュー記事

spctrm.design

Spectrum Tokyoの三瓶さんと、Figma Japanの谷さんとDMM.comの河西さんの座談会

デザインシステムの背景、その構築と運用に関する実体験、そしてデザインシステムの普及がデザインの未来にもたらす変化について掘り下げて語っている

  • デザインシステムは、エンジニアリングとの連携強化、多様なデバイスやメディアへの対応を可能にし、効率的なデザインプロセスを促進
  • デザインと構造の分離の考え方が普及し、デザインシステムは「見た目と構造を分離する」という潮流の中で期待を集めている
  • カラーパレットやコンポーネント集を「デザインシステム」と定義することは議論の余地があるが、組織内でのアセットの組み合わせが機能し、その組織の文脈で「デザインシステム」と呼ばれているならば、それは適切かもしれない
  • デザインシステムの構築・導入を考える上で重要なのは、規模感や関係者の範囲を考慮すること
  • 「Atlassian Design System」のような巨大なデザインシステムを模倣することの落とし穴として、本来目指すべきものを見失い、プロジェクト自体が目的化してしまうリスクがある
  • デザインシステムは、一夜にして作り上げるものではなく、その構築と運用には相応の時間とコストが必要であり、組織の規模やフェーズ、現場の課題感に合わせたツールセットが求められる
  • デザインシステムは「共通言語」の確立に貢献し、デザイナー、エンジニア、マーケターなどが関わりやすくなることで、プロダクトの品質や生産性の向上、学習コストの削減に寄与する
    しかし、その運用フェーズになると、「デザインシステム警察」といった問題が生じる可能性があり、組織全体で「より良い議論の基盤としてデザインシステムを活用する」志向性を持つことが重要
  • 最終的には、デザインシステムを実質的に活用し、組織全体で利用するプロダクトとして定着させることが成功のカギ

だいたい同じような感想を持っていて良かった

【Git】git commit --fixup 知らなかった

「squash & merge」対応していない現場で、ローカルで作業してて追加でコミットしたものをあるコミットに混ぜたい場合、これまでrebaseしてsquashしていたのだが、コミット時に--fixupをつけておくと簡単にできるみたい

squashだと毎回コミットコメントの記載を求められるのは地味に面倒だが、fixupは指定したコミットに混ぜる前提なのでコミットコメントの入力は求められない

コミット時に以下のコマンドでコミットする

git commit --fixup <HASH>

追加の修正をし、追加のコミットをする際に、--fixup <HASH> を使う

引数にはまとめたいコミットのハッシュ値を指定する

$ git add .
$ git commit --fixup 9c57cb3e7a

コミットすると以下のようにfixup!がついている

$ git log --oneline
084069f (HEAD -> main) fixup! wip
9c57cb3 wip

これでrebaseをすると、自動的に指定のコミットに混ぜてくれる

やってみたが、--fixupをつける方が手間かもしれない、、、

git rebase -> git squash の流れで手が慣れているので、あまり使わないかもしれない

【Zod】Always-Valid Domain Modelを実装する話

ZodでAlways-Valid Domain Model を実現する話し

zenn.dev

Always-Valid Domain Model とは

  • ドメインモデルがそのライフタイムにおいて常に有効な状態を保つように設計されるアプローチ
  • ドメインモデルの不変条件をクラスのコンストラクターやメソッドを通じて強制し、不正な状態になることがないようにする
  • これにより、アプリケーションの堅牢性が向上し、ランタイムエラーの発生が減少する

ドメインモデルの有効な状態とは、例えば「数量」における「自然数」で「上限付き」が検証されていることを指す

このAlways-Valid Domain Modelの考えは、RefinementsとBranded Typeという2つの方法論を実装すると実現する

  • Refinements(値の制約): 例えばnumber型に「自然数」「上限付き」の制約を加えた値として表現すること
  • Branded Types: (同じ構造の型を区別する): 「価格」などの他のnumber型と混同されないように、これらの数値を型レベルで区別する

それぞれzodを使って実装できる

  • Refinementsはzodの本領なところだと思おうので説明は割愛
  • Branded Typesはzodのbrandを使うと実装可能なことを知った

他に記事での気づきは、Result型の定義にNeverThrowを使っているところ

github.com

これまで自分で定義していたので、これに置き換えるの良さそう

ドメインモデルを検査し、それをイミュータブルに保つやり方の良い参考記事だと思った

【組織づくり】ポジションをつくらない組織づくり

昨日書いたCTOの役割変化の話とはうって変わって、そもそもポジションをつくらない話も面白かった

zenn.dev

以下まとめ

なぜポジションをつくらないのか?

  • 特定のポジションがあるとそのポジションを目指すことが社内で正当化されちゃう
  • 会社のビジョンと個人のビジョンがポジションを設けることによって変わってしまう恐れがある

「期待合わせ会」で期待値調整

  • 今期自分がやること
  • 他の人に頼ること
  • 心配ごと
  • こういう時は助けて

大きく2通りのエンジニアキャリア

  • 事業を前に進めるエンジニア(Ace)
  • 事業を進めやすくするために仕組みを整えるエンジニア (Captain)
  • AceとCaptainの両輪でプロダクトづくり

プロダクトや技術スタックなどの意思決定

  • その都度リードしたい人が素案をまとめて、チームと相談して決める

ポジションが欲しくなったら

  • 「PdMっていらないんだっけ?」ってなったらそのポジションに期待することを言語化
  • それはそのポジションをつくらないと解決できないことなのかを考える

基本的に自分で考え、チーム内で期待と役割を調整し、チーム全員で協調しながら実行できる人がいないと厳しい気がするが、そのような人たちが集まったなら確かにポジションなしでやれるかもしれないと思った

【組織づくり】CTOとしての役割の変化の事例

CTOという役割がどのように変化していったかの事例がとても参考になった

speakerdeck.com

CTOの役割の変化が以下のように変わっていったという話

開発 -> テックリード -> PdM/PjM -> 採用

変化の軸は企業価値最大化という目標に対して、一番ROIが高そうな仕事をすること
企業価値とは時価総額+有利子負債
 これを最大化させ、持続的に事業を成長させ資本市場から評価いただく必要がある
 →ミッション・ビジョン実現のため
→最大化につながる仕事を判断するために
 →事業計画の要素分解でボトルネックを探る
  →売上目標・粗利・営業利益などを理解

他に参考になったのは以下のテンプレートで、その役割の時に何をやっていたかがわかりやすかった

例えば2020年は

当時の状況
経営 CEO/COOに全振り
開発業務 とにかく早くプロダクトリリースするために機能開発
プロダクトマネジメント 店舗へ行ってヒアリングしたデリバリーサービスのAPI仕様を確認したり
プロジェクトマネジメント タスク管理はほぼやらず自律的に開発。デイリーMTGのみ実施
ピープルマネジメント Twitter DMやリファラルを活用して採用活動
テクノロジーマネジメント
CS 経営陣3人で24h365d電話対応

で、2023年~は以下になったとのこと(その間もある)

当時の状況
経営 組織・事業拡大に伴い経営チームでの会話内容増加。CTOとしてプロダクト戦略や採用計画の検討
開発業務 自分で手を動かすことはほとんどない
プロダクトマネジメント 業務文書を定義して社内メンバーに権限移譲
プロジェクトマネジメント 業務文書を定義して社内メンバーに権限移譲
ピープルマネジメント とにかく採用
テクノロジーマネジメント 新プロダクトはテックリードに。一部の重要な開発のみ相談
CS なし

自分もこれを参考にまとめてみようと思う

【サービスデザイン】サービスブループリント

以前あるイベントで拝見した、樋口さんのスライドで「サービスブループリント」が紹介されていたので調べた

speakerdeck.com

スライドでは

ビジネス・サービスに関係する全てのステークホルダーのタスクと連携を可視化し、フロントヤード・バックヤードの課題抽出や最適化に活用するためのツール

とある

Miroにテンプレートがあった

サービスブループリントとは?作り方と例【テンプレート付き】 | Miro

自分なりにサービスブループリントをまとめると、

  • 1984年にリン・ショスタックによって考案されたフレームワーク
  • サービスの設計、分析、改善を目的としたツール
  • 顧客の体験(カスタマージャーニー)を視覚的に表現し、サービス提供の背後にあるプロセスや相互作用を明確にする
  • これにより、企業や組織は顧客にとって価値のあるサービスを効率的かつ効果的に設計、実施、管理できるようになる

サービスブループリントの主な要素

  • Customer Actions: 顧客がサービス利用時に取る行動を時系列に沿って描写
  • 接点(タッチポイント): 顧客がサービスと直接接触する点
    ウェブサイト、店舗内の案内板、顧客サービスとの会話などが含まれる
  • 可視化ライン(ライン・オブ・ビジビリティ): 顧客から見えるサービスの要素と見えない要素を区分けする
    このラインより上が顧客に直接見える部分、下が内部プロセスになる
  • 内部相互作用: 従業員やシステム間の相互作用を示す
    これには、顧客には直接見えないサポートプロセスや裏方作業が含まれる
  • サポートプロセス: サービス提供を支える裏方のプロセス
    在庫管理や配送、ITサポートなどがこれに当たる

サービスブループリントの作成手順

  1. サービスの範囲の定義: 分析するサービスの範囲や目的を明確にする
  2. 顧客の行動のマッピング: 顧客が取る行動を時系列に沿って列挙する
  3. タッチポイントと物理的証拠の識別: 顧客がサービスとどのようにして接触するか、そしてその証拠を特定する
  4. 内部プロセスのマッピング: 顧客の体験を支える内部の相互作用とプロセスを識別し、マッピングする
  5. 分析と改善の機会の特定: ブループリントを使用してサービスのギャップや非効率性を特定し、改善の機会を見つける

サービスブループリントでサービスの全体像を理解し、改善点を発見するためツールだとわかった

ただ、実践してみないとやり方がいまいちわからないので練習してみる

参考

サービスブループリント:定義 – U-Site

【システム開発】一般的に普及してるレイヤーを使用した設計はソフトウェア設計として破綻しているという話

一般的に普及してるレイヤードパターンの設計はソフトウェア設計として破綻しているよという話

medium.com

理由

  • レイヤーというのは何らかを抽象化したものをさすが、レイヤー化することが抽象化したことにはならない
  • 一般的に普及してるレイヤー化は機能依存していて、テスト容易性も可読性も拡張性も下げている

一般的に普及してるレイヤー化というのは、例えば以下のようなレイヤーに分けることをいっている

  • プレゼンテーション層
  • アプリケーション層
  • データ層

OSIの7階層との違い

抽象度は、大きな処理の流れを簡潔に表したものが「抽象度が高く」、より具体的な処理の流れを表したものは「抽象度が低い」

OSIの7階層はその定義通りに抽象度で階層わけされている

一般的なレイヤー化をもう一度見ると、このように階層わけされているわけではない

プレゼンテーション層 は アプリケーション層 の大きな処理の流れを関係に表したものではないからだ(他の層もしかり)

つまり、「レイヤー」という名前がついているが「レイヤー」じゃない残念な感じになっているよねと

なんて呼ぶ?

OSIの7階層よりも、レイヤードデザインパターンの「レイヤー」の方が市民権を得ているので、OSIの7階層のようなレイヤーに別の言い方をしたい

そこでこれを「Strata」と呼ぶことにする

関数型プログラミングではすでに「Stratified Design」という階層化の名前が使われており、そこから引用したとのこと

一般的なレイヤー分けの依存関係

一般的なレイヤー分けは上位レイヤーに依存している

これをよく制御の反転や依存関係の反転のような原則を用いたりして、設計上は抽象レイヤーのみに依存しているように見えるが、実装ではモックや依存注入などのツールが必要で完璧には覆い隠せていないことが多い

また、依存注入などを使うと全体が見えなくなるので迷子になりがち

コードで表すとこうなり

public static void Main(string[] args) {
    var data = new DataLayer();
    var business = new BusinessLayer(data);
    var presentation = new PresentationLayer(business);
    presentation.Show();
}

それぞれのテストに依存するレイヤーのオブジェクトが必要になる

Stratified Design

Stratified Designでは以下のように実装する

public static void Main(string[] args) {
    var data = new Data();
    var business = new Business();
    var presentation = new Presentation();
    var app = new App(presentation, business, data);
    app.Run();
}

各レイヤーはどこにも依存しておらず、最後のnew Appでアプリケーションの最上位層を表している

中を覗くと

public void Run() {
    var text = presentation.Ask_for_text();
    var n = Count_words(text);
    presentation.Display_word_count(n);
}

このようになっており、プロセス全体の概要を把握できるようになっている

さらに、Count_wordsや、Ask_for_textDisplay_word_countの詳細を知らなくても実行できるようになっている

そして、詳細をみても同じような構造になっている(さらに抽象化された関数があり入れ子になっている)

図にするとこう

ノードの関数は詳細な関数を「統合」しているだけで、リーフの関数に「ロジック」がある状態になっている

これを統合操作分離原則 (Integration Operation Segregation Principle: IOSP)というらしい