matobaの備忘録

育児しながら働くあるエンジニアの記録

機能という言葉のもやもや

システム開発・ソフトウェア開発の設計に関する書籍をいくつか読んだりします。

いろんな書籍を読んでいるなかで、よくわかんないなあと思うことがあります。

わかんないこと

それは、「機能」という言葉の意味です。

「機能」という言葉が出て来た時に、「この本は、今、どういう意味というかどういう粒度で話をしているんだろう」という疑問が出てきます。

そして、なんの話をしているかを間違えると、全然理解が進まないです。

で、それを解消するために、機能って言葉について、もう少し詳しく考えてみたいと思ってます。なんか近い話がどこかに書いてないのかなあ。と思ってインターネットを検索しました。

インターネットで検索しながら、自分が学んだことを書きます。

機能という言葉の定義

機能という言葉について調べていると、以下のことが個人的に重要でした。

  • 機能は、ある物が本来備えている働きのこと
  • 機能は、全体を構成する個々の部分が果たしている固有の役割のこと

このあたりに書いています。

kotobank.jp

とりあえず、以下の理解が進みました。

  • 単体では機能と言わない。
  • 複数で全体を構成するから、機能という。
  • 誰かがどう動くかを期待している働きを機能と言っている。

機能の単位

機能という言葉で検索していると、いろんな機能が出て来ました。 その機能をどんな単位で決めるかを考えてまとめてみました。

  1. 国単位で考える機能(お金の機能、法律の機能、とか。)
  2. 組織単位で考える機能(人事の機能、営業の機能、研究の機能とか。)
  3. チーム単位で考える機能(予算管理の機能、時間管理の機能とか。)
  4. 仕事単位で考える機能(在庫引当機能、レビュー機能、とか。)
  5. 行動単位で考える機能(受注を確認する機能、在庫を確認する機能、受注に対して、在庫を引き当てる機能、とか。)

機能にはいろんな単位があるんだなあと思いました。

個人的には、「これ、どういう意味があるんだろう?なんのためにあるんだろう?」とかを考えたり、それを知ったりするのが好きです。

だから、色々考えたりします。それって、機能を自分なりに考えてたんだなあ、と思いました。

機能の階層

システムの機能の粒度の話を検索してたら、機能の階層という話が出て来た。

階層があるのかあ、なるほど。と思いながら、ぼんやり考えていました。

すると、ここに書いてあるシステム開発って、仕事の単位でシステムを開発しようとしているケースが多いなあ。と思いました。

そして、仕事の単位を一つのプロジェクトにして、システムを開発していくことが多いのかもなあ。そして、その一つ一つを実現する小さい何かを、ソフトウェアで実装していくのかなあ、とか思ったりしました。

参考:見てたページ

で?

ちょっと脱線しました。

結局のところ、機能という言葉の意味は、定義のところに書いたとおりです。

そして、モヤモヤ色々考えた結果、話をしている目的によって、機能という言葉の意味は変わるのかな、というのが今の僕の理解です。

例えば、「ソフトウェアをどう作るか?」を考えていて、機能の話が出て来たら、それは、ソフトウェアで作るものに何が必要かの話だと思います。

「ソフトウェアをどう使うか?」の話をしていたら、「ソフトウェアでどんな仕事をしようとしているか」が機能なのかなあ、とも思いました。

あと、「ソフトウェアで何がしたいのか?」の話をしていたら、「ソフトウェアで解決したい問題」が機能なのかなあ、とも思いました。

二つ目は、シナリオ。 三つ目は、ストーリー。とか書いた方がわかりやすいんじゃないかな、とか思いました。 一つ目は、、、、なんだろう。モジュール?なんか違うような。 機能かなー、うーん。って思ったのが僕の今のところの話です。

Gitが大切にしていること、成り立ち、他との違い

僕は、やっぱりツールを使っていて、「中身がブラックボックスなのは、気持ちが悪いなあ。」と思ってしまうたちのようです。

だって、よくわかんないんだもの。気持ち悪い。

という訳で、Gitについて、もっと詳しくなりたいと思いました。

ProGitを読んでいます。ここでは、個人的な発見を記します。

Pro Git 日本語版電子書籍公開サイト

CVCSの問題とDVCSの成り立ち

