ContractS開発者ブログ

契約マネジメントシステム「ContractS CLM」の開発者ブログです。株式会社HolmesはContractS株式会社に社名変更しました。

スプリントプランニング〜虎の巻

この記事は Holmes Advent Calendar 2020 - Qiita 9 日目の記事です。

こんにちは。 Holmesでスクラムマスターをしている吾郷です。

今日はチームで行ったスプリントプランニング改善について振り返ります。 また、それにあたって最近アップデートがあったスクラムガイドも参考にしましたので、そちらにも触れながら自身の所属チームのHudsonのスプリントプランニングについて紹介します。

スプリントプランニング改善したい!という意見が出てきたのでチーム内でプランニングの目的や、やることを再定義する機会を設けました。

背景

自分が参加しているスクラムチームはHudsonといいます。 今年の1月からHudsonというチームで活動を続けています。 この一年の間で様々なTRYが生まれ、各イベントやスプリントで実施してきました。

課題

現在、スプリントプランニング内での実施項目が多く、アジェンダが曖昧。 (特にスクラムガイド2017内でいうプランニング二部) そのため、時間が足りなくなり、目的とするスプリントバックログ作成までできていない。

やったこと

スクラムガイドがアップデートされていい機会なので、きちんとガイドに沿うために読み合わせをする。 30分でトピック1からトピック3を読み、それぞれ気づいたことを共有・ディスカッション

結果

今回は、普段使用しているオンラインホワイトボードのmiroに整理したアジェンダを作ってみました。 結果としてはHudsonチームでは以下の分割・内容でプランニングを進めてみることにしました。 時間はトピック1と2に30分ずつ、トピック3に1時間を目安にしています。

f:id:seiseiholmes:20201214180248p:plain

トピック1:Why
プロダクトの価値の提案 from PO

基本的にはスクラムガイド2020のトピック1をそのまま採用しています。 まずはPOからプロダクトバックログの状況などを共有してもらいながら、どういったことがこのスプリントでできるとよいかを提案してもらい、 その提案をもとにスクラムチームでどういうスプリントゴールを設定するか議論します。

スプリントゴール決め(仮)

一通り意見が固まれば、仮案としてのスプリントゴールとして次のトピックに進んでいきます。

トピック2:What
アイテムの選択

直近のベロシティを確認しながら、どのアイテムを選択するかを話し合います。 また必要であればPBIをスプリントのサイズに分割したり、実装についての認識合わせをしたりといったリファインメントも行います。

Hotfix

また、現在HolmesではHotfixチケットについて、専任チームではなく状況に応じて各チームで対応を行っています。 そのため、対応すべきHotfixがなにかの認識合わせも行います。

スプリントレビューフィードバック検討

さらに、このトピック2でスプリントレビューでいただいたフィードバックの対応方針検討も行います。

トピック3:How

ここからは、各スクラムチームで色が分かれるところになると思いますので、参考にしていただけると幸いです。 基本的には、スプリントバックログを作成していく時間になります。 せっかくなのでアジェンダ内のTRYについても少し触れながら流れを説明します。 気になるアジェンダなどありましたら、ぜひコメントしていただければと思います。

モック確認・タスク作成

モックを確認しながら、現時点で必要な作業をまずは付箋に洗い出していきます。 この際、モックも必要なことがわかれば付箋にして作成していきます。

マッスルマーク

一通りの作業を洗い出したら、各曜日の午前午後に自分たちがスプリントに集中できるかどうかを一見してわかるようにマッスルマークというものを振っていきます。力こぶのようなものがそれです。下記画像参考

f:id:seiseiholmes:20201214185157j:plain

クラス名決め

さらにプランニング時点で想定できるクラス名を決めてしまいます。 ここで決めれば都度都度悩む必要がなくなりますし、誰でもすぐに作業に着手できるためです。

SBIの時間ふり

このあと、各付箋に予定時間をmiroのタグ機能を用いて設定していきます。 これによって、各曜日に置く付箋の量などを調整しやすく、 スプリント内における残タスク量も可視化しやすくなり、適応を促進してくれます。

ロードマップ調整

時間まで入力を終えるといよいよ最後にロードマップ決めとなります。 これまで洗い出した付箋にかかれた情報とカンバンをもとに、 一週間の中でどのようにスプリントゴールを達成するかを決めます。

スプリントゴール最終確認

ここで仮に想定していたスコープでは難しい・違ったといった気づきがあれば、量の調整やスプリントゴールの調整を行います。

以上が、スプリントプランニングトピックでHudsonが行っているものです。

まとめ

ガイドラインが新しくなり、自分もチームで一緒に読める機会が持てたのは非常に良かったです。 他のセクションに関しても、チーム内ないし開発内での読み合わせを行っていきたいです。

また、今回のワークでスプリントプランニングに対する共通認識を作れましたが、今後の経験を通してこのアジェンダも変化していくことと思います。 さっそく、定義後のスプリントで実践してみて、トピック3で時間が足らないなどのこれからの課題も見えてきています。

定期的にどういったプランニングをしているか続編としてブログにしたいと思います。

