読者です 読者をやめる 読者になる 読者になる

sifue's blog

プログラマな二児の父の日常

WEB+DB PRESS Vol.82 にオブジェクト指向アプローチによる変更に強いテーブル設計という記事を書かせてもらいました

今回でデータベース実践活用の連載2回目ですが、この度は、オブジェクト指向アプローチによる変更に強いテーブル設計、というタイトルで記事を書かせて頂きました。

写真は先ほど届いた査読誌です。

f:id:sifue:20140820224121j:plain

内容は、テーブル設計をやりはじめたばかりの新人エンジニア向けの初歩的なオブジェクト間の関連の定義の仕方から、マーチン・ファウラーのテーブル継承の手法、そして最近流行りの大規模WEBにおける具象テーブル継承のデメリットを打ち消すID設計戦略までを説明しています。

そしてこの度は、漢(オトコ)のコンピューター道で有名な奥野さん、達人に学ぶSQL徹底指南書で有名なミックさんにも査読いただき、とてもよい内容にまとまっていると思います。

おそらくWEBでDBを触っているエンジニアならば読んで損はない記事になっていると思いますので、8月23日発売ですのでぜひお買い求め下さい~。

 

WEB+DB PRESS Vol.82

WEB+DB PRESS Vol.82

  • 作者: 山口徹,Jxck,佐々木大輔,横路隆,加来純一,山本伶,大平武志,米川健一,坂本登史文,若原祥正,和久田龍,平栗遵宜,伊藤直也,佐藤太一,高橋俊幸,海野弘成,五嶋壮晃,佐藤歩,吉村総一郎,橋本翔,舘野祐一,中島聡,渡邊恵太,はまちや2,竹原,河合宜文,WEB+DB PRESS編集部
  • 出版社/メーカー: 技術評論社
  • 発売日: 2014/08/23
  • メディア: 大型本
  • この商品を含むブログを見る
 

追伸

今回は一番最初に出ているこのWebAPIデザインの鉄則がすごくよい記事だなと思いました。というかいつも悩んでるだよなぁ。

既存のIRCボットをSlack対応させた時にハマった点

最近Slackが大ブームということもあって、IRCやその他のチャットシステムからSlackに移行している方も多いと思います。そんな中、IRCのgatewayがあるということで、IRCのボット資産をSlackに移行するために自身がハマった点が何点かあったのでまとめておきます。

今回IRCからSlack対応させたのは、自身がScalaでメンテナンスしているranking_ircbotというチャンネルにおける発言回数と名言を保存しておいてくれるボットです。

 

問題になった点は以下4点。

 

  1. noticeがない
  2. IRCの通信をSSL化しないといけない
  3. IRCのgatewayを使う場合、専用のアカウントがないといけない
  4. IRCのgatewaybotが発言しまくると、そのチャンネルにおいてIRCを通じて発言できなくなる

 

になります。

 

1.noticeがない。これに関しては諦めざるを得ません。なので、noticeがなくてもよい運用にしましょう。幸い@usernameで呼びかけるとSlackから相手に通知が行くので通常の投稿と、人に通知を送りたい場合は@usernameを入れて対応するということで、通常のメッセージにはあまり反応しないような運用が良いのではないかと思います。あと変わりに_でメッセージを囲ってイタリックにしてやる方法や@usernameにゼロサイズスペースや_を挟んでnotice反応しないようにするのも手です。

 

2. IRCの通信をSSL化しないといけない。これはSSL対応しているIRCクライアントを利用する必要があります。自身が使っているsIRCというJavaIRCクライアントライブラリは対応があったため、特に問題なく移行することができました。Java系だと、証明書を登録するか無視するかのどちらかの対応をしなくてはいけないというのがちょっと面倒臭いところです。自分は無視しています。

 

3.IRCのgatewayを使う場合、専用のアカウントがないといけない。これが一番厄介で、IRCで発言するようにすると、SSLのサーバー認証がユーザーIDとパスワードで行うため、登録ユーザーIDがボットの動きをしてしまうことになります。

なお自身のアカウントでbotを動かすと、人格をbotに乗っ取られるような感じになりますw

なお、ボット専用のメールアドレス等を用意されるのであればそれで対応されるのも良いかと思います。

 