個人的には、以下の3点が重要でした。

  • CVCS(集中バージョン管理システム)は、中央サーバーが単一障害点になるのがよくなかった
  • 中央サーバーを作らなきゃいんだ。ということでDVCS (分散バージョン管理システム)が誕生した。
  • CVCSで出来なくて、DVCSで出来るワークフローがあるが、それらは、各DVCSの階層モデルによる副次的な産物だった。

この辺りに書いてます。

Git - バージョン管理に関して

Gitで大切にされていること

個人的には、以下の5点を目標に開発されているとの話が、重要だと思いました。

  • スピード
  • シンプルな設計
  • ノンリニア開発(数千の並列ブランチ)への強力なサポート
  • 完全な分散
  • Linux カーネルのような大規模プロジェクトを(スピードとデータサイズで)効率的に取り扱い可能

以下に書いてます。

Git - Git略史

これを見て、他のDVCSやCVCSは、以下のような特徴を持っていたことがわかります。

  • Gitに比べて、スピードが遅かった
  • Gitに比べて、設計がシンプルではなかった
  • Gitに比べて、ノンリニア開発へのサポートが貧弱
  • Gitに比べて、完全に分散しているといえなかった
  • Gitに比べて、プロジェクトが大規模になると効率的に取り扱えなかった

そして、Gitの5つの目標を達成するために、Gitの各コマンドが作られていると思うので、その気持ちで読み進めていきます。(僕はプロダクトのコンセプトを知ることが、プロダクトの一つ一つの機能を理解するためのいちばんの近道だと思ってます。)

他のCVCSとGit

以下のページにある「GitはSubversionと情報の格納の仕方が違う」という情報は、僕にとって、すごく重要でした。

Git - Gitの基本

なぜなら、僕は、Subversionを利用していましたし、Subversionの情報の持ち方を理解していたので、「Gitもきっと同じだろう」と思っていました。それが混乱を加速させていました。

僕にとって、衝撃だったのは、Gitはスナップショットを保持していて、差分を保持していない。ということでした。

それによって僕が、Gitを利用していて違和感を感じていた以下のような疑問が解消されました。

git cloneが遅い?

疑問その1:なぜ、これくらいのテキストファイルしか入っていないGitリポジトリをローカルにコピーしてくるだけなのに、こんなに時間がかかるのか?裏で何が動いているのか?SVNのリポジトリで、もっと大容量のファイルを管理していたことはあったが、チェックアウトはもっと高速だった。当時の環境と比較して現在の環境のネットワークが低速だとは思えない。Mercurialをcloneした時ももっと速いような気がしてる。git cloneでは何が起きているんだろう?

答え1:Gitリポジトリをcloneするということは、これまでの履歴も含めて全ての情報をコピーするということ。しかもGitリポジトリには、履歴がスナップショットで格納されているので、変更回数の増加とリポジトリの肥大化のスピードは、SVNやMercurialの比ではない。ただし、それは、開発中のスピードダウンではなく、開発を開始する前に時間がかかるだけである。Gitは開発者がストレスフリーに開発が行えるために作られたバージョン管理システムであって、管理者がリソースを効率的に利用して、新しい環境を作るコストを抑えるために作られたバージョン管理システムではない。ということ。

gitのbranch切り替えが高速すぎる?

疑問その2:Gitでbranchを変更した際に、切り替えが高速すぎて、本当に切り替わっているのか不安になる。例えば、ブランチの切り替えでは、ファイルが切り替わるが、切り替えが実施されているのかどうかもわからないほど高速で切り替わっている。何が起きているのかわからないような感覚になる。これは何が動いているのか?僕が思っているbranch切り替えとgitのbranch切り替えは違うように思えるが、これまでの経験は、全て使えないのか、一部使えないのかどちらだろうか。

答え2:Gitは差分を管理しているわけではなく、スナップショットを管理している。言い換えるなら、「このコミットが行われた時に配置されていたファイルは何か」という情報を管理している。branchが切り替わっても、ただ単にその時に配置されていたファイルの情報と現在配置されているファイルの情報の差分を見て、違うファイルを差し替えるだけである。だから、その間にたくさんのコミットがあったとしても、関係がないし、切り替えが高速になる。これまでの経験が、全て使えないとは言えないが、仕組みが違うということは頭に入れておいた方が良さそう。

