見出し画像

akippaが採用しているLaravelのデザインパターンの考え方を現実の出来事で例えてみる

akippaでバックエンドエンジニアをしている村上です。
前回前々回で、akippaで採用しているLaravelのデザインパターンのお話をさせて頂きました。

上記の2記事は、エンジニアの方に理解していただければよいと考えて書いた記事なのですが、今回は、エンジニアではない方にも、このデザインパターンの考え方が伝わるように、現実の出来事で例えてみたいと思います!
特に、akippaの方には是非読んで頂き、今の仕事上で他部署の方と取られているコミュニケーションのやり方に当てはめて考えてみていただくと嬉しいなと思います。

現実で起こっている問題の例

akippaの社内では、部署関わらず以下のようなやり取りをよく見かけます。
Xさん:hogeの件については、明日からXではなくYさんが担当になりますので、次回からYさんへ連絡してください!
後日…
Zさん:Xさん、hogeの件ですが、ご対応お願いします!
Xさん:それは先日アナウンスしたとおり、今Yさんが担当なので、Yさんへ連絡してください!
Zさん:アナウンスを見落としていてすみません…
Xさん:チッ…
Zさん:チッ…

最後の舌打ちは、僕の勝手な想像ですが笑
上記のやり取りを見て、一体どなたが悪いと思われるでしょうか。
少なくとも僕には、Zさんが悪いとは思えません。
自分の部署内の担当変更を、他部署に押し付けているXさんが強引にも見えますが、これは会社の文化に引きづられて…みたいなものもあるので、Xさんが悪いとも思いません。
どなたが悪いとかいう話ではなく、仕組みが整備されていないのが問題で、XさんもZさんも被害者だと僕は思います。
長年、社内からのプロダクトに関する問い合わせ対応は、私村上が行っておりまして、その後山下さんというエンジニアに引き継ぎ、さらに現在は谷口さんというプランナーの方に引き継がれております。
この引き継ぎの際、開発チームから全社に対して、先に挙げさせてもらったようなアナウンスをさせて頂きました。
このとき、僕は内心心苦しかったのを覚えております。他部署の方からしたら、知らんがな!のはずなのに、嫌な顔せずにご対応頂いている皆様には感謝しております。
この現実にあった上記の出来事を、この記事では「担当者変更問題」と呼ぶ事にします。
ではこの「担当者変更問題」をプログラムで表現してみましょう。
※ここから掲載するサンプルプログラムは、厳密に正しい言語ではなく、なんとなくPHPっぽい書き方で表現します。

担当者変更問題をプログラムで表現

まず、どんな便利な仕組みを利用するにしても、問い合わせ対応を行う担当者は、問い合された問題の解決を行うためのスキルや経験は絶対必要となります。上記で挙げたお名前でいうと、山下さん、谷口さん、村上が行う処理ですね。
以下のような処理が、担当者毎に必要となるイメージです。

class 村上
{
    public static function 問い合わせ受付()
    {
        // 問い合わせ内容に応じて色んな処理を行う
        if (プログラムの不具合だったら…) {
            プログラムを治す
            治したプログラムをリリースする
            依頼元へ問題が解決した事を連絡する
        }
    }
}

class 山下
{
    public static function 問い合わせ受付()
    {
        // 問い合わせ内容に応じて色んな処理を行う
        if (プログラムの不具合だったら…) {
            プログラムを治す
            村上に連絡する
            村上がリリースする
            依頼元へ問題が解決した事を連絡する
        }
    }
}

class 谷口
{
    public static function 問い合わせ受付()
    {
        // 問い合わせ内容に応じて色んな処理を行う
        if (プログラムの不具合だったら…) {
            エンジニアに連絡する
            担当エンジニアがプログラムを治す
            村上に連絡する
            村上がリリースする
            依頼元へ問題が解決した事を連絡する
        }
    }
}