それでも回避しきれないのが次の問題で、4.IRCのgatewaybotが発言しまくると、そのチャンネルにおいてIRCを通じて発言できなくなるという問題です(ちなみにこれ解除するためにはパスワードを再生成しないとダメです)。おそらく、Slackが、REST APIの制限の抜け道をIRCでやられないようにこのような制限をかけているのだと思います。

 

この3番、4番の問題を解決するために、最終的に、取得だけはIRCのチャンネルからストリームで取得し、発言はSlack REST APIから行うようにしました。ただし、こちらは1秒間に1回しか発言しないように制御する必要があります。

そこで自分はScalaで実装していたので、Javaの並行プログラミングユーティリティのSemaphoreを利用して、Slackのクライアントを以下HTTPクライアントのdispatchを使って下のように実装しました。このおかげで1秒間に1回以上連投をせずにちゃんとブロックしてくれるようになります。

Slack API Client for Message Posting with API limi ...

 

以上が、SlackにIRCボットを対応させるために行った時にハマったこととその対応になります。参考になれば幸いです。

社内LTでOpen Broadcaster Software(OBS)のプラグインを作ってみたことを発表しました

発表の半分以上がLoLの説明なのは仕様です。どっぷりハマっております。

作成したプラグインソースコード

sifue/CLRStudy · GitHub

です。

こと生放送の配信ツールという意味では、完全にOBSがデファクトスタンダードになりつつあるなぁとおもう今日このごろ。

恐ろしく軽くて、日本語のローカリゼーションも完璧でな所がすごい。

ただ、プラグインでできるのは映像ソースや音声ソースの追加がメインな所がちょっと残念な所。まあOSSだから特に問題にはならないけれども。

「データベース実践活用」の連載をはじめました

本日発売のWEB+DB PRESS Vol.81からデータベース実践活用という記事の連載をはじめました。次回と次々回まで自分が担当する予定です。

 

WEB+DB PRESS Vol.81

WEB+DB PRESS Vol.81

 

 

第一回目は、オブジェクト指向プログラミングを利用したDAO設計パターンの紹介です。DAOってあれですね、データアクセスオブジェクトです。RDBとかKVSとかファイルとかごにょごにょするオブジェクト群のことですね。


最近は、ORMとかいろいろ便利なライブラリが整備されてはきてるんですが、実際にはDAOの実装にはいろいろなパターンがあって、作るシステムの要件によって最適な実装というのは異なってきます。特に最近は、扱うデータストアがRDBだけじゃないってこともあってより、複雑なDAOの設計が求められています。

 

今回の記事の内容は、エンジニアが担当ソフトウェアアーキテクトになってWEBシステムを作る際、データストアの構成、ドライバの選定、ORMの選定までは済んだけれども、ソフトウェアの設計をどのようにしようかと悩んだ時に役に立てばいいな、という内容になっています。

 

今回紹介しているパターンは以下の表の通り。

パターン名概要用途保守/拡張性能実装コスト
トランザクションスクリプト データベースに対する一連の手続きをタスクとしてオブジェクト化する手法。共通ロジックに関してはサブタスクにすることもある 長期保守しない、パフォーマンスが求められるシステムの実装 とても低い とても低い
テーブルゲートウェイ データベースのテーブルに対しての処理のゲートウェイとなるオブジェクトを用意する手法 短期間の保守を行い、複数のテーブルをまたぐような複雑なビジネスロジックが存在しないシステムの実装 低い 低いがテーブル間の関連が多いビジネスロジックの場合は高い
アクティブレコード データベースのテーブルが持つ特定の行をラップする手法。オブジェクトはデータと振る舞いの両方の特性を持つ データベースの構造とビジネスロジック乖離(かいり)が少ないシステムの実装。または、要求変化が少ないプロトタイプの実装 中程度だが単純なビジネスロジックの場合は高い 中程度
データマッパ 永続化対象、データベース、マッパ自体がそれぞれ独立したオブジェクトとなっている構造を持つ 中長期の保守が求められ、複数のデータベースおよびテーブルより1つのオブジェクトを構成するようなある程度複雑なビジネスロジックを扱うことのあるシステムの実装 高い 高い
ドメイン駆動設計におけるリポジトリ データマッパの抽象度をさらに高め、扱う永続化対象オブジェクトとビジネスロジックで扱うオブジェクトを分離する方法。また実際の永続化方法についてはビジネスロジックからの隠蔽(いんぺい)を行う 長期保守が求められ、ビジネスロジックのデータベースへの依存を断ち切りビジネスロジックが凝集されたモジュールを構成しなくては保守が難しくなるような、とても複雑なビジネスロジックを扱うシステムの実装 とても高い とても高い

 