gitのrebaseでなぜマージ処理が走る?

疑問3:gitでは、rebaseした際にコミットが実行されているように見える。rebaseの際は、マージもされているように見えるが、何か違和感がある。rebaseが自分のイメージしている動きと何か違う気がする。処理速度が、自分の思っているスピードと違う。これまでに使っていたSVNと同じように使っていると何か地雷を踏みそうな予感がする。マージしているつもりが、マージされていない。などの問題がどこかで起きていないのか不安だ。後ろで何が行われているんだろう?自分が何を勘違いしているのだろうか。

答え3:gitは、rebaseが行われた際、指定されたポイントから、現在のブランチに行われたコミットを一つ一つ確認しながら、ファイル状態をマージしていく。gitは、差分を持っているわけではなく、スナップショットで管理しているので、rebaseが実施されたタイミングで、同じファイルが更新されれば、それらのスナップショットを元に、一つ一つのファイルと差分を取り、マージ作業を行なっていく。rebaseのタイミングでファイルがマージが行われるということは注意した方が良い。

Gitのコミットの完全性

僕にとって、こある意味で衝撃的だった話は以下です。

  • Gitのほとんどすべてのコマンドが、データを追加するだけ。
  • Gitでは、UNDOを実行したり、データを消去することは困難である。

ただ、これは次のように紹介されていたのも印象的です。

激しく物事をもみくちゃにする危険なしに試行錯誤を行なえるため、これはGitの利用を喜びに変えます。

引用元: Git - Gitの基本

どのあたりが、危険なしに試行錯誤を行えるんだろう・・・というのはよくわかっていない。今のところ、gitはすぐにぐちゃぐちゃになるなあ。と思っている。

時間が来たので、一旦ここで。続きは、そのうち読む。

DjangoのViewってなんなんですか?

タイトルのような質問をされたらどうしますか?

僕は、なんて答えたら良いんだろう、と思いました。

そもそもの話をすると、DjangoのViewのテストについて考えていた時、『これはViewでやることか、Modelでやることがどっちだろう?』とか『apiとして外だしするのが良いのだろうか?』とか『formとの関係性は、、、?』とか、もやもやが出てきて、「あー自分の中で、DjangoのViewが何かわかってないんだなー」と思いました。

で思った質問が『結局、DjangoのViewってなんなんですか?』ってこと。

もやってても、解決しないので、調べてみよう。

DjangoのView

DjangoのViewについて調べてみると次のことがわかりました。

ビュー関数、つまり view は、単にWeb リクエストを受け取って Web レスポンスを返すPython 関数です。

参考:ビューを記述する | Django documentation | Django

なるほど。

ここでいう、Webリクエスト、Webレスポンスって何だろう。

Webリクエスト、Webレスポンス

DjangoのViewを詳しく見てみると、Webリクエスト、というのは、django.http.HttpRequestインスタンス。Webレスポンスというのは、django.http.HttpRequestインスタンスだとわかりました。

そりゃそうだ。

じゃあ、django.http.HttpRequestdjango.http.HttpRequest ってなんだっけ。。

django.http.HttpRequest,HttpRequest

改めて調べてみると、ここをみると書いてます。

リクエストとレスポンスのオブジェクト | Django documentation | Django

当たり前ですが、django.http.HttpRequestはHTTPリクエストをPythonのオブジェクトにマッピングした何か、django.http.HttpRequestHTTPレスポンスをPythonのオブジェクトにマッピングした何か。でした。

はい。まあ名前見たらわかるよね。と言う話です。当たり前でした。はい。

追加の疑問

Viewは、HTTPリクエストオブジェクトを受け取って、HTTPレスポンスオブジェクトを返すことがわかりました。

追加で以下のような疑問が出てきました。

よくわかってないのでそのうち調べます。

僕のブログのモチベーションあれこれ

ブログを書くモチベーションが変化したなあ、とふと思った。

気が向いたので、誰が興味あんねん、と思いつつ、振り返りながら書こうと思います。

なお、この記事を通して言いたいこと特にないです。(とりあえず書きたいだけ)

高校生くらい(2005年とか)

自分のバンドのホームページのコンテンツとして書いていた。

毎日書くことが目標だったので、トータル500本くらい書いた気がする。

