パルカワ2

最近はFlutterをやっています

仕事における責任とはなんなのか

課題感

「責任には権限が必要」みたいな話を時々聞くしそうだねと漠然と思っているのだけど、ふと責任って何?と思ったので、自分の考えをまとめておく。

前提として仕事をするときの責任である。

責任とは

昔、アカウンタビリティの講習に参加したときに責任を分類出来ることを知った。仕事における責任を分類すると以下のようなものが思いついた。他にもあったり、ちゃんとした名前があったり、定義が違ってたりするかもしれない。

成果責任

決められた成果を達成することに責任を持つこと

判断責任

成果を達成するために判断を行うことに責任を持つこと

説明責任

判断について周りに説明し巻き込むことに対して責任を持つこと

実行責任

判断の結果、決まったことを実行することに責任を持つということ

質問/フィードバック責任

わからないことに対して質問をすること・思ったことをフィードバックをすることに責任を持つこと

倫理責任

法令遵守はもちろん企業倫理、社会規範に従うことに責任を持つこと

責任はみんなが持っている

「責任を負う」というとなんだか非常に重たいもので、責任は特定の人間が持つべき!!!とか思いがちだけど、やることや立場(役割、等級など)によって比率が違うけど全員が各責任を大なり小なり持っている。なので、あまり重たいものと考えず、各責任をどう果たすか考えていくのがいいと思った。

責任を明確にするには

責任は自分含めみんなが持っているはずだが、なんの責任を持っているのか曖昧になりがちな気がしている。一人ひとりが自律的に動いて"いい感じにやる"ことも重要だとは思うけど、必要な役割は誰が責任を持つのか明確にしたほうが善意で成り立っている状態を減らす意味で健全だと思うし、お見合いがなくなったり自分のやるべきことが明確になって働きやすくなったり良いことが多いと思う。

責任を明確にするには、役割を与えられることが一般的な気がしている。役割には与えられていないものと与えられたものがある。

与えられていない役割は、例えばリリースフローの定期的な改善は継続的に必要だし自分が気になるから勝手にやってるみたいなもの。当然勝手にやってるだけなので、役割は与えられていないし、責任を明確にはなってない。

与えられた役割は、例えば「A事業部として、品質レポートをリードする」みたいな役割をチームから与えられている場合、レポートの実行責任や説明責任を持っているのがわかる。*1

一方で等級や役職なども与えられた役割である。例えば「EMの役割はチームの生産性をバク上げすることです!」みたいな役割が会社から与えられているとして、生産性をバク上げにすることが長期的な責任だとしたら、短期的には何に責任があるのか?というのは自分で言語化し表明しないと明確にはならない。*2

という感じで、責任を明確にするには以下のことが必要だと思った。

  • 継続して必要な役割を人に与えて、与えられていない役割を減らすこと
  • 与えられた役割はどのような責任があるのかという言語化と表明

まとめ

責任は分類出来るし、その分類は自分が思いつくだけでも結構ある。そして、責任はすでにみんなが持っていて、必ずしも重たいものではない。

また与えられていない役割を減らすこと、責任の言語化と表明が非常に大事だと考えた。

参考

*1:まあリードって曖昧な言葉なので、後述する言語化が必要な場合はある

*2:昔テクニカルリードになった時簡単に説明していたけど、今ならもうちょいいい感じに言える気がする

タスク・時間管理方法 2022

課題感

HourStackとGoogleカレンダーとZapierを連携して、10時から19時の間何をやっていて何に時間を使っているのかを管理(計画、計測、ふりかえり)をしていた。最初の1ヶ月ほどはあまり不満はなかったし、差し込みによって時間が奪われていることが可視化出来たので良かったのだけど、様々なものを頑張って連携して実現しているので変化に弱すぎてこうしたいな…と思うことはあれどめんどくさくて困っていた。

Sunsama

https://www.sunsama.com/

Sunsamaは昔使っていて、計画はしても計測もふりかえりとかしないし月20ドルは高いな!と思ってやめたのだけど、今は計画も計測もふりかえりもしているので、これでええやんとなった。

前までのやり方と少し違うのは、10時〜19時の間に何に時間を使ったのかを記録していたのだけど、Sunsamaはタスクに対してどのくらい時間を使ったのかを記録するので、この時間にこれをやる予定ですという計画は記録出来るけど、具体的に何時から何時に何をやったのかは記録出来ない。

前回Sunsamaを使うか考えたときにそれが理由でやめたんだけど、今となってはMTGがまとめて実施されるようになりコンテキストスイッチに伴う虚無時間は減ったので気にしないことにした。

