サクサク読めて、アプリ限定の機能も多数!
トップへ戻る
掃除・片付け
qiita.com/tanakahisateru
拙著「ちょうぜつソフトウェア設計入門」の発売から1年を記念した特別イラストです。毎年恒例だったなんとかパターンのシリーズは、ネタ切れでした。今年はこれ単品でご容赦を。 まえがき まずは、いまこそ明かせるちょうぜつソフトウェア設計入門(通称ちょうぜつ本)制作秘話、というほどではないですが、最初はこんな流れでした、というお話をしましょう。 GoFのデザインパターンを1人で書き切るアドベントカレンダーをQiitaでやると宣言し、最終回のバズりのおかげで個人総合1位の座に輝いたのは、2019年のことでした。そこから、技術評論社さんのSoftwareDesignにマンガで釣る入門者向けのシリーズを担当させていただき、その後単著の執筆を企画する機会をいただきました。 実は当初、このキャラクターで何か書く、とは決まっていたのですが「GoFパターンツアーとかでいいんじゃないですかね」ぐらいのゆるい感じでし
ちょうぜつ設計概要 ちょうぜつ設計とは、自分の手でプログラムを書かない人たちの思い込みに反して、一見不思議に見えるけれど、普通の現役エンジニアが当たり前に備えている、暗黙的なソフトウェア設計センスの常識のことである。クリーンアーキテクチャとアーキテクチャ実体のメタ関係と構造的に同じになる。 なぜ変更しやすく作るのか ちょうぜつ設計の目的は変更容易性である。変更が容易なソフトウェアでなければ、反復的な開発に耐えることはできない。 使い捨ての簡単なソフトウェアはウォーターフォールで作ることができる。ウォーターフォールに変更容易性を求めるのは、技術者の自己満足にしかならない。反復的な開発において、以前開発した箇所を調整する、あるいは、運用を続けているサービスを壊さずに機能拡張する、といった目的がなければ、変更容易性は不要である。現代のソフトウェアの主流は当然後者である。 変更容易性は、結果得られ
ここからは「オブジェクトリレーショナル振る舞いパターン」に属すパターンの紹介です。 Unit Of Work パターンは、Domain Model 内で起こるさまざまな変更を、都度データベースに随時反映させず、一連のビジネスロジックが完了した後に、Domain Model の外で最終的な結果をまとめて反映させる方式を指します。 いくつもの構成要素が連携する Domain Model パターンでは、互いに他のオブジェクトのロジックがどうなっているかの詳細には踏み込みません。責務を満たすなら詳細を問わないのが、オブジェクト指向を活かしたモデリングです。が、もし連携するビジネスロジックが SQL を発行していると、それは思わぬパフォーマンス問題につながるかもしれません。 別のオブジェクトにある「ひとつ処理する」のメソッドが便利だからと、軽い気持ちで 10 回呼び出してしまうと、場合によっては 1
複雑なプログラムを書いてしまうのを避けるために、if 文の else を避ける制約を設けてプログラミングしてみましょう、というアプローチがあります。これはあくまで、ThoughtWorks アンソロジーに書かれていた、ある種のプログラミング思考のトレーニング方法のひとつにすぎないものです。 しかし、権威だからか、あるいは、あまりコードを書かない人がわかりやすいと感じるからか、プロダクションコードの規約に使おうとする誤った考えがあります。そんなことをすると、コード品質は下がります。 else 禁止制約というのは、「これまで if-else で記述していた多くのコードは、実は、生成するオブジェクトの多態性によって、分岐の前倒しが可能になるものだったのか」という認識を得られれば、すぐに忘れるべきルールです。 ある実在の OSS コードを例に説明します。 https://github.com/xr
http://wiki.c2.com/?ArchitectureByImplication 日本語のタイトルからその意味をもっとも誤解されやすいのがこの文書化軽視パターンです。このアンチパターンが語っているのは、成果物としてのドキュメントではなく、実装前のアイデア整理のためのドキュメントです。ポイントは文書を残すことではなく、「プログラミングの前に、まず母国語で考えろ」ということです。 英語では Architecture By Implication と名付けられていますが、こちらの方がそのゴールをうまく物語っています。Implication (含意) の逆は Explication (説明) です。言語化されたアイデア分析のプロセスといったニュアンスを持つ言葉です。 書籍の中で日本語タイトルや本文内容が文書化を強く主張しているのは、おそらく、アンチパターン本が書かれた時点では、まだそのた
This article is a Private article. Only a writer and users who know the URL can access it. Please change open range to public in publish setting if you want to share this article with other users.
この業界、デスマーチという用語が安易に使われすぎていると私は感じています。自虐的な表現が好きな日本で、この言葉はとてもウケが良かったのでしょう、他の IT 系ことわざに比べて極端に有名です。 が、そのために誤用も増えてきました。たんに自分の仕事がきつい状態になることを「デスマってる」と表現する人がいますが、本当のデスマーチはそんなものではありません。まず、「マーチ」である以上、個人の問題ではないというのが最重要点です。 デスマーチとは組織の病です。ソフトウェア開発プロジェクトを計画するトップが未熟だと、その素人見積のせいで、見えていない部分の労力に予算と時間を確保されないまま、プロジェクトがスタートしてしまいます。冷静に考えて、リソースが半分しかなければ、50% 以上の進捗が出るはずがありません。愚かな組織人はなぜか、その明らかな失敗を見通す合理的判断をタブー視し、不可能な催促をしたり、品
http://wiki.c2.com/?WalkingThroughaMineField まだ知見の少ない新しい技術を使うことは、バグの地雷原を徒歩で突破するようなものです。地雷に例えるのは、どこに仕掛けられているかわからないため、発生を予見することができないことを表しています。(しかも仕掛けた本人でさえ意識せず) リリース後に何度も問題を起こしては修正され、あるいは問題回避方法が広く知られ、ある意味「枯れた」技術を使うことで、地雷を踏むリスクは下がります。エンドユーザーなら、ある程度こなれた製品を選べばよいのですが、開発者がそればかりでは、先進的な技術にチャレンジして競争力を高めることができません。 比較的安全な最新地雷原の抜け方は、使おうとしているソフトウェアが、リリース前によくテストされているか、開発者の思想が信頼できるかを評価できる目を養うことだと思います。当時はテストを重視と言わ
$item = $query->fetch(); if (!$item) { throw new NotFoundException(); } owner_id と一致しない者がアクセスしたときは 403 Forbidden にして欲しいと顧客が求める可能性はないのか。拡張に対してオープンであろうとする配慮をなぜできないのか。 そもそも、プライマリキーで十分高速にレコードを特定できている時点で、データベースの責務は終わっているのだ。なぜ貴様らは SQL などというモデリング言語外の文字列 にユースケースを実装するのか。 正しいコードを示そう。
誰か作ってくれる人がいることにして、遊ぶほうに意識が行っちゃってますね。いいですね、これこそオブジェクト指向の醍醐味です。 複雑なものをできるだけシンプルにするには「関心の分離」が重要です。とくに、操作に関する知識と生成に関する知識とを分離するのは良いアイデアです。操作のたびに、どういう作りなのかを気にして if - else を書いてしまうと、「ラジコンのプロポをガチャガチャするだけで楽しい」では済まない複雑さになってしまいます。サーボの設定事情などは、どんなちょうぜつ操作をしてもいい感じに動くように生成して、隠蔽すればよいのです。判断を前倒しした結果を生成物に閉じ込めてしまうわけです。 というふうに生成と操作を別のクラスに分離しましょう...で話は終わりません。ここで、操作する人が具体的に誰かに作ってくれと言ってしまう(具象クラス型を利用してしまう)と、操作は生成者に直接依存してしまい
ここまで読んでくださった皆さんに、ちょっとしたクリスマスプレゼント。マンガでわかる GoF デザインパターン 23 種チートシートです。これでもうデザインパターンは完全にマスターしましたよ。やったね! (注: ここからはあとがきポエムです) ところでみなさん、せっかくデザインパターンを学んだので、これを使ってプログラムを書こう、チートシートがあるからなんでも書けそうだぞ、なんて思っていませんか。ダメですよ。そんなことしたら 2000 年前後に起きた失敗を繰り返してしまいます。 実は GoF のデザインパターンは、ビジネス的には成功したけど、教育には失敗しました。最初に出版された本に「オブジェクト指向における再利用のための」という肩書が付いていましたが、これが本当に良くなかった。 あの頃 (ポール・グレアムが LISP と Ruby を褒めるまで) は、「オブジェクト指向様こそが良い設計のす
Mac OSX Mojave は、Retina によってもはや不要となった、サブピクセルアンチエイリアス処理がオフにされました。て、いやこれ Retina ディスプレイなら細いフォントで綺麗なんですが、非 Retina 外部ディスプレイではひどいことになるじゃないですか。 アプリにもよりますが、自分が使っている VSCode はこのありさまでした。 これを以前のアンチエイリアス処理に戻す方法があります。
PhpStorm は、呼び出したメソッドの phpdoc の @throws をヒントに try-catch の不足などをインスペクションすることができます。が、これが現状の PHP コミュニティの例外の意味付けのブレ (PHPの例外はすべて非検査例外 v.s. RuntimeException以外は検査例外) に合わなくて、いろいろなライブラリを使うとすぐに黄色くなってしまいます。 また、「すべての Throwable 発生に割り込んで何かしておきたい」というような場合も、 とすると、メソッドの doc コメントに @throws が足りないよという警告が出て、それに従ってしまうとこんど、コール側に Throws の catch が必要だよという、わけのわからない警告になってしまいます。 そんなこんなでインスペクションを切ってしまうと、こんどは、ビジネスロジック上の例外を捕捉必須のつもり
お疲れ様です。田中です。 PHPのプロジェクトの作業ブランチ内で、追加のライブラリが必要になったとき composer.json に変更を入れますよね。このときおもむろに composer update を叩くと composer.lock に派手な差分が発生するので、絶対にしないでください。 composer update はすべてのパッケージについて、現時点で可能な限り高いマイナーバージョンに上げようとします。当然、自分が master からブランチを切った時点でインストールされていたパッケージのバージョンは、現時点より古くなっています。直接使っているものだけでなく、その依存パッケージも上がります。 いちど composer.lock に大きな差分が発生すると、コミットログが無駄に大きくなるばかりでなく、その後のりベースやマージに支障をきたします。後のリベース/マージ後はつねにフルの
Mackerel はそのままだと Zabbix より監視項目が少ないけど、プラグインを使えば、より個々の構成に固有なメトリクスを過不足なく取得できて嬉しいです。 自分はよく PHP のウェブサーバーを Ansible でプロビジョニングしているのですが、そういうお仕事でオススメな監視設定について、理解しながらチュートリアルを進める感じで紹介します。 お膳立てとして、なるべく CLI をシンプルにするために、カレントに ansible.cfg があるものとします。
現在は実質、argparse か docopt の二択ですね。 元は、python -V とか mysql --version みたいな、コマンドラインオプションを argv から切り分けるために C の getopt を借用。その後、使いやすさを向上させる、optparse が採用されました。 が、そもそも機能的なサポートがオプション引数だけでいいのか、ということで、mv <form> <to> みたいに順序で指定する通常のコマンドライン引数までカバーできる argparse の導入。 ここまでは Python に同梱されるライブラリの世界。こういう感じ: import argparse parser = argparse.ArgumentParser(description='Process some integers.') parser.add_argument( 'integers
PHPUnit は 6.0 で PHP7.0 未満との互換性を切り捨てました。それとともに、Zend1 式の名前空間を捨てて、PHP5.3 で導入された名前空間に移行しました。 <?php use PHPUnit\Framework\TestCase; class MyTestCase extends TestCase { } PHPUnit >= 6.0 にはもう PHPUnit_Framework_TestCase はありません。use PHPUnit\Framework\TestCase; が今後のスタイルです。 でも、弊社まだ本番に 5.x がいるんですよ、とか、自分の公開しているライブラリ/フレームワークには 5.x 互換性の維持が必要で、とか、完全に 7 になりきれない事情がいろいろありますよね。高い方に合わせると前のやつが動かない、低い方に合わせておけばどうにか両バージョン動
イライラ 素の PhpStorm でイラっとくる箇所といえばダントツ、PHPUnit のモックあたりですよね。こう書かないといけないの。 $connector = new SomeMiddlewareProcess(); /** @var MiddlewareInterface|\PHPUnit_Framework_MockObject_MockObject $processor */ $processor = $this->createMock(MiddlewareInterface::class); $connector->setProcessor($processor); setProcessor の引数定義に MiddlewareInterface のタイプヒント付いてて、docコメントがないと MockObject 型だぜ間違ってるYo! って警告にされちゃうやつ。 最近だと a
Cmd + A からの ssss で Start SSH Session にヒットします。 まあ、プラグインの機能名にコンフリクトがなければ sss でも十分です。で、もしプロジェクト設定で Vagrantfile の場所を設定してればこう... 何が嬉しいかというと、実はこれ Option + F12 の Terminal のシェルで vagrant ssh するより起動が速いのです。 通常、vagrant ssh-config コマンドの実行は3〜5秒かかり、vagrabnt ssh は内部的にそれやってからのSSHなので、ちょっともたっとします。が、PhpStorm など JetBrains の IDE はこの vagrant ssh-config の結果をキャッシュしているようです。なので、毎回の待ちが起きない。 てかやっぱ、なんか s キー4回ダダダダッとやるのが気持ちいい。それ
結論 日本語入力の設定で円記号をバックスラッシュに割り当てるのはやめて、Hammerspoon で以下のスクリプトを使います。 --- Perfect backslash(\) for Mac JIS keybord users -- The problem: -- On Mac, Japanese IME setting to replace Yen-backslash is ignored by -- IntelliJ, jEdit or such as because JVM uses another keymap traditionally. -- Solution: -- Use Hammerspoon (http://www.hammerspoon.org/) instead of Japanese IME -- setting. Paste below to your ~/.
PHP は各種プログラム言語の中でも比較的高級な (表現力が豊かで最適な記述を選ぶのに知識を必要とする) 例外モデルを持っていると言えます。そんな PHP の例外の各区分とその使い分けを整理し、PHP の例外モデルの設計意図を考察したいと思います。 PHP例外の分類 PHP の例外は Java とは異なり、(Error を合わせると) 合計 4 つの区分に分類されます。Java には 2 区分しかありません。(PHP では Java の Error に相当するものは発生しません。PHP の Error は Java では RuntimeException の一種に分類されています) PHP Java
自分が Go で誰かと何か作るなら、まずここまでを共有してからにしたい、という勝手な理由ですぐ見てもらえるところにこれ置いときます。 ディレクトリ How to Write Go Code を読みましょう。ただし、これだけでは src の下に依存パッケージ置き場 vendor を置けることに言及してないので、Gopher Academuy Blog の Understanding and using the vendor folder で補うのが手っ取り早いです。 そのうえで、 Glide | Package Management For Go を使いましょう。チームメンバーに足りないパッケージをコツコツ $GOPATH/src/github.com/ に go get させず、チームが決めた依存パッケージが自動的に vendor にインストールされるようにしましょう。 /.../your
Webアプリケーションは基本はHTTPリクエストごとにステートレスなので、いくらプログラムが並列で動いていても、それをほとんど意識せずに書けて簡単です。が、データを保存するとなると少々厄介です。ユーザーが自分専用のデータを変更するときは問題ありません。同じ共有データに同時に複数の人から書き込みがある場合が問題です。 といっても、WebではRDBを使って当たり前というこの時代、トランザクションという高級で暗黙な排他制御があるんだから任せればいいやと、同時書き込みを気にする人は少なくなりました。むかしはファイルシステムのロックを利用したりして、アクセスを排他制御したものです。 なーんだ、いまどきトランザクション切れないSQLなんてないから、排他制御なんてもう忘れていいんじゃん... とは言えない事情が最近出てきています。NoSQLを併用したとき、バックグラウンドに非同期のジョブキューがあるとき
基本は http://www.1x1.jp/blog/2014/08/how-to-setup-php-remote-debug-with-vagrant-vm.html こちらからどうぞ。 大事なポイント = CLI で PHP を実行するとき XDEBUG_CONFIG 環境変数が存在しないと Xdebug が動きはじめないことがあります。 VM の php.ini には xdebug.remote_enable や xdebug.remote_host が書いてあって、Webアプリケーションならデバッグできるという状況で、なぜか CLI だとうまくいかないことがあります。xdebug.remote_autostart=Off にしておいてブックマークレットでXdebugをON/OFFしながら Web をデバッグしているんじゃないですか? そんなときは XDEBUG_CONFIG=""
YiiのActiveRecord/ActiveQueryは、比較的SQLを隠蔽しないタイプの、軽量なORMです。軽いORMは、永続オブジェクトを一元管理しないため、都度場合に応じてSQLをチューニングできるメリットがある反面、全体を意識しないと、すでに取得済みのレコードを何度も取得し、同じレコードに対して異なるオブジェクトを生成してしまうリスクがあります。 これを勝手に「妻の夫は私以外の誰か」問題と名づけました。「彼女の彼氏が俺じゃない」問題でもかまいません。 1 to 1 の例 簡単な例として、互いに hasOne 関係なレコードを考えてみてください。2つのレコードは pair で相互にリンクし合っている、夫婦のような関係があるとします。つまり、pair の pair は自分になるはずです。 $model = SomeModel::find()->where(['id' => 1])->
データベースを含んだ自動テストは面倒ですね。なにが面倒って、テスト用のデータ、いわゆるフィクスチャを準備するのがもう。 Yii はデータベースの結果をモックする純粋なロジックテストではなく、ファンクショナルテストやデータベース込みのテストを指向しています。2.0 になって、BDDふうのテスティングフレームワーク Codeception のテストプロジェクトが一式ついてくるようになりました。BDD ふうにページをテストするにはホンモノが動くことが前提、つまりデータベースも当然要るわけです。 フィクスチャはすべて手書きしてもいいのですが、たとえば 21 件以上でページネーションすることを試そうと思ったら... というわけで Faker を活用しましょう。 Yii のプロジェクトテンプレートの tests フォルダ以下には、テスト環境専用の codeception\bin\yii コマンドが置い
タイトルのまんまですが、Yii2 にかぎらず、自動テストを一括実行したさい大量にアプリケーションログが出るのは無駄だしいろいろヤバいので、ログを出力しないようにしましょう、という話です。 ログを出力するべきとき Yii2 だとデバッガで見るとわかりますが、高度な Web アプリケーションフレームワークは、ひとつのリクエストが非常に多くのログを出力します。多くは単なるトレースログですが、きちんと完成している場合でも、警告やエラーは含まれます。 というのも、通常のナビゲーションでは起こらないような不正アクセスが起きた場合や、UIで想定していないようなクエリパラメータの間違いがあった場合は、それらをログに残すべきでだからです。 たとえば、ユーザーのログイン失敗が連続して起こっているとき、それは以下のようなコードでログを出力して検知できます。 class LoginForm extends Mod
海の向こうのサーバーで日時の扱いをどうするのかは、いつも悩ましいところです。自分なりの答えを先に言うと、論理値以外のリアルな日時は UTC ベースの Unix タイムスタンプで正規化して扱い、画面表示するまでに別の形式に変換するのは禁止です。 以上。 というのは乱暴なので、Yii2 で日時がどう扱われるかを見ながら、その根拠を考えてみたいと思います。 Yii2 における日時 Yii2 のアプリケーションテンプレートでは、タイムスタンプの日時をデータベースに保存するさい、整数型で Unix タイムスタンプの整数値を保存するようになっています。 [ // ... 'created_at' => Schema::TYPE_INTEGER . ' NOT NULL', 'updated_at' => Schema::TYPE_INTEGER . ' NOT NULL', ] これはなぜでしょう?
エラーを放置するとコードフォーマッターで文法を壊されます。とくにRubyはスペースあけるあけないで変わってくるので。 これは Ruby1.8 にない文法ゆえに出ている、というのがわかればこう書き換えればいいのですが: なんでこんな変更したのか意味わかりませんね。負けた気になります。 Ruby プラグインは、Ruby SDK が指定されているモジュール以下のファイルでないと、文法バージョンを指定できません。指定できなかったときのデフォルトは 1.8 になります。エー (´Д`) 強引な方法としては、プロジェクトのルートを Ruby モジュールとして定義し、そのモジュールが使用する Ruby SDK に、1.9 以上のものを指定します。たとえPHPのプロジェクトだろうとPythonのプロジェクトだろうと、ルートモジュールの種類を Ruby にしてしまうという... PythonやPHPとは競合
次のページ
このページを最初にブックマークしてみませんか?
『@tanakahisateruのマイページ - Qiita』の新着エントリーを見る
j次のブックマーク
k前のブックマーク
lあとで読む
eコメント一覧を開く
oページを開く