最初は、とりあえずなんか書くことが目的で、三行のブログとかも多かった。

書いてたことは、普通に音楽をやってる日常のことだった。

次第に、バンド友達で見てくれる人が増えていったのを覚えてる。

個人的にムカついたこととかも書いてたので喧嘩とかした(若い)

知らない人との交流会もあったし、ブログからはじまる人の繋がりもあった。

この時のモチベーションは、コンテンツを作る仕事と人との交流かなあ。

そうこうしてたらmixiとか出てきた。

大学生のとき(2008年とか)

最初のころは、高校のときのブログをバンド友達が見てくれていた。

会う頻度も少なくなっていったので、最近、僕は何をしているかを共有するために書いていた。

あった時に『ブログを読んでるよ。』って言われると嬉しかったし、空気感を共有できている気がした。

話のネタになったから書いてた。と言うのが大きい。

この頃にはmixiが流行ってたので、友人とのコミュニケーションのための記事はmixiに移行された。

ただ、mixiになると、どうでもいい記事が目に入るようになってめんどくさくなっていった。

あと、あんまりステークホルダーが多いと書くことに気を使うので、mixiは嫌だなあという気持ちになっていった。

大学生のとき(2010年とか)

またバンドをはじめて、そのWebサイトのコンテンツとして、mixiとは別でブログを書きはじめた。

当時は、引きこもりでギターを弾く、スタジオに行く、ライブする、たまに学校に行く、みたいなダメ学生だったから、音楽ネタで書くことに困らなかった。

この頃、大学でコンピュータについて学びつつ、家でPC使いながら、音楽作ったりしてた。

当時のDAWについて悩み事も多かったし、情報が少なかったので、自分で試してたり、2chを見たりしながら、それの解決法とかもブログに書いたり。

あとは、作ってる音楽の機材の話もけっこうしてた。

パラメータチューニングもけっこうあったし、時間の限り試行錯誤してたから、その話とか。

その話があったから、機材の使い方を聞かれたり、音楽制作のエンジニアで依頼が来たりした。

バンドをやめたら自分の日記みたいになっていった。

大学院のとき(2012年とか)

この頃は、音楽の信号を分析する研究をしていた。ブログは、WordPressに移行した。

次第に音楽の記事より、IT系の記事が増えていった。というか、9割くらいそういう記事だった。

今だとQiitaに書いてるような記事を書いてた。(ポエマー)

当時、Pythonを使っていた。その前はCとかJavaとか書いてた。

JavaとかCは、やりたいことに対して、書かないといけないことが多いし、よくわからない魔法が多くて、好きじゃなかった。

Pythonは、書いてて気持ちが良いから好きだった。あと、JavaとかCは、既存のコードが動かない時にどうするかで、すごく悩むけど、Pythonはソースがあるから、辿って解決できるのが嬉しかった。

ブログでは、当時は少なかったnumpy、scipy、matplotlibの記事を日本語で書いてた。

virtualboxでけっこう悩んだこともあったのでその記事も多かった。

あと、Webサーバーのレンタル屋で働いてたのもあって、Webサーバーネタとかも多かった気がする。

あ、音声の信号処理を勉強してたのもあって、自作で音声を加工してプログラムを解説したりしてた。

当時、Googleアナリティクスを貼ってたけど、だいたい月間アクセスが1.5万くらいになってた。

そのあたりで、『あー、Pythonとかデータ分析ってすごい検索されるんだなあ』とか思い始めた。

就職したあと(2014年とか)

就職したら、ブログの更新は止まった。会社にいる時間が長くなりすぎて、そもそもブログを書く時間が減った。

さらに会社で、手を動かすことがなかったから、技術的なことでかけることが全然増えなかった。

あと、マネジメントに近い業務をしてると、仕事で悩んだことや解決したことは、だいたい人間関係の話になる。人間関係の悩みや解決をブログに書くのは、あんまり気が進まない部分がある。

ついでに、会社で関わる技術が、特許とかNDAに囲まれてて身動き取れなかった。

たまに、本読んで試してみたこと書いてたかもしれない。

そうこうしていると、ブログを読んだと感想もらうこともなくなったし、サーバーの更新料ももったいなくなってきたので、2015年の半ばに、一旦ブログは閉じた。