特に、アクティブレコードパターンと、データマッパーパターン、ドメイン駆動設計(DDD)のリポジトリあたりは実際にどれを採用するか、WEBシステムのアーキテクチャなら一度は頭を悩ませたことがあるのではないかと思います。

実際にはどの方法にも良し悪しがあるので、これが一番!ということはできませんが、クラス図と共に細かく説明していますのでご一読頂ければ適切な判断ができるようになるのではと思います。

 

またDDDのリポジトリのは特に実際どのようにすべきかということで悩まれている方もいらっしゃるかもしれません。なので今回は具体的な実装を十分に用意してみました。番組と番組タグという情報を例に取ったScalaの実装例を sifue/oopdb · GitHub および サポートページ:WEB+DB PRESS Vol.81:|gihyo.jp … 技術評論社 にて公開しております。sbtでビルドして動かすこともできるので気になる方はこちらの方をみてどのような構成になっているのか見てみてください。

 

追伸
実はサンプルコードを最初はJavaで書いてくれと言われたのですが、PoEAAやエリック・エヴァンスのDDD本にもJavaのサンプルコードは沢山あるし、Scalaの方が短くかけて構造が簡潔に伝わりやすいと思い、Scalaを選択しました。型があるのに短くかけるScala、いいですね。

 

さくらVPSのCentOS6.5を最初からセットアップする時にしたこと

CentOSのバージョンを上げないといけない自体になったので、久しぶりにセットアップ作業。その記録をメモ。

 

Heartbleed脆弱性のために最新版OpenSSLの確認

# openssl version

全ライブラリのアップデート

# yum update

SSHのポート変更して再起動

# vi /etc/ssh/sshd_config

# service sshd restart

 

ユーザーの追加とパスワードの設定とsudoerの追加

 

# adduser hoge

# passwd hoge

# visudo

 

コンソール作業の必須ツールのインストール

# wget http://pkgs.repoforge.org/tmux/tmux-1.6-1.el6.rf.x86_64.rpm

# yum localinstall tmux-1.6-1.el6.rf.x86_64.rpm

# wget http://pkgs.repoforge.org/git/git-1.7.10-1.el6.rfx.x86_64.rpm

# yum localinstall git-1.7.10-1.el6.rfx.x86_64.rpm

# wget http://downloads.sourceforge.net/project/zsh/zsh/5.0.5/zsh-5.0.5.tar.gz

# cd zsh-5.0.5

# ./configure

# make

# make install

# vi /etc/shells

 

最後に/usr/local/bin/zshをshellsファイルに足す

 

http://d.hatena.ne.jp/hits-inju669/20131123/1385221276

を参考にvim7.4をインストール

 

# yum groupinstall 'Development tools'

# yum install ncurses ncurses-devel

# cd /usr/local/src

# wget ftp://ftp.vim.org/pub/vim/unix/vim-7.4.tar.bz2

# tar -xjf vim-7.4.tar.bz2

# cd vim74

# ./configure --prefix=/usr --with-features=huge --enable-pythoninterp --enable-luainterp

# make && make install

 

SSH鍵の作成

$ ssh-keygen

 

公開鍵をgithubに登録した後、

https://github.com/sifue/dotfiles

dotfilesをチェックアウトしてsetup.shで設定

 

ZSHに変更

# chsh

 

VimのNeoBundleをインストール

https://github.com/Shougo/neobundle.vim

その後、:NeoBundleInstallをvim上で実行して最低限の設定は完了。

PHP開発においてVimやST2にはできないけれどPHPStromにはできる10のこと

【blog.soichiro.orgの閉鎖にともない転載しました】

f:id:sifue:20140429122030p:plain


今まで散々VimSublime Text2のエントリーばかり書いていた自分ですが、運良くIntelliJ IDEA UltimateのオープンソースライセンスをJet Brain社から頂いたこともあってPHPStorm (IntelliJPHPプラグイン)を利用し始めました。 このスクリーンショットのようなUIです。