Holmesでは、スクラムを用いながらプロダクトを成長させ、契約に関する顧客課題解決を通じた価値提供をしていきます。 興味がある方はご連絡下さい。

lab.holmescloud.com

Haskellの型を触ってみた

この記事は Holmes Advent Calendar 2020 - Qiita 16 日目の記事です。


こんにちは。Holmesでインフラエンジニアをしている渡辺です。

Holmesでは社内LT大会が何度か開催されていて、趣味の話や技術話など業務に関係あることないことを持ち寄り、みんなそれぞれ好きなことを話しています。自分も発表に参加したので、ここではその時に自分が発表した内容を紹介できればと思います。

エンジニアであれば、自分が好きなプログラミング言語があるという人は多いと思います。自分が好きな言語はいろいろありますが、Haskellが好きなので今回はそれについてのお話です。

型について

大抵のプログラミング言語で扱える型としては以下のような物があると思います。

-- 文字列型
String s = "Hello, World"

-- 数値型(整数)
Integer x = 256

-- 数値型(浮動小数点数)
Double d = 3.14159265

-- 論理型(ブーリアン型)
Bool b = true

-- 配列型
List xs = [2, 3, 5, 7, 11]

通常取り扱うデータとしてはこのような型があれば普通のプログラムを書く分には困らないでしょう。ですが、例えば成功・失敗を表したい時にはどうするでしょうか。関数の結果として返り値で取得したい場合には構造体などのデータ構造を用いて取得する場合もあると思います。もしくは例外処理で対応することも可能でしょう。Haskellでは次のような書き方を使うこともできます。

Maybe型

失敗を返すかもしれない関数の並びから計算を構築できます。失敗はNothingで表現し、成功はJust a (aは任意の型)で返すことができます。

data Maybe a = Nothing | Just a

-- x が 2 で割り切れない場合には失敗する
div2 :: Int -> Maybe Int
div2 x = if even x
            then Just (x `div` 2)
            else Nothing

使用例は下記の通りです。ghciでの実行例になります。

ghci> :t Just 123
Just 123 :: Num a => Maybe a

ghci> :t Nothing
Nothing :: Maybe a

ghci> div2 6
Just 3

ghci> div2 3
Nothing

Either型

失敗あるいはエラー処理を構造化する例外処理をつかう関数のならびから計算を構築できます。失敗時にもただ終了するのではなく、エラーの内容から次のアクションを設定することができます。

data Either a b = Left a | Right b

head' :: [a] -> Either String a
head' [] = Left "empty list"
head' (x:xs) = Right x

使用例は下記の通りです。

ghci> :t Right 123
Right 123 :: Num b => Either a b

ghci> :t Left "failure"
Left "failure" :: Either [char] b

ghci> head' [1,2,3]
Right 1

ghci> head' []
Left "empty list"

さて、通常の型の使用方法としてはこれぐらいにして、もっと型を駆使して面白いことはできないでしょうか。

型レベル計算

Haskellは型の表現力が高く、型レベル自然数という物が扱えます。

まずは下準備として、今回の記事の書き方を使うにあたって必要なGHCの機能を有効化します。