オレオレルール

Contextの分類

  • 推奨されていたworkとpersonalだけ作った

Channelの分類

channelsのベストプラクティスには、「少ないチャンネルから始めてチャンネル内で何に時間を費やしているのか気になったら分割しましょう」と書かれていたので、自分がアサインされているチームとmtgと差し込みとした。

  • 第2事業部
  • アプリケーション開発部
  • エンジニアリング本部
  • mtg
  • 差し込み

Googleカレンダーの予定は全てMTGとする

繰り返しタスクはSunsamaで設定するようにした。もともとはGoogleカレンダーで繰り返しタスクを記録していたのだけど、タスクにするたび毎回channelなどを設定するのがめんどくさいので、Sunsamaで設定するようにした。

計画、Focusモード、ふりかえり

Sunsamaは計画とふりかえりが組み込まれているのでそれに沿ってやる。Focusモードもあり、タスクをやっているときはそのモードにしておくことでそれに集中しやすい+考えてることやメモが取れるのでなんだっけとなりにくい。

所感

  • Zapierとの連携がないので、PagerDutyのアラートが発火したらタスクを生成するみたいなのは出来ない。PDに呼び出されることが減ってきたので、まあいいかと思って諦めた
  • Focusモードが結構いい
  • Todayに絞ることができないと思っていたけど出来た
  • 前にはなかったAuto-scheduleが出来ていた 便利
  • Plan, Shutdownが最初からあり予定としてあるの便利

M1 MacのiOS SimulatorでFlutterアプリを動かすとスクロールの動作がおかしい

スクロールすると想像の数倍下にいったり上にいったりする。我慢してたけど、いい加減ムカついてきたので直し方を調べた。結論から言うと自分は直せていない。

Obsidianを使い始めた

課題感

ノートアプリは、Craftを使うようになっていたが、微妙に使いにくくて結局Notionで書いたりしていた。あまり自分の知見として貯まっている感じがせず、必要なときに必要な情報を取るみたいなのが出来ず、メモを書いたような気がするがどこへ………となったり、自分で記憶しておく必要があるということが時々あった。というか記憶していないものは大体なかったことになっている。

Obsidian

https://obsidian.md/

今年の10月に1.0.0がリリースされ「なんかよくなった」という雑な噂を聞いたので触ってみたところ、自分が触った時よりも自分が求めている動きをしていたのでいいじゃんと思って移行を検討し始めた。

Obsidianが僕の第二の脳になるらしい。脳は、情報の記録や取得はもちろん一つの情報から関連した情報を高速に取り出せるので、そういうことができるという話だろうと理解した。求めているものだ!

オレオレルール

Obsidianを第二の脳にするためには、関連のある情報同士が紐付いていないといけない。 またObsidianはコミュニティプラグインの開発が盛んでほしいと思ったものは大体ある。逆に言えばやろうと思えばなんでもやれてしまう気がするので、シンプルに使わないと途中で挫折すると思った。

それらを意識したオレオレルールを設ける必要がある。

とにかくリンクを貼る

関連のある情報同士を紐付けるために内部リンクを利用する。内部リンクを利用することで、情報同士が関連付けされ表示されるようになる。

また存在しているページだけではなく存在していないページにもどんどんリンクを貼る。

2ホップリンクを有効にする

2ホップリンクがあることで、より関連した情報を取得しやすくなる。

Obsidianでは、公式には対応していないがコミュニティプラグインがあるのでそれを利用する。リリースされているバージョンは表示バグがあるので、Githubにあるバージョンを使った。

具体的な物事のページ・抽象的な概念のページを作る

2ホップリンクを効果的に利用するために

タグは使わない

Obsidianには、タグがあるが使わない。内部リンクを利用する。理由は以下

  • 内部リンクならページなので物事に対する説明や考えてることが書けるし、エイリアスもつけれる
  • 使う概念を減らせて、ドキュメントを書く時にタグかページかで悩まなくてすむ
  • タグにはネスト出来たりタグペインなるものがあったりするが今のところ不要だと思う
  • タグと比べて入力文字数が多い、見た目は悪い、タイトル特有の禁止文字があるのが欠点

階層は基本使わない

Obsidianには、フォルダを分けることで階層を作れるが 画像を保存するassets, テンプレートを保存するtemplatesだけ用意する。理由は以下

  • 階層があることで、どこに保存するべきか悩む
  • 重要なのは情報を素早く取り出せることだが、階層があっても素早く取り出せないことがすでにわかっている
  • ドキュメントはすべて同じ階層に置くので、タイトルは被らせることは出来ないのが欠点