最近のこと(2017年)

転職を機にブログを再開した。

もともと、何の役にもたたない文章書くのも好きだし、自分の考えてることをとりあえず記録に残すのは好きだったし、ブログという形がけっこう好きなので。

あと、手を動かす機会が増えたし、技術的なことに触れる機会も増えたのもある。手を動かす機会が増えると、自分なりに試行錯誤したい気持ちになるから勉強することも増える。

今は主体的に動くことを応援してくれる体制なので、動きたい気持ちにもなった。*1

なんで書いてるかと言うと、情報をアウトプットしたいから、かなあと思った。

別に、ブログを書く時にまとめてないけど、一度ブログに書いたことを別で人に説明すると、多少はまとまっているはず。

あとは、自分で『前も同じことやったような』とか思った時に、ブログを検索すると出てきたりするのも良いなと思ってる。

それは、自分のEvernoteでも良いけど、インターネット上に登録しておくと、もしかしたら他の人も検索できるかもなーというくらいの気持ちでwebに書いてる。

また、そんなこんなで、最近はブログを書いている。

最近は移動中にブログを書いてるから、読んだ本の話が多くなってる。

もうちょっと技術的なことを書きたいなと思ってる。

*1:主体的に動くのが望ましいと言われながらも、主体的に動くと上下左右からたくさんのマサカリが投げ込まれる環境があるのです

ソフトウェアをリファクタリングするということ

リファクタリングについて調べてます。

この記事の続き。

リファクタリングについて調べはじめた - blog.mtb-production.info

キチンとしたリファクタリングのやり方を知りたいと思ってます。*1

というわけで、この本を読んでます。

新装版 リファクタリング―既存のコードを安全に改善する― (OBJECT TECHNOLOGY SERIES)

新装版 リファクタリング―既存のコードを安全に改善する― (OBJECT TECHNOLOGY SERIES)

本を読んでいて、自分なりにポイントだと思ったことを書いています。最後に所感も書いてます。

リファクタリングの頻度

リファクタリングは定期的にやることではなく、何かをやる時に一緒にやること。

  • Bad:定期的(例えば、二週間に一回)やる。
  • Good:リファクタリングするべきタイミングでやる。

リファクタリングをやること

リファクタリングは目的ではなく、手段である。

リファクタリングのタイミング

次のようなタイミングでやる。

リファクタリングしないとき

次のタイミングでは、リファクタリングを避けます。

  • コードが汚すぎて書き直す方が早いとき
  • 既存コードが動かないとき
  • 締め切りが迫っているとき

なにをリファクタリングするか

  • じゃあ、なにをリファクタリングしたらいいの?ってと言うと、不吉な臭いのするコードリファクタリングする。
  • 不吉なコードを嗅ぎ分けるスキルは経験によって養われる。

所感

この話の中だと、一番良かったのが、何かを対応する中で理解のためにリファクタリングするということ。

ちょうど、開発してるコードでも、新しい機能を作ったら、元のコードで気になる部分が出てきていた。

新しく作っている機能がなかったら気にならなかったけど、新しい機能を追加したら気になることがある。

たとえば、新しい機能があることで既存機能の変数名が誤解を招くとか、無駄な処理があるとか、そもそも、設計が微妙になるとか、そういうやつ。

そういう微妙ななにかは、新しい機能を追加するときにわかるし、それはリファクタリングすべきコードだということがわかった。

そして、リファクタリングした際に、デグレートしてないかを確かめるためにユニットテストが有効に作用する。

ユニットテストがしっかりしていれば、リファクタリングがスムーズにできることがわかってきた。

あと、これまではユニットテストを書くのが遅かったけど、ユニットテストを書くスピードが上がれば、ソフトウェア品質と開発スピードを保ったまま、ソフトウェアを拡張していけることがわかってきた。

これまで、設計した後にコーディングをする。そして、コーディングの段階で、設計を修正しないといけないのがわかったら負け。みたいなマインドがあった。

コーディングする前に、設計が全部わかるわけないでしょ。と思っていたけど、『僕が実力不足なだけで、できる人ならコーディングする前に設計が終わるのかもしれない。』とも思ってた。