PHPStorm、さすがは有料のPHP用のIDEだけあってST2やVimプラグインでできる機能とは格が違う自動生成やリファクタリング機能を持っています。お値段はコマーシャルライセンスで$199、個人で$99、学生で$29という高価格帯。にも関わらず、FacebookMediaWikizyngaVALVE(洋ゲー販売のSteamで有名な)で正式採用されるIDEなだけあります。

ぶっちゃけて言うと、このクソ言語を使って大規模開発をせざるを得ないPHPerで、懐に余裕のある方にはぜひオススメしたいIDEです。
一日3時間以上PHPを書いたり、読んでいたりする人は買って損はないかと思いますが、ただこの価格なので無理強いすることはできません。なので、利用するかどうかの判断材料になるようにとVimやST2にはできないけれどPHPStormにはできる機能だけをまとめることにしました。

ちなみに、それVimやST2でもできるよ、って言いたくてVimプラグインやST2のパッケージを作って下さる方もいるとは思いますが、2013年3月12日時点で自分が満足にいく拡張を見つけられなかったものだけをまとめてあります。

1. 型情報のあるコメントを補完するゲッターセッターの自動生成

GetterSetterのジェネレーターというのは結構エディタにもプラグインが存在しているのですが、型情報のコメントまで丁寧に作ってくれるジェネレーターはなかなかありません。以下の様な手順です。

f:id:sifue:20140429122049p:plain


以上のエンティティクラスで右クリックしてGenerate...を選択します。

f:id:sifue:20140429122107p:plain


その後出てくるコマンドでGetters Settersを選択します。

f:id:sifue:20140429122120p:plain


GetterやSetterを生成したいフィールドを選択します。

f:id:sifue:20140429122133p:plain


このように型情報コメントを保管するゲッターセッターを自動生成してくれます。

f:id:sifue:20140429122148p:plain


さすがにここまでやってくれるエディタのプラグインはありませんでした。

2. コンストラクタの自動生成

ゲッターセッターの自動生成プラグインは結構な数あるのですが、コンストラクタの自動生成は中々ありません。先ほどのエンティティクラスで右クリック、Generate...で出てくるコマンドで、Constructorを選択します。

f:id:sifue:20140429122209p:plain


コンストラクタで代入したいフィールドを選択します。

f:id:sifue:20140429122230p:plain


このように簡単にコンストラクタが自動生成されます。

f:id:sifue:20140429122243p:plain

3. オーバーライド可能なメソッドの自動生成

継承クラスのオーバーライドしたいメソッドも自動生成してくれます。以下のようにまずクラスを継承します。

f:id:sifue:20140429122301p:plain


その後、また右クリックのGenerate...からOrveride Methods...を選択します。

f:id:sifue:20140429122331p:plain


次にオーバーライドしたいメソッドを選択します。

f:id:sifue:20140429122346p:plain


すると以下のようにメソッドが自動生成されます。

f:id:sifue:20140429122354p:plain

4. 未実装のインターフェースのメソッドの自動生成

クラス宣言のimplements句にインターフェースを設定します。メソッドが未実装なので赤いラインでエラーが出ていますが、右クリックのGenerate...からImplement Methods...を選択します。

f:id:sifue:20140429122409p:plain

 

f:id:sifue:20140429122419p:plain


ここで、実装したいメソッドを選択します。

f:id:sifue:20140429122430p:plain


このように、実装しなくてはいけないメソッドが自動生成されます。

f:id:sifue:20140429122441p:plain

5. メソッドの呼び出し階層の表示

メソッドの呼び出しがどこで行われているのかを、再帰的に知りたい場合はメソッドを選択して、メニューのNavigateからCall Hierarchyを選択します。

f:id:sifue:20140429122458p:plain


すると、再帰的にどういうふうにメソッドが呼ばれているのか見ることができます。

f:id:sifue:20140429122508p:plain


この場合は、handleメソッドを呼んでいるstartメソッドが更にBasicAuthenticationLitenerのhandleメソッドから呼ばれていることがわかります。

6. クラス名、メソッド名、変数名の全ファイル自動リファクタリング

命名を変更するリファクタリングも強力で、全てのファイルを自動的に修正してくれます。まずクラス名などを選択して右クリック、Refactor > Rename...を選択します。

f:id:sifue:20140429122518p:plain