フロー情報かストック情報かを明確にする

Notionの検索で苦しむ理由の1つは、ストック情報がほしいのにフロー情報が出てくるからだと思っている。例えば「勤怠登録ってどうやるんだっけ〜」と勤怠登録の仕方(ストック情報)を探したいと思ったときに「勤怠登録」と検索すると同僚の勤怠登録タスクが出てきてやれやれだぜと思うみたいな。勤怠登録をタスクにしてる人はまあいないだろうけど、似たようなことが多々ある。

なので、ストック情報を探したい時は、明確にフロー情報を避けれるようにする。

ちなみにObisidianで扱うフロー情報とは、Daily noteだけだと思っている。会社のMTGの議事録などはみんなが見えるところで書きたいのでNotionで書く。

  • フロー情報の場合は、内部リンクで [[flow]]と記載する
  • ストック情報には何もつけない。両方に必ずつける運用はつけ忘れが発生するし、Daily noteはテンプレから自動生成が出来るので、自分でつける必要がない。なので、フロー情報にだけつけるのがよいと考えた
  • ストック情報を検索したい時は、-[[flow]] とすればいい

フロー情報とストック情報を1つのページに混ぜない

検索容易性をあげるために混ぜない。Daily-noteに書いても必要だと思ったらストック情報として切り出していく。

ページは細かく分ける

Notionの場合、ページ同士の関係を表示するのが苦手なので1ページにまとめた方がいいのではないかと思ってるけど、Obsidianの場合は細かく分けてリンクするのが関連した情報として出てきやすいので、いいのではないかと思った。

前のデータは引き継がない

邪魔になるだけだと思ったので引き継がないことにした。手元には置いといて必要になったら持ってくる形にする。

なんでもできるけど、なんでもやらない

Obsidianに限らずなんでもできると楽しくなってなんでもしたくなる。重要なのは必要な情報を得れることなので頑張りすぎない。

所感

  • 上記ルールに則って運用してみているが、結構いい感じな気がする。
  • Obsidian自体に最初から機能が揃っているという感じではなく、コミュニティプラグインを有効にしていくことでまともになっていくという印象だった。正直IDEなど最初から設定されているものに最近は慣れていたので設定がめんどくて投げ出しそうになった
  • 書きやすさに関してはNotionのほうが書きやすいと思っていて、Notionはリンクを貼る時とかそのあたりの気の利きようはすごいな〜と改めて思いました
  • 値段は、仕事に関することを書くと年50ドル払う必要があり、更にSyncを使うと年96ドルかかるので、合計146ドルかかり年2万円くらいかかるのでなかなか高い
    • Syncはコミュニティプラグインでどうにか出来る説はある
  • ちゃんと確認したわけではないけど、チームで使うのは書きやすさ・設定の大変さ・同時編集などがないあたりで厳しいのかなと思った
  • はてなブログに書く内容をどこで書くかは悩ましい。はてなブログに出すならはてなブログで書けば良い気がしてきた
  • Daily noteをどこで書くかは結構悩んでいて、Obsidianじゃなくてよくね?と思いつつ、振り返りやすいように設定してしまったのでまあいいかとなっている
  • いい感じに自動でリンクになってもいいのでは?と思ったけど、それってはてなキーワードじゃね?

まとめ

CraftからObisidianに移行した。とにかくリンクを貼るというのが大事な気がするので、無意識に出来るくらいになるとよさそう。そんなこと言って2ヶ月後には使ってない可能性もある。

話は変わるけど、仕様書同士や設計書同士の関係性をどう表すのか難しいと思っていたけど、バックリンクや2ホップリンクなど関係を一覧にするのはかなりいいなと思った。

Dartのextensionについてぼんやり思っていること

Dartには Extension methods | Dart というのがある。ぼんやり思っていることをメモしておく

前提

extensionは

  • クラスにメソッドを追加することができる
  • テストするためにクラスを作る必要がある
  • インスタンスフィールドは持てない
  • クラスの責務の大きさはextensionで切り出しても小さくならない

思っていること

変更できないクラスにどこでも使えるメソッドを生やすのはいいと思う

  • 変更できないクラスとは、StringやListなどDartが提供しているクラスやライブラリが提供しているクラス
  • どこでも使えるメソッドとは、Listをsliceするとか特定のドメインを扱う時のみ利用するメソッドではないもの

ほとんどがdartxdart:collectionにあると思われる。