担当者によって、担当領域や職種が異なるので、問題解決に至るための詳細な手順は異なってきますが、最終的に求められている事はすべて同じです。
上記でいうと「依頼元へ問題が解決した事を連絡する」がゴールですね。
では、他部署の業務の一部もプログラムで表現してみましょう。
ユーザー様から問い合わせを受けるCS部門の業務を例にして、開発部門の問い合わせ担当を村上とすると、プログラムは以下のイメージになります。

class CustomerSupport
{
    public function ユーザーから問い合わせ受付()
    {
        // 問い合わせ内容に応じて、様々な部署へ連携する
        if (問い合わせ先が開発部門なら) {
            村上::問い合わせ受付();
        } else if (問い合わせ部門がXX部門なら) {
            〜 省略 〜
        }
    }
}

で、ここで、担当が山下さんに変わりました!という事になると、以下のように、「村上」となっていた箇所を「山下」へ修正する作業が発生する事になります。

class CustomerSupport
{
    public function ユーザーから問い合わせ受付()
    {
        // 問い合わせ内容に応じて、様々な部署へ連携する
        if (問い合わせ先が開発部門なら) {
            山下::問い合わせ受付();
        } else if (問い合わせ部門がXX部門なら) {
            〜 省略 〜
        }
    }
}

この後また、担当が谷口さんに変わりました!となれば、また同じくプラグラムの修正が発生する事になってしまうという事がおわかりになるかと思いますが、これは現実で起こっている問題と全く同じです。
このCustomerSupportクラスに修正が入るという事は、現実世界でいうと、CS部門の仕事の手順に修正が入る事を意味します。
本来、開発部門の問い合わせ担当が誰に変わろうが、CS部門の仕事には一切の影響がない事が嬉しいはずです。

担当者変更問題のプログラムでの解決方法

プログラムの世界での解決方法の例を示します。
エンジニアではない方に説明するのが目的であるにも関わらず、ちょっと難しくなりますが、少し頑張って読んで頂きたいです!
まず、以下のような「インタフェース」というものを定義します。

interface 開発部門問い合わせ担当
{
    public function 問い合わせ受付()
}

「インタフェース」は、直訳すると「接点」です。
この「接点」を現実世界にあるもので例えるならば、akippaの方々がイメージしやすいものは、Redmineのようなツールです。
他部署と開発部門はRedmineという「接点」を通じてやり取りをする事がありますね。
うーん、ちょっと、わかりにくい気がするんで、最後に書きます…。
とりあえず、上の方で出てきた担当者毎の処理を、このインタフェースを通してみます。

class 村上 implements 開発部門問い合わせ担当
{
    public function 問い合わせ受付()
    {
        // 問い合わせ内容に応じて色んな処理を行う
        if (プログラムの不具合だったら…) {
            プログラムを治す
            治したプログラムをリリースする
            依頼元へ問題が解決した事を連絡する
        }
    }
}

class 山下 implements 開発部門問い合わせ担当
{
    public function 問い合わせ受付()
    {
        // 問い合わせ内容に応じて色んな処理を行う
        if (プログラムの不具合だったら…) {
            プログラムを治す
            村上に連絡する
            村上がリリースする
            依頼元へ問題が解決した事を連絡する
        }
    }
}

class 谷口 implements 開発部門問い合わせ担当
{
    public function 問い合わせ受付()
    {
        // 問い合わせ内容に応じて色んな処理を行う
        if (プログラムの不具合だったら…) {
            エンジニアに連絡する
            担当エンジニアがプログラムを治す
            村上に連絡する
            村上がリリースする
            依頼元へ問題が解決した事を連絡する
        }
    }
}

各担当者毎の問い合わせ受付の処理内容自体は、先程と全く同じです。
これは、現実世界と一緒で、どんな便利ツールを使ってやり取りを楽にしたとしても、各担当者は問い合わせ対応が行えるだけの必要なスキルや経験は変わらない!という事を意味しております。
ただ、それぞれのクラスが「開発部門問い合わせ担当」というインタフェースを実装(implements)するように変わっていますね。
これが、他部署の業務にとっては良い方に効いてきます。
では、CS部門の業務を表したプログラムも書き直してみます。