{-# LANGUAGE FunctionalDependencies, MultiParamTypeClasses, UndecidableInstances, FlexibleInstances #-}

型でペアノ数を表していきます。Z は 0 を表します (zero)。S は (+1) を表します (successor,後者)。S Z は 1 、 S (S Z) は 2 という意味になります。

-- ペアノ数の定義
data Z
data S a

型クラスとそのインスタンスで関数を定義しています。

-- 型レベルの演算として加算を定義
class Add a b c | a b -> c

-- 0 + a は a になる
instance Add Z a a

-- a + b の結果を c に入れる
instance Add a b c => Add (S a) b (S c)

足し算(add), zero, oneについては型のみで表現し、two, threeについてもそれらの組み合わせでできています。

add :: Add a b c => a -> b -> c
add = undefined

zero = undefined :: Z
one = undefined :: S Z

two = add one one
three = add one two

ここまで書くと実際に型での計算が確認できるようになります。

ghci> :t one
one :: S Z

ghci> :t two
two :: S (S Z)

ghci> :t three
three :: S (S (S Z))

というわけで、型をうまく扱うことで型の上で数字の取り扱いができるようになりました。 今回の内容ではあまり高度な例とも実用的な例とも言えないかもしれませんが、型の表現力の一端は感じていただけたのでは無いでしょうか。

感想

業務では使用していないプログラミング言語なので難しかったという声はありましたが、内容を理解したうえで面白かったと言っていただけたり、Haskell関数型言語に興味を持ってくれた人がいたのでとても有意義で楽しい社内LT大会になりました。

最後に

Holmesはエンジニア・デザイナーを募集しています。 興味がある方はぜひこちらからご連絡ください!

lab.holmescloud.com

lab.holmescloud.com

Nuxt.jsのビルドを高速化してみる

こんにちは。Holmesでエンジニアをしている三澤です。

背景

弊社ではフロントエンドフレームワークとしてNuxt.jsを利用しています。プロジェクトが進みコードが増えてくるとビルドに時間がかかってくるのが悩みの種です。 ビルド時に最も時間がかかっているのは下記の画像の部分ですが、恐らくwebpackのビルドに最も時間がかかっているのではないかと仮定しました。

f:id:a-misawa:20201214150456p:plain

この仮定に基づいて何かいい方法はないかと探しているとNuxt.js本家のGithub上で興味深いissueを見つけました。

github.com

ここでNuxtの中の人がこのようなことを言っていました。

f:id:a-misawa:20201211223733p:plain

今回は上記のコメントで取り上げられている方法を試してNuxt.jsのビルド高速化(=webpackのビルド高速化)に取り組んでみたいと思います。

概要

今回行うビルド高速化は、nuxt.config.jsのbuildプロパティに設定を追加することによってwebpackのビルド設定を変更します。 nuxt.config.jsのbuildプロパティに追加する項目は下記の3つです。

名前 内容
parallel webpackプラグインのthread-loaderで複数スレッドでビルドすることで高速化する
cache webpackプラグインのterser-webpack-pluginでjsをminifyし、cache-loader を使ってwebpackビルド時のloaders情報をキャッシュ化して高速化する
hardSource webpackプラグインのhard-source-webpack-pluginでモジュールをキャッシュ管理することにより2回目以降のビルドを高速化する

実行結果

何もしていない場合

  • 平均ビルド時間:53秒

私の環境で何回か実行した場合の平均値ですが、この数値をどれだけ低くできるかになります。

parallelプロパティ

https://nuxtjs.org/api/configuration-build#parallel

nuxt.config.jsに下記1行を追加します。

export default {
  build: {
    parallel: true, //<-追加
  • ビルド時間(1回目):1分11秒

  • ビルド時間(2回目):1分08秒

却って遅くなるという結果になりました。この設定はファイル数が多い場合に有効なようですので今回は不要ということになります。

ファイルが多い場合どの程度短縮されるかについての参考情報:Webpackのビルド時間を1/3にした話 #gotandajs - Speaker Deck

cacheプロパティ

https://nuxtjs.org/api/configuration-build#cache

nuxt.config.jsに下記1行を追加します。

export default {
  build: {
   cache: true, //<-追加
  • ビルド時間(1回目):49秒

  • ビルド時間(2回目):42秒

こちらは1回目からビルド時間が少し短縮され(terserのおかげ?)、2回目以降もcache-loaderが効いているからか更に短縮されました。

hardSourceプロパティ

https://nuxtjs.org/api/configuration-build#hardsource

nuxt.config.jsに下記1行を追加します。

export default {
  build: {
   hardSource: true, //<-追加
  • ビルド時間(1回目):1分43秒

  • ビルド時間(2回目):21秒

こちらは1回目はモジュールのキャッシュ作成のため大幅に増えてしまいましたが、2回目以降は平均20秒前後でビルドできるようになりました。

上記3項目すべて

nuxt.config.jsに下記3行を追加します。

export default {
  build: {
   parallel: true, //<-追加
   cache: true, //<-追加
   hardSource: true, //<-追加
  • ビルド時間(1回目):49秒

  • ビルド時間(2回目):21秒

1回目からcacheプロパティが効いているためか短縮されました。2回目以降もhardSourceプロパティのおかげで大幅に短くなっています。

感想

体感的にはhardSourceプロパティが一番効果があり、次いでcacheプロパティが効くことが分かりました。parallelは今回効果がなかったようですが、ファイル数によってはビルド時間を大幅に削減できるようです。

デメリットとしてはhardSource、cacheプロパティ共に未だNuxt.jsとしては実験的機能の扱いとなっていることです。 調べてみますとhardSourceをONにしてビルドすると稀にビルドに失敗することがあるようです。解決方法としてはnode_modules/hard_source/*(hardSourceのキャッシュファイル群)を削除するとエラー解消されるようですので、キャッシュ管理に問題が潜んでいるのかもしれません。ですから未だ実験的機能であることから、チーム開発で活用するかは要相談だと思います。

また、今回はプロパティを設定して効果を測定したに過ぎません。今回ご紹介した3つのbuildプロパティはいずれもwebpackのプラグインを利用しているため、webpackの仕組みを理解することがNuxt.jsのビルド時間短縮の本質的な最適化につながりそうです。今後もwebpackのビルドの仕組みを更に調査してみたいと思った次第でした。

webpackのビルドパフォーマンスについての情報:Build Performance | webpack

最後に

Holmesではエンジニアを募集しております。ご興味がある方はこちらからご連絡ください。

lab.holmescloud.com

ArchUnitがDDDのモジュール実現にちょうど良かった話

この記事は Holmes Advent Calendar 2020 - Qiita 11 日目の記事です。


こんにちは。エンジニアの友野です。最近、Quartoにハマっており、チーム内普及に勤しんでいます。

先日、ドメイン駆動設計(以降、DDD)初学者にありがちな

  • 「これはどこに置くんだっけ?」
  • 「このクラスからドメイン層呼んでいいんだっけ?」

というような不安を払拭するために良い方法はないものかと悩んでいたところ、前回のJJUGでArchUnitを知りました。 早速プロダクト適用してみたら、結構良かったのでまとめておきます。

これから例示するコードは以下の動作環境*1で作り、動かしています。

JVM: OpenJDK Runtime Environment Corretto-8.252.09.1 (build 1.8.0_252-b09)
Gradle: 4.10.3
Kotlin: 1.3.41
Spock: spock-spring:1.3-groovy-2.4

ArchUnitとは

ArchUnitは、Java/Kotlinで書かれたアプリケーションのアーキテクチャを検証するためのライブラリです。パッケージやクラスなどの依存関係チェックができます。詳しくは公式サイトをご参照ください。

www.archunit.org

Holmesでは一部アプリケーションをKotlinで書いているので、JavaだけでなくKotlinもテストできるのは嬉しいですね。 詳細なセットアップ手順やAPIは読みやすいドキュメントが公式から提供されているので、割愛します。

www.archunit.org

Why ArchUnit

改めて整理するとやりたいことは、以下の2点です。

  • 参照関係を明確化して責務分離を進める
  • データモデルなどの既存資産とドメインモデルを分離する

パッケージ構造や参照関係のような決め事を守るために、最も簡単な始め方はレビュープロセスで担保することです。 しかし、ご存知の通り、この方法は強制力がなかったり、見逃しがあったり、適切に運用するのは難しいです。

仕組みで守る方法として、gradleでサブプロジェクト化して依存の方向をdependenciesで定義することも考えられますが、新規プロジェクトならいざ知らず、既存資産があるとこのアプローチに舵を切るのは若干尻込みしてしまいます。

そのちょうど中間として、現在の構造を大きく変えずに、かつテストコードによって比較的強い制約として表現できるArchUnitはまさに我々のような状況には最適と言えます。

セットアップ

今回対象としているアプリケーションはkotlinでプロダクションコードを書き、テストコードはgroovy(spock)で書いています。 それぞれのバージョンは冒頭で記載した通りです。 テストフレームワークにspockを採用しているので、build.gradleの依存には無印のものを追加します。

dependencies {
    // other dependencies...
    testImplementation 'com.tngtech.archunit:archunit:0.14.1'
}

spockテストクラスも書いておきます。

class ArchitectureSpec extends Specification {

    final def BASE_PACKAGE = "com.example"
    final String[] LEGACIES = [
        "..entity..",
        "..repository..",
        "..service.."]
    final def CONTROLLER = "..controller.."
    final def USE_CASE = "..usecase.."
    final def DOMAIN = "..domain.."
    final def INFRASTRUCTURE = "..infrastructure.."

    final JavaClasses importedClasses =
            new ClassFileImporter().importPackages(BASE_PACKAGE)

    // ここにテストケースを書く
}

これで準備が整いました。

守りたいアーキテクチャ

先日の記事で触れた三層+ドメインオブジェクトアーキテクチャから試行錯誤をして、今のところオニオンアーキテクチャに近い形に落ち着いています。

tech.holmescloud.com

f:id:a-tomono:20201210231738p:plain
簡略化したアーキテクチャ構成図

参照関係の明確化

ユースケース層はコントローラ層から参照され、ドメイン層はユースケース層およびインフラストラクチャ層から参照されます。

def "ユースケース層はコントローラ層からのみ呼び出される"() {
    given:
    ArchRule rule = classes()
        .that().resideInAPackage(USE_CASE)
        .should().onlyBeAccessed().byAnyPackage(CONTROLLER, USE_CASE)

    expect:
    rule.check(importedClasses)
}

def "ドメイン層はユースケース層、インフラストラクチャ層からのみ呼び出される"() {
    given:
    ArchRule rule = classes()
        .that().resideInAPackage(DOMAIN)
        .should().onlyBeAccessed().byAnyPackage(
            USE_CASE,
            DOMAIN,
            INFRASTRUCTURE,
        )

    expect:
    rule.check(importedClasses)
}

これを実行すると…、テストに失敗しました。

...
    at com.example.ArchitectureSpec.ドメイン層はユースケース層、インフラ層からのみ呼び出される(ArchitectureSpec.groovy:47)
Caused by: java.lang.AssertionError: Architecture Violation [Priority: MEDIUM] - Rule 'classes that reside in a package '..domain..' should only be accessed by any package ['..usecase..', '..domain..', '..infrastructure..']' was violated (9 times):

既存資産のモデル変換は、そのモデル自身にさせていたため、インフラストラクチャ層以外から参照していることを思い出しました。 これは既存資産を活かすことを優先した結果でもあるので、広義でのインフラストラクチャとして扱います。既存資産のモデルを参照元に追加して再実行、テスト成功しました。

final def LEGACY_MODELS = "..entity.."

def "ドメイン層はユースケース層、インフラストラクチャ層からのみ呼び出される"() {
    given:
    ArchRule rule = classes()
        .that().resideInAPackage(DOMAIN)
        .should().onlyBeAccessed().byAnyPackage(
            USE_CASE,
            DOMAIN,
            INFRASTRUCTURE,
            LEGACY_MODELS, // 追加
        )

    expect:
    rule.check(importedClasses)
}

既存資産とドメインモデルの分離

新しいドメインモデルを定義しているので、既存資産に依存はさせたくありません。つい、既存サービスクラスをDIすればもっと早く実装できるのに、という誘惑に駆られますが、これはファットなドメインサービスを生み出し、結果としてドメイン貧血症を引き起こします。なによりビジネスルールが散在したままです。 これを避けるためにテストケースを追加します。

def "ドメイン層は既存資産を利用しない"() {
    given:
    ArchRule rule = noClasses()
        .that().resideInAPackage(DOMAIN)
        .should().dependOnClassesThat().resideInAnyPackage(LEGACIES)

    expect:
    rule.check(importedClasses)
}

これで最低限の労力でやりたいことは満たせたと思います。

ふりかえり

今回のテストを書いていく中で、偶然にも、コントローラがドメインオブジェクトを参照している実装を発見できました。レビュー済みの箇所ではありましたが、やはり見落としはあるようです。 テストでアーキテクチャの制約を表現できるので、構造を頭に入れつつも、個々の機能実装に集中できる感覚がつかめました。

現在はコントローラからのドメインオブジェクト参照は禁止していますが、IDクラスなど、制約を部分的に緩くするパターンも今後考えられます。これは、例えば、特定のインタフェースを実装した値オブジェクトのみ許可する、というようなテストで簡単に実現できそうです。 ただし、なぜこの制約があるのかはしっかりと共有しないとルールを守ることがゴールになり、目的と手段が入れ替わってしまう懸念もあります。

まとめ

スタートしたばかりのDDDにArchUnitで適度な制約を設けて、開発者がモデリングとそのコード表現にフォーカスできている状態に一歩近付きました。ArchUnitはユーザーガイドがよくできているので、色々読みながらプロダクト適用していこうと思います。

Holmesでは、今後もDDDを活用してプロダクトを成長させ、契約に関する顧客課題解決を通じた価値提供をしていきます。 興味がある方はご連絡下さい。

lab.holmescloud.com


明日は、同じチームでスクラムマスターをしている吾郷さんによる「スプリントレビュー改善の記録」です 。

*1:2019年に開発したサービスの環境で試しているため、バージョンは少し古いものです

目標管理制度を一年間運用する中での取り組みと学び

この記事はHolmes Advent Calendar 2020 10日目の記事です。

こんにちは。HolmesでVP of Engineeringとして開発組織の組織づくりや採用を担当している守屋です。
最近はもっぱら子供のクリスマスプレゼントに頭を悩ませています。

この記事では約一年間運用してきた評価制度、特に目標管理の運用について、実践を通して学んだことを時系列に沿ってまとめてみたいと思います。大きく分けると制度の導入をした2020/1Q(1-3月)、定着と拡大を図った2020/2Q-3Q(4-9月)、暗黙知言語化を図った2020/3Q-4Q(9-12月)に区切って記述しています。
制度運用にフォーカスしていますので、制度策定のステップについては触れていません。
アーリーステージでの評価制度と給与決定ロジックについて書かれていた、All Star SaaS Blogの金田宏之さんのウェビナー記事にインスパイアされ、このテーマを選びました。

想定される読者の方

主に開発組織での目標管理・評価制度の運用に悩まれている方はもちろん、チームや組織の方向性が揃わず力が分散してしまっているな、と課題を感じている方のちからになれればと思って書きました。

せっかちな方へ

学んだことを先にざっと書きます。

プロセスをぶらさないこと

始めたことは最後までやる。
制度の運用は挫けそうになることばかりですが、プロセスを守っていなければ公平感を感じてもらうことは決してできません。
期間や対象業務など、意思決定したスコープに対してはぶらさずにやりきることが最初の一歩だと痛感しました。

主観を磨き続けること

評価を完全に定量化し、主観が一切入らない状態にすることは、現時点においては方法が十分には確立されていないと思います。
それゆえ、一人ひとりの評価に直接関わる評価者の主観を磨き続けることが大切だとわかりました。
例えば「Aさんの等級に対して、業務Xの取り組み姿勢、最終成果は期待値に達していると判断できるか?」といった基準は、一次評価者同士での主観の磨き合いを抜きにしては納得感のある評価となりえません。

HRM(Human Resource Management)の知見を最大限取り入れる

口当たりの良さを求め、フレームワークや仕組みを導入した当初からベストプラクティスを捻じ曲げてしまうことの危険性については、システム開発に通ずるところ*1があると思います。
迷ったときには先達の知恵を惜しみなく使い、まずは型を守ることを強く意識しました。
また個人的には数年前ワークショップで同席させていただいた人事コンサルタントの坪谷邦生さんとの出会いをきっかけに、HRMの知見に触れることができました。
結果的に坪谷邦生さんの著書『図解 人材マネジメント入門 人事の基礎をゼロからおさえておきたい人のための「理論と実践」100のツボ』は、この一年間で最も繰り返し開いた本になりました。

www.amazon.co.jp

導入(2020/1Q)

この目標管理・評価制度導入以前は、全社でOKRによる目標設定を行っていましたが、評価制度は存在しませんでした。
評価制度を導入するにあたって、OKRについては、Google re:workの簡潔な定義に明記されている通り、評価ツールではありません。
目標管理と評価制度で別のツールを運用することはこの時点ではまだ現実的でないと判断し、他社の制度などを参考にしつつ、MBOの思想をベースとして目標管理・評価制度を導入しました。

制度の理解醸成と導入の背景説明

最初に取り組んだのは、個々のメンバーへの制度そのものと導入背景に対して腹落ちするまで対話をするということでした。
それまで取り組んでいたOKRの運用については、フォーマットの自由度が非常に高く、成果やコンピテンシーのバランスについてもメンバーごとに大きなばらつきが許容されている状態でした。
しかし、評価制度と一体になった目標管理制度に移行するため、目標の中で成果と各コンピテンシーそれぞれに対する目標設定が必要となり、目標設定の難易度が上がったと感じるメンバーが多くいました。
当然業務時間を圧迫する要因となるため、何のためにこの制度を導入して運用するのか、一人ひとりに理解してもらう必要がありました。
このときは一人あたり約一時間時間を確保し、制度の背景についての説明や具体的な運用イメージを膨らませてもらい、そこから目標設定に入っていきました。

最初の個人目標の設定での悩みどころ

実際に運用する目標管理のシートは、多くの企業で採用されているものと近いものでしたが、初めて経験するメンバーも多く設定に苦戦しました。
特に下記のようなポイントで悩みが多く出ました。

  • 成果目標の定量
  • 個人のビジョンと組織のビジョンがアンバランスな目標
成果目標の定量

成果目標については基本的には定量的な目標値を設定することにしています。(例外もあります)
ありがちではありますが、KPIが自己目的化してしまわないように、定量目標を設定することの意義を伝えていきました。

KPIが自己目的化した例を挙げると、例えば組織目標として「ユニットテストカバレッジをXX%に上昇させる」という目標を設定します。
この組織目標からブレイクダウンして、「個人が該当期間にコミットしたコードにより、カバレッジをxポイント向上させる」といった目標をメンバーが立てたとします。
この目標を追いかけると、業務上の重要性に関係なくテストコードの記述量を増やす方向に行動を起こしやすくなります。
本来組織目標としてテストカバレッジを設定する背景としては、コードの変更容易性を高めることや、testabilityを意識することでコードをcleanにしていきたいというモチベーションが強いと思います。
しかし単純に既存のコードへのユニットテストを増やすことだけにフォーカスしてしまうと、変更容易性が逆に下がってしまうという結果にもなりかねません。
そこで、個人目標としては「チームの作業ブランチからmasterブランチへのマージタイミング」といった意味ある変更の単位で、「CIで計測されるテストカバレッジを最低でも下げない」といった形で定量目標を設定します。
これを実現するためにTDDのスキルを習得したり、チーム内のコードレビューを行うといった行動目標を合わせて設定します。

個人のビジョンと組織のビジョンがアンバランスな目標

前出の坪谷さんの著書では、下記の通りに表現されています。

人間性の尊重と業績向上を同時実現するのが本来のMBOです*2

特に中途採用で、前職においてノルマ管理的な使われ方で目標設定を行われていた場合に、「個人のビジョンについて考えたことがなかった」というケースも少なくありません。
その場合、過去のキャリアの棚卸しやそのときに感じたことの言語化に伴走し、個人としてのビジョンを描くことから始めました。
その上で、個人のビジョンといま時点で持っているスキル、組織が個人に期待する役割を加味して目標のバランスを調整していきました。
(たまたま私の前職の上司がリクルート出身だったこともあり、慣れ親しんでいたWill Can Mustのフレームに寄っています。)

定着〜拡大(2020/2Q-3Q)

Holmesが導入した目標管理制度は評価は半年、四半期で中間評価・再設定を行う制度です。
このため、この期間には中間の目標の立て直しと下半期の目標設定が行われました。
特にこの期間では組織の人数が1.5倍に増えたこともあり、全員分のフォローを一人で行うことが難しくなりました。
そこで一次評価を担うメンバーの拡充と業務の委譲を進めていきました。

コンピテンシーの解釈についての明文化

この評価制度で定義されているコンピテンシー項目の等級に対する定義は、全社で共通の記述になっているため、開発組織のメンバーからすると実際の業務シーンを想像しにくいという課題がありました。
そこで、等級に対する定義を開発組織の業務に近づけた解釈を明文化し、目標設定前に全メンバーに共有しました。
その結果下期の目標設定では、年初の目標設定と比較して格段にスムーズに目標設定ができるようになりました。
具体的には、目標を最終的に承認しているCTOが一人あたりのメンバーとの目標設定に費やした時間が、年初の半分に短縮されました。
全員の目標設定スキルの向上と一次評価者の尽力に感謝しかありません。
特に各人の中で、評価制度のコンピテンシーの各項目への理解が醸成されてきたことが大きく寄与しました。
しかし、この時点で一次評価者同士やメンバー間で、その醸成された理解をすり合わせたり明文化する取り組みはまだできていませんでした。

暗黙知言語化(2020/3Q-4Q)

3Qから4Qにかけての中間評価、四半期目標の設定に際して、一つのチャレンジを設定しました。
本人と一次評価者で練り上げる目標の精度向上を目的に、目標の承認を行うCTOを一人あたりが割り当てられる時間の上限を設定しました。
このチャレンジを成功させるために一次評価者の共通認識づくりに取り組みました。
結果的にこのチャレンジには成功し、その後もコンピテンシーに関わる様々な暗黙知言語化することに取り組みました。
下記はその一例です。

MBO本来の意味と目的

振り返ってみると制度運用開始時点ですり合わせすべきことでしたが、その時点では考え及ばず、遅ればせながらこの時点で言語化を行いました。
過去の私自身も含め、MBOというとExcelで作られた目標管理シートをイメージされる方は非常に多いと思います。
しかしMBOを提唱したドラッカーは、Management by Objectives and Self-controlと定義しており、MBOを「目標と自己管理によるマネジメント」というマネジメントの哲学として位置づけています。
そのため、マネジメント哲学としてのMBOの共通認識を作るため、下記のように明文化し、一次評価者と認識のすり合わせを行いました。

  • MBOは目標を手がかりに自らの仕事をマネジメントできる状態にすることが目的
    • 定められた目標に照らし合わせることで、自らの成果を評価できる状態を目指す
    • self-controlに依る、各人の目標への強い動機づけが引き出されることを目指す

また、self-controlを最大限発揮するために下記のようなパターンを洗い出しました。

  • 本人が目標の設定に深く関わる
    • 一方的に課されるノルマのようなものではない
    • 会社・組織の課題を本人が腹落ちしている
  • プロセスを守る
    • 目標を達成することで評価されることが保証されている
    • 画一的なプロセスで制度が運用される
  • 身近な目標
    • 本人が確信を持って設定した目標であること
    • 面談や1on1のときだけ思い出すような目標ではないこと

一次評価者の役割

一次評価者の役割としては、下記の点にしぼりました。

  • メンバーを正しく見る
    • 事実を正確に把握する
    • 信頼関係を築く
  • 組織の未来を本気で考える
    • 未来を自分の言葉で語る
    • メンバーの疑問を払拭する
  • 主観を磨き続ける
    • 公平感を担保するために、一次評価者同士の主観のすり合わせる

おわりに

長文にお付き合いいただきありがとうございました。
これを書いているまさに今、期末の評価と来季の目標設定に組織全体で取り組んでいます。
まだまだ試行錯誤の最中ですが、約一年間で人も組織も大きく成長できるということを体感できたことが個人的に最大の学びでした。
「それ違うっしょ」というツッコミや、「めちゃわかるわー」といった共感などコメントやメッセージなど、なんらかフィードバックいただけるととても嬉しいです。

開発組織は超絶積極採用中です

ピープルマネジメントに関心があるエンジニアやデザイナの方はもちろん、「マネジメントとかマジ興味が湧かない」という方も、Holmesの目標管理・評価制度では一人ひとりの個性やなりたい姿を全力で応援しています。
少しでも興味が湧いたらぜひ一度カジュアルにお話しさせてください。

lab.holmescloud.com

lab.holmescloud.com

第2回 場のデザイン

Holmesでスクラムマスターの役割を担っているid:tomoya_misudaです。

引き続きファシリテーション協会のセミナーで学んだことを紹介します。 今回は、場のデザインです。会議が終わらない、みんなに発言してほしい、和やかに進めたい、厳格に伝えたいなど、会議の準備に悩んでいる方に読んでもらいたいです。

f:id:tomoya_misuda:20201206113459j:plain
場のデザイン

www.faj.or.jp

場のデザインとは

参加者が主体性を持って会議に参加できるようにすることです。そのために、事前準備として5つの項目を決めます。また、机椅子の配置なども会議によって変更します。参加者が話しやすい場を設定することが重要です。

事前に決める5つの項目

  1. 目的:何のために実施するか。

  2. 目標:会議の終了時、どうなりたいか

  3. 進め方:時間配分やワークの方法

  4. メンバーと役割:参加者と参加者の役割

  5. ルール:会議の約束

上記の5つを事前に決めて、会議を実施できるとベストです。しかし、準備に時間が取れない場合は、目標まで決めておきたいです。 スクラムは、スクラムガイドに5つの項目を決めるために必要なことが記載されてます。参考になると思います。

例としてチームのレトロスペクティブ(振り返り)を紹介します。

※レトロスペクティブ(振り返り)
1.目的:品質と効果を高める方法を計画する。
2.目標:メンバーのチームのやりたいこと、やって欲しいことを把握する
3.進め方:ドラッカー風エクササイズ
4.メンバーと役割:開発者、プロダクトオーナー、スクラムマスター 、スクラムマスター は時間、ワークの進捗を管理する
5.ルール:他者が発表している時は傾聴する

ドラッカー風エクササイズは、弊社の吾郷さんが書いた記事を参考にしました。 tech.holmescloud.com

場の雰囲気をデザインする

机と椅子の配置を決めたり、参加メンバーの緊張をほぐすためにアイスブレイクも有効です。また、WEB会議でコミュニケーションのやり方を合わせることも重要です。

机と椅子の配置は、2つのパターンを使い分けてます。基本的は、下図のパターン1を利用してます。一緒に参加していることをイメージすることができます。パターン2は、司会や進行に徹する時に利用します。机と椅子の配置で場の雰囲気を作ることもできます。

f:id:tomoya_misuda:20201206115142j:plain

WEB会議の場合は、コミュニケーションのレベルを参加者で合わせることです。参加者が多く集まっている場があると、人数が多い箇所や司会役がいる箇所がメインとなり話し合いが行われます。また、カメラがONできない場合は、全員カメラをOFFにする工夫をしてもいいと思います。やはり、face to faceの方がコミュニケーションは円滑に進みます。

まとめ

参加者が主体性を持つには、目的や目標が必要です。今、議論していることに一貫性がないと他の業務や違う話題に変化します。また、タイムボックスがうまく行かないこともあります。しっかりとした目標と成果があれば、その時間を設定することに意味があります。会議毎に5つの要素を設定して改善していこうと思います。

最後に

ブログを読んで頂き、ありがとうございます。 Holmesはエンジニア・デザイナーを募集しています。
興味がある方はぜひこちらからご連絡ください!

lab.holmescloud.com

lab.holmescloud.com

顧客課題をプロダクトバックログに変換するプロセス-Alpha

株式会社Holmesで2020年10月よりプロダクトオーナーをしているid:w-miuchiです。

プロダクトオーナー(以下PO)としてプロダクトバックログをどういう観点、手順で作成すべきか考えました。この作成のプロセスを記載いたします。
まだまだ試行段階であることをご了承頂ければと思いますm( )m

About Product Backlog

弊社では現在、アジャイルスクラムを適用し開発を行っております。
スクラムガイドのPOの欄にはプロダクトバックログについて以下の記述があります。

プロダクトオーナーは、効果的なプロダクトバックログ管理にも責任を持つ。たとえば、
- プロダクトゴールを策定し、明示的に伝える。
- プロダクトバックログアイテムを作成し、明確に伝える。
- プロダクトバックログアイテムを並び替える。
- プロダクトバックログに透明性があり、見える化され、理解されるようにする。
https://scrumguides.org/docs/scrumguide/v2020/2020-Scrum-Guide-Japanese.pdf

ここにある「透明性」「見える化」「理解される」プロダクトバックログを作成するために、
プロセス化を行い、同じ観点で作られたプロダクトバックログとすることが目的です。

About Epic

弊社では顧客課題、解決すべき課題を記載したドキュメントをEpicと定義しています。
Epicに関しては以下も参考になるかと思います。

www.atlassian.com

Epicはプロダクトマネージャー(以下PM)が管理しておりPMからPOに伝達されています。

今回記載するのはこのEpicからプロダクトバックログに変換を行う際のプロセスになります。

Epic to Product Backlog

f:id:w-miuchi:20201207140259j:plain

User

登場人物の特定を行います。
弊社プロダクトの主な利用者は、法務部や事業部、営業部となります。どの部署のどのポジションの人が利用するか、ペルソナから抽出します。
ただし、機能に特化した改善の場合は必ずしも行う必要がない場合もあります。

f:id:w-miuchi:20201207140545j:plain

Flow

課題周辺に関して、業務や運用のフローを作成します。
アクション単位で作成したり機能単位で作成したり、Epic内容によって様々です。
全体の流れを理解するのを目的としています。
(ここでのフォーマットは決めていません) 詳細はプロダクトバックログアイテム(以下PBI)で記載します。

f:id:w-miuchi:20201207140852j:plain

Data

課題に対して関連するデータの抽出を行います。
利用者数や関連機能の利用回数などを調べ、機能に対するプライオリティ付けの参考とします。
実際には欲しいデータが必ずしも抽出できないこともあり、今後の課題になっています。

Use Case

ここまでのUser, Flow, DataからUse Caseを作成します。
Use Caseは機能ではなく、利用者の課題ベースで考えます。
この理由としては、実装に自由度を持たせることが目的です。あくまでも課題を解決することがゴールであることを意味します。

例) 「リマインド機能を付ける」ではなく「利用者の確認のために再度通知をする

実際にやってみるとUse Caseを作成する際はFlowUse Case毎に分割していくことになりました。

Image, Wireframe

また同時にImageWireframeを用意します。
例えば、以下のような粒度のWireframeになります。

f:id:w-miuchi:20201207170226j:plain

弊社のようなWebアプリケーションの場合、画面イメージが必要となります。ここではデザイナーに協力頂き作成を行います。
どこまで詳細に明示するかは都度判断していますが、あくまでも実装される画面ではなくイメージであることを重要としています。
ただし、明確にUIを改善するという顧客課題であれば詳細に作る必要もあるかと考えます。 このプロセスはFlowの作成と並行して行うこともありました。

Agreement

ここまでをMVP(Minimum Viable Product)としてPMと合意をします。
あとはMVPをPBIに分割し開発チームとリファインメントを行うという流れになります。

To close

以上が現在定義しているプロダクトバックログの作成プロセスとなります。
もちろん完成ではなく今後も迷いなくプロダクトバックログを作成できるようにプロセスを改善していきたいと考えています。
今後プロダクトオーナーを目指す方の参考になればと思います。