逆に言えば、以下のようなパターンはextensionは使わずクラスを定義したほうがよいと思う

  • 自分が定義したクラス
  • 特定のドメインのみを扱う時に利用するメソッド

別クラスとして定義して、テストをする時に依存する情報を減らしたりクラス自体を小さくしたほうがいいと思う。

一応例外はあって、enumは自分が定義していて特定のドメインでのみ扱う場合でもextensionを使っている。そうしないとenumにメソッド生やせないので。

extensionを定義する場所をまとめる

様々な箇所でextensionを実装すると似たようなextensionが生えたり別でクラスを作ったりしてしまいそうなので、すべてまとめておいてまとめてexportする形にしておくのがよかったかもしれないと思っている。

変更できないクラスにどこでも使えるメソッドを生やすというルールだったらそれが出来る気がする。

リファクタリングをするために"一時的に"別ファイルに持って行くために利用する

リファクタリングを行う時に変更回数が多い+コードの行数が長いファイルをまず別ファイルに切り出してから少しずつリファクタリングすることがある。extensionを使えば簡単にクラスから別ファイルに切り出すことができる。ただ切り出し方にも工夫は必要で、例えばたくさんある切り出したいメソッドをまとめて別ファイルに切り出すというようなやり方をしてしまうと結局大きなファイルになってしまうのでクラスとして切り出すことを想定して切り出す必要はある。

また切り出して終わりにするとクラスは責務過多のままなので、ちゃんとリファクタリングしていく必要がある。

まとめ

僕はDartのextensionはあんま使う必要がないなと思っていますがみなさんはどうでしょうか

FlutterKaigi 2022で「Dartにおける静的解析」を話してきた

speakerdeck.com

初の動画撮影だったんですが、mmhmmで細切れで撮影したのでむしろ楽だったかも。最初は頑張って話そうとしてたんですが、録画していると思うと緊張して全くうまく話せなかったので、スクリプトを書いて読む形にしたりした。

内容的には、custom_lintcodemodを知らなかったとかコメントがあったりしたので話して良かった。

反省としては、時間的制約があって色々話せなかったこともありanalyzer pluginの説明をバッサリ端折ったので意味わかんない人は意味わかんなかったかも。端折るところ間違えたかもしれない。あとanalyzer pluginのメモリ消費多いよ問題の話も話してないので、興味ある人はイシューを読んでください。

運営のみなさん、ありがとうございました!

GoogleカレンダーからHourStackのEntryを作成した時にプロジェクトを自動で付ける

HourStackでタスクと時間の管理をしている。

HourStackは、Zapierと連携が出来て色々自動化出来るので、Googleカレンダーで作ったEntryはプロジェクトを自動で付けるようにした。

  • HourStackのEntry CreatedをTriggerに選ぶ
  • Source Prov が google-calendar のときのみ実行するようにフィルタ
  • Project が Does not exist のときのみ実行するようにフィルタ
  • GoogleカレンダーからFind Event
    • Search Termに作成したEntryの Name を指定
    • Start Time に Start Date と Start Timeをスペース区切りで指定
  • Run Python
    • Googleカレンダーの色分けからプロジェクトを決める
    • Inputには Color ID, Start Date, Start Timeを指定する
  • Update Entry in HourStack
    • 何も指定しないと指定していない状態で更新されるので、Entry Createdの情報を指定する
    • Start AtをRun PythonでOutputした start_at を指定する。Start Onを指定しない。
    • Project IDには、Run PythonでOutputした project を指定する

Run Pythonに書くコードは以下の通り。Project IDは自分で指定する。

from datetime import datetime
from dateutil import parser
import math

color_id = "0"
if "color_id" in input_data:
  color_id = input_data['color_id']

start_at = ''
if "start_time" in input_data:
  start_at = f"{input_data['start_date']} {input_data['start_time']}+00:00"
 
project = {
  "0": "<Project ID>",
  "1": "<Project ID>",
  "2": "<Project ID>",
  "3": "<Project ID>",
  "4": "<Project ID>",
  "5": "<Project ID>",
  "6": "<Project ID>",
  "7": "<Project ID>",
  "8": "<Project ID>",
  "9": "<Project ID>",
  "10": "<Project ID>",
  "11": "<Project ID>",
}[color_id]

output = {'project': project, 'start_at': start_at}

HourStackのProject IDは、Update EntryでProject IDを指定しようとすると出てくる。 GoogleカレンダーのColor IDは Google カレンダーの色 - SAKI Web Design を参考にした。

Googleカレンダーの色分けとHourStackのプロジェクトの色を同じにしている。こんな感じでカラフルになってかわいい