変更したいクラス名を入力します。

f:id:sifue:20140429122536p:plain


ファイル自体の変更を確認したOKを押すとリファクタリング完了です。

f:id:sifue:20140429122548p:plain


ファイル名はもちろんのこと、全ての呼び出し元のクラス名が修正されます。非常に強力です。

f:id:sifue:20140429122559p:plain

 

f:id:sifue:20140429122609p:plain


ただしこのリファクタリング、全ファイルを自動的に書き換えるという強力さ故にUndoはできないようですので、慎重に実施ください。

7. 変数、定数、フィールドへの抽出

変数、定数、フィールドへのくくりだしも簡単です。変数にくくり出したいときは、くくりだしたい部分を選択して、右クリックRefactor > Extract > Variableです。定数の場合はConstant、フィールドの場合はFieldを選択します。

f:id:sifue:20140429122630p:plain

 

f:id:sifue:20140429122642p:plain


変数名は何がいいか聞かれるので入力します。

f:id:sifue:20140429122653p:plain

f:id:sifue:20140429122707p:plain


このように変数に抽出されます。

8. 処理のメソッドへのくくり出し

処理のメソッドへのくくりだしも自動です。どの変数使ってるんだっけなというように頭を悩ませることもありません。処理を選択して、右クリック Refactor > Extract > Methodを押します。

f:id:sifue:20140429122722p:plain

 

f:id:sifue:20140429122734p:plain


メソッド名と引数の順番を聞かれるので設定します。

f:id:sifue:20140429122746p:plain


このように処理がメソッドに抽出されます。

f:id:sifue:20140429123633p:plain

9. 使ってないインポート文(use句)の表示

使ってないインポート文はこのように、灰色に表示されてわかりやすくなっています。

f:id:sifue:20140429123639p:plain

10. タイプヒンティングとデフォルト値を元に型情報を補完するPHPDocの自動生成

GetterSetterの所で型情報の入ったコメントが自動生成されるので基本的に同じなのですが、ファイル上で右クリックしてGenerateを選択した後、PHPDoc Blocks..を選択します。

f:id:sifue:20140429123702p:plain


次にPHPDocを生成したいメソッドを選択します。

f:id:sifue:20140429123731p:plain


このように、タイプヒンティングとデフォルト値を元に自動的に型情報を持ったPHPDocを自動生成してくれます。うーん便利。

f:id:sifue:20140429123741p:plain

以上です。まとめると、

1. 型情報のあるコメントを補完するゲッターセッターの自動生成
2. コンストラクタの自動生成
3. オーバーライド可能なメソッドの自動生成
4. 未実装のインターフェースのメソッドの自動生成
5. メソッドの呼び出し階層の表示
6. クラス名、メソッド名、変数名の全ファイル自動リファクタリング
7. 変数、定数、フィールドへの抽出
8. 処理のメソッドへのくくり出し
9. 使ってないインポート文(use句)の表示
10. タイプヒンティングとデフォルト値を元に型情報を補完するPHPDocの自動生成

これが自分がまとめたVimやST2にはない、PHPStormの機能でした。
細かい所で言うと各種タグジャンプや補完機能、シンタックスハイライトやコードスタイルの設定などもIDEならではの上をゆく便利さがあります。ただこのへんの機能は頑張ればVimやST2でもある程度用意可能なので割愛します。

なお自分は、リモートのPHPファイルを編集する必要があったので、ローカルにバージョン管理システムを使ってチェックアウトしたソースコードをPHPStormのDeployment機能のAutomatic Upload機能を使って、リモートのマウントしているディレクトリに自動送信させて使っています。

リモートにしかPHPが動かせるサーバー環境があいよという方は、このようにSSHSambaなどでリモートディレクトリをマウントして、Deployment機能を使ってやるこのやり方がよいと思います。ちなみに最初はマウントしたリモートディレクトリをそのままPHPStormのワークスペースとして利用しようとしましたが、あまりの重さに使い物になりませんでしたw

一応PHPStormは30日間は無料でお試しできますので、一度は使ってみるのも一つなのではないかなと思います。
以上、ここまで読んでくださり誠に頂きありがとうございました。

ScalaとSlickで発言数順位表示と名言記録をするIRCボットを作りました

【blog.soichiro.orgの閉鎖にともない転載しました】