class CustomerSupport
{
    public function ユーザーから問い合わせ受付(開発部門問い合わせ担当 開発窓口)
    {
        // 問い合わせ内容に応じて、様々な部署へ連携する
        if (問い合わせ先が開発部門なら) {
            開発窓口::問い合わせ受付();
        } else if (問い合わせ部門がXX部門なら) {
            〜 省略 〜
        }
    }
}

このCS部門の業務を表現したプログラムを見ると、「開発部門問い合わせ担当」インタフェースを実装した誰かである「開発窓口」に投げるように変わりました。
「開発窓口」が具体的に誰なのか?はわからなくなりましたが、CS部門からはわからなくていいんです。
CS部門が期待している事は、問題の解決であって、具体的に誰がやるかは興味ありません。(現実世界では、興味持ってもらうと嬉しいかも笑)
じゃあ一体誰に紐付けるのかという定義は、プログラムの場合は、CS部門の業務が書かれた場所とは全然違うところで、以下のようなイメージで設定を行います。

bind(開発部門問い合わせ担当::class) {
    return 村上::class;
};

ここで「開発部門問い合わせ担当」は「村上」だとバインド(紐づけ)しています。
もし谷口さんに担当を引き継ぐ場合は、上記を以下のようにするだけです。

bind(開発部門問い合わせ担当::class) {
    return 谷口::class;
};

現実世界に例えると、担当者が変わった場合のこの設定の修正担当は、各部門が担います。これは開発部門なので開発部門が担当しますし、これが営業部門の担当者を設定するものであれば営業部門が修正を担当する事になります。
で、この設定が変わっても、上述したCS部門のプログラムは一切の変更せずに動作する事が保証されていて、修正が不要なんです。

現実世界にも当てはめてみよう

プログラムはそんな仕組みがあるんだーよくわからないけど便利そうだねーという声が聞こえてきそうな感じですが、現実世界こそ、この考え方が大事じゃないか!?と思うんです。
先程出た「開発部門問い合わせ担当」インタフェースの考え方を、現実世界に置き換える事ができれば、それが叶うと思いますが、その一つが、例えばRedmineのようなツールの活用かなと思います。
現在akippaでは、他部署からの依頼事項は、Redmineで管理しておりますが、他部署の方がRedmineで起票するに際して、特定の誰かに連絡をする事はしないはずです。(緊急時とかは置いといて)
毎朝、Redmineで起票された依頼事項を、チームメンバーで吟味しておりますが、このメンバーは、明日には変わるかもしれません。
ただメンバーが変わっても、他部署に影響は出ないようにしています。
上で記したプログラムを現実世界に例えるならば、このRedmineが、「開発部門問い合わせ担当」インタフェースであり、このインタフェースを実装しているのが、今の開発チームにいるメンバー達となるかと思います。

akippaでは、部署にまたがるコミュニケーションをChatworkで行ってしまっているので、現状のままだと、この担当者変更問題を解決する事はすぐには出来ないかもしれません。(Slackとかだったら、特定のメンバーだけをまとめたグループみたいなものを簡単に作れて、担当者が変わればそのメンバーを入れ替えれば済むんですけど)
今すぐできる事は少ないかもしれませんが、少なくとも、担当者が変わったって言ってるのに伝わらない!とか、担当者が変わったなんて知らんがな!とかでは怒らず、何か良い手はないだろうか?と建設的に考えながら、お互い温かい心で接していけたらなーと思います。
僕なんかが言うまでもなく、akippaでは、温かい心で接して頂いている方々ばかりですが、プログラムで例える事で、さらに皆様のストレスを緩和できれば…と思い、今回の記事を書きました!
最後まで読んでいただき、ありがとうございました!

この記事が気に入ったらサポートをしてみませんか?