ただ、この本を読みつつ仕事をしてる中で真実はこうでは?と思ってることがある。

  • 設計してからコーディングした方が良い。(必須ではない。規模、複雑さ、何回使いまわすか、による。)
  • コーディングする前に設計が完了するときもある(だいたい作ったことがあるシステムと、全く同じものを作る場合は近いかもしれない。ただ、ホントにそんなことある?チュートリアルか?)
  • 設計してからコーディングして、その後に設計を修正することはある。(必ずではない。コードの目的が何なのかによる。)
  • 前は良かった設計が、新しい機能追加によって悪い設計になるときがある(拡張性が高ければ良い設計ではない。拡張されないのに、拡張ポイントを作ると、逆に読みにくいコードになる。コードが読みにくいければ良い設計とは言えない。)
  • 時間と共に設計は、腐っていくので改善しないといけない。(周辺環境によって、設計が良いか悪いかは変化するし、周辺環境は時間と共に変化していくので、それに合わせたリファクタリングが必須。)

とりあえずおわり。

*1:キチンとした、ってなんか型にハマってて、書いてあることしかやらなさそうな響きが個人的には好きじゃないんだけど、そういうのはとりあえず基本をしっかりしてから言う事な気がしてるのでとりあえず基本的なことをやりたい気持ち。

プロジェクトと停滞と復活

僕が前に書いてたメモを見つけた。こんなこと書いてた。

プロジェクトが詰まった時にどうすれば復活できるか?

まあ気が向いたので、ちょっと調べてみた。*1

調べてみたら色々出てくるもんなんだなあ。と思った。*2

PMOの視点

こんな記事が出てきた。

www.pm-portal.jp

書いてあったこと。

  • 体制、役割、期待値の明確化
  • プロジェクト全体スケジュール策定
  • チームWBS策定
  • 会議体整理

PMOっぽいと思った。PMOと言うのは、Project Management Officeと言うやつで、その組織の中でいくつも走っているプロジェクトがいい感じになるように色々やる人。プロジェクトが炎上してないかをチェックしてたり、炎上してるプロジェクトの火消ししたり、プロジェクトがうまく回りそうに後ろで色々動く人たち。いわゆるプロジェクトリーダーの相談役みたいポジション。

個人レベルの視点

関連キーワードで検索してたら、こんな記事が出てきた。

orangewind.hatenadiary.jp

GTDの話。GTDについては、原著読むほうがいいと思うので、書かない。

全面改訂版 はじめてのGTD ストレスフリーの整理術

全面改訂版 はじめてのGTD ストレスフリーの整理術

僕もGTDやってるけど、GTDに定期点検は必須だと思う。*3

とは言え、止まってるプロジェクトとかあるよなあ。止まったら嫌なプロジェクトは、定期的に「見直し」みたいなタスクがあがるようにして、少しずつ前に進むように工夫してるなあ。とか思い出した。

プロジェクトリーダーの視点

別のキーワードで検索してたら、出てきた。

xlinkpat.jp

書いてあったこと。

  • プロジェクト全体を俯瞰する
  • 頭より手を動かす
  • 新メンバーを入れる
  • 専門家の手を借りる
  • 三人寄れば文殊の知恵

終わり

調べてる途中で思ったけど、こう言うのって、当事者にならないとイマイチわからないなあ。*4

後、個人的には、自分がどう言う役割なのか、を考えて頑張るんじゃなくて、誰でもいいから前に進めよう、と言う感じの混沌としたスタイルの方が好きだと思った。*5

それから、プロジェクトによって状況は変わるから、なんとも言えないよなあ。とかぼんやり考えていた。

*1:ただ単に、メモから削除したい気持ちがあったけど、せっかくメモしてたから多少調べてみようと思った。

*2:僕が関わっていたプロジェクトに行き詰まりを感じたこともあったし、そう言う時にどうすればスムーズに復活できるんだろうと考えたりしたけど、ググったらよかったんだなと思った。

*3:基本的にタスクがモリモリ増えていくから、定期点検しないと埋もれてしまう。

*4:と言うか、当事者じゃないと真剣に考えられない。。。

*5:役割分担が厳密に定義されたとしても、それをみんなが同じように認識するまでだいぶ時間がかカルシ、同じように認識したからできるわけじゃないし、その時間いるの?って思ったりするから。それなら泥臭くても前に進める方が良さそう