最近IRCボットを書いたりすることが多いのですが、また汎用的なものを一つ書いてみたので公開します。今回は初めてORMとしてSlick、組み込みDBとしてH2を使ってみましたが。Slickは内部処理がわかりにくいが関数言語的にかける特徴的なORM、H2はSqliteよりも軽快でWebベースのGUIがデフォルトで用意されていて非常に使いやすい印象でした。

f:id:sifue:20140429120524p:plain

今回のビルド可能なソースコードは、GitHubにて公開しています。

今回作ったRanking Ircbotについて

IRCの発言数ランキングと名言の登録、及び登録数のランキングをチャンネルごとに設定できるIRCのボットです。 複数のチャンネルに参加し、kickされても戻ってきたり、 オペレーター権限を与えられている場合、他の参加者にオペレーター権限を分け与えたりする機能があります。

ビルド方法

java(jdk6以上)とsbt(0.12.2)をインストールの上、

$ sbt
> assembly

以上を実行することで、targetディレクトリの中に、ranking_ircbot-assembly-2.X.jarがビルドされます。

使い方

ranking_ircbot-assembly-2.X.jarと同じディレクトリに、 ranking_ircbot_template.propertiesを正しく編集して、 ranking_ircbot.propertiesというファイル名で保存ください。 さらに、ranking_ircbot_empty.h2.dbを ranking_ircbot.h2.dbという名前に変更してください。

irc.address = hostname
irc.channel = #channelname1 #channelname2
irc.nickname = ranking_ircbot
irc.charset = UTF-8
db.url = jdbc:h2:file:ranking_ircbot
db.driver = org.h2.Driver

以上のようにチャンネルはスペース区切りで複数設定することができます。 日本語のチャンネル名は、native2asciiのwebサービスなどを利用して 入力することができます。

設定の後、

$java -jar ranking_ircbot-assembly-2.X.jar

で実行することができます。 またIRCのボットが入っているチャンネルにて

ping bot_nickname

とするとWorking now.とnoticeを返して動作確認をすることができます。

使い方

ranking_ircbotが参加しているチャンネルにて以下のメッセージを打つと様々な機能が利用できます。

hourlyranking>
1時間の発言数ランキングの表示

dailyranking>
24時間の発言数ランキングの表示

weeklyranking>1週間の発言数ランキングの表示

monthlyranking>
30日間の発言数ランキングの表示

yearlyranking>
1年間の発言数ランキングの表示

覚えろ:{nickname} {message}
そのチャンネルで{nickname}の名言を保存

{nickname} 曰く
そのチャンネルで保存している{nickname}の名言をランダムで発言

消して:{nickname} {message}
そのチャンネルで{nickname}で発言登録された{message}を全て削除

wiseranking>
そのチャンネルで保存されている名言の個数のランキングを表示

ping {ircbot_nickname}
Working now. > {nickname} https://github.com/sifue/ranking_ircbot

と発言します。

 

以上のような機能を持っています。

Slickについて

今までScalaのORMにSquerylを使っていたのですが、今回はじめて、ScalaQueryの後継でtypesafeが作っているORMのSlickがScala2.10で使えるということで使ってみました。

今までのORMっぽくなく、かなり関数型言語っぽく書けるORMです。結構戸惑ったのは

Slickのコード例

 

このようにlist()を一度でも読んでしまうと、count関数がうまく流れないのではと思っていたら、ちゃんとselect count(*)が流れるように最適化されていたりするところが、ちょっとわかりにくかったところでした。

あと、GroupByの書き方がちょっと特殊でした。

Slickのコード例2


のようにタプルで受け取る形式となります。このように短く取り扱おうと思うとタブルで受け取る形式になるので、このへんはうまく書かないとわかりにくくなってしまうかもしれません。確かに短くて済むのですがコードの可読性を保つためにはちょっと工夫が必要かなと思いました。

H2 databaseについて

ダウンロードして、梱包されているh2.shを実行して、dbのURLを入力してログインすると。

f:id:sifue:20140429121245p:plain


以上のようなUIが実行できて、自由に編集することができます。今まで使って来なかったのでこの親切さにおどろきました。すばらしい。
しかも実行速度もsqliteよりも速く、とても気に入ってしまいました。今後もH2は組み込みDBとして利用していければと思っています。