susumuis – susumuis Info https://susumuishigami.github.io/susumuisinfo Webエンジニア susumuis の技術ブログ Fri, 18 Nov 2022 16:55:34 +0000 ja hourly 1 https://wordpress.org/?v=6.4.3 「Twitter終了」と聞いたら俄然意欲が湧いてきた https://susumuishigami.github.io/susumuisinfo/entry/2022/riptwitter Fri, 18 Nov 2022 16:36:59 +0000 Twitter終了」がトレンドらしい。

当方、Twitter廃民の一人であるので、終了したら困る。非常に困る。

移行先どうこうではない。Twitterは空気だ。ツイートは呼吸だ。残念だがこの体は異国の地では生きられそうにない。

朝起きたらツイートをし、仕事の息抜きにツイートをし、ご飯を食べながらツイートをし、夜寝る前にツイートをする。休日もツイートしながら過ごしている。

最近の友達つながりはほぼ全てTwitterで作ってきた。「いいね」送り合うところから始まり、リプで絡んで、「ここぞ」というタイミングでDM送ってリアルに出会う。最近はそうして作った友達ばかりだ。

家にテレビがない、新聞も購読していない僕は、Twitterでニュースを知る。Twitterがなければ世の中を知ることもできないだろう。

つまり、Twitterが終わったら、生活が終了する。僕の人生は終わりだ。

どうしてこうなってしまったのだろうか?考えてみたら、むしろ意欲が湧いてきた。

そもそも、僕はASPというものが嫌いだった。Gmailもはてなも使いたくなかった。本来インターネットというのはオープンなプロトコルで分散された素敵な世界なのだ。それを「Web」という論文を共有するためのプロトコルの上に、Webメールやインターネット掲示板、Webチャットのような劣化されたソフトウェアを構築して何が嬉しいのだろうか。しかもソースコードはクローズドだ。SMTP/IMAP4、NNTP、IRCを使おう!それらはオープンだから誰でもサーバーやクライアントを作れる。SNSなんて「オープンなインターネッツをクローズドなものにする、なんてとんでもない邪悪なやつ!絶対にやるもんか!」

ところが「絶対にやるもんか!」と言った半年後mixi廃人になってた。Gmail以外のメールをもう10年以上使っていない。負けた。俺が悪かった。もうTwitterでつぶやいているだけで良いや。そして、いつしかブログも書かない「つい廃人」になっていた。

しかし、今「Twitterが終わる」かもしれない。これは転機かもしれない!

「Twitterがあるからいいや」という怠惰から目を覚ませ!Tweetはなんのオープンなプロトコルでもない。一企業のクローズドソースサービスじゃないか!お前の大事な発信を一企業にゆだねて良いのか!「HTML」というオープンフォーマットをなぜ使わない!

今、mstdn.jpfedibird.comのユーザーが増えているらしい。急なトラフィック増で、Twitterよりも瀕死になりつつ、中の人は頑張っている。僕もアカウントを作った。

https://mstdn.jp/@susumuis

https://fedibird.com/@susumuis

これらを今後使うかどうかはこれから考える。しかし分かったことがある。面白いのは「マストドン」ではない、これらをつなぐFediverseというプロトコルがあるということだ!マストドンのユーザーが増えれば増えるほどFediverseのユーザーが増える。これこそがインターネッツではないか!

僕はプログラマーだ。簡単なWebアプリなら作れる。AWSを使えば個人用途のサーバーも立てられる。自分のサーバーから、自分のドメインを使って、Fediverseに発信したい!これが理想だと思う。毎月費用を払って取得しているドメイン、SSL証明書、まさに「公式」ではないか!

それに、何かまとめて発信したければブログを書けば良い。ストックされるし後から参照しやすい。今はWordPressで構築したブログを使っているけど、全然気に入っていないので、一旦廃止して、Djangoかなにかで独自のブログサービスを作りたい。その方がWordPressのプラグインをごった煮にするよりも楽に開発できる気がする。今はAWSもGitHub ActionsもあるからソースをPushしてDeployする仕組みを構築するのは容易だ。

10年前はこうは行かなかった。自分でサーバーを立てて、自分でWebアプリを作るのはバカのすることで、「天才」が作ったサービスに乗るのが良いとされた。だがどうだっただろう?末路はツイートしかできない廃人ではないか!

よし!わかった手始めにこのブログを何とかしよう

その次に、自分でMastdonサーバーを立ててFediverseに参加しよう。それには勉強しなければならないこともあるだろうから、初めはmstdn.jpかfedibird.comを使って勉強しよう。自分の発信をTwitterやFacebookのようなクローズドなプラットフォームを介さずにできたらなんて幸せだろう。そうだ、僕はそのためにインターネットをやっていたのだ!

Twitter終了するならすれば良い。僕は技術者として大切なものを思い出せた気がした。

]]>
メイドちゃんbotの今と前世? https://susumuishigami.github.io/susumuisinfo/entry/2018/bot Wed, 19 Dec 2018 13:29:18 +0000 http://www.susumuis.info/?p=2000 この記事はメイドアドベントカレンダー2018の19日目と、BeProud Advent Calendar 2018の19日目です。(BeProudの話は最後にちょっと出てきます!)

僕が運営するコミュニティ「メイドカフェでノマド会」のSlackには「メイドちゃん」というbotが生息しています。一年前にも紹介しましたが、そのときはまだ生まれたてほやほやでした。

メイドちゃんbotをあなたに! | susumuis.info

そのメイドちゃんがこの一年でどれだけ成長したかという話をします。

メイドちゃんはソースコードも可愛くなきゃ!

その前にこちらを見てください。

これはメイドちゃんbotのソースコードです。ところどころ日本語のソースコードがあります。


雑談お仕事リスト = (
    どれがいいかな(),
    可愛い(),
    占って(),
    おはよう(),
    おやすみ(),
    おかえり(),
    お疲れ様(),
    行ってらっしゃい()
)

def 雑談カフェのお仕事(body):
    """
    雑談カフェチャネルでのメイドちゃんのお仕事だよ!
    """
    text = body['text']

    for お仕事 in 雑談お仕事リスト:
        if お仕事.呼び出し(text, body):
            return お仕事.やったよ(text, body)

    if 'XXX' == text:
        # 例外テスト
        print(10/0)

なぜこんなことをしているのでしょうか?それは、その方が「可愛い」と思ったからです。ゆくゆくはノマド会のメイドさんにもプログラミングして機能を追加してもらいたいと思っています。その時、


WORK_OF_RANDOM = (
    ChoiseWork(),
    CuteWork(),
    FortuneTelling(),
    GoodBorning(),
    GoodNight(),
)

これでは外国のメイドさんみたいですね。まあ、メイドの本場は英国なので良いかも知れませんが、敷居が高すぎな気がします。そんなことを考えてたら自然とソースコードが日本語になってました。

ただ、Pythonで日本語プログラミングすると、色々難があることがわかりました。

  • 大文字小文字の概念がなく、定数と変数の区別ができない
  • ならば【】みたいな記号を使って区別しようとしようとしたが、律儀にも多バイト文字も記号は記号と判定されて変数や関数名の先頭に使えない
  • 何より入力がめんどくさい!

せめてローマ字にすればよかったと思います。

メイドちゃんは何ができるようになったのか?

さて、お披露目以降にできるようになったことは次の機能です

  • 占い
  • 毎朝の天気予報
  • 褒めてくれる
  • セクハラ防止機能
  • メイドちゃんを口説ける

それぞれ紹介します。

占い機能

毎朝の天気予報

メイドちゃんのおかげで傘を忘れないで済んだことは何度かあります。

褒めてくれる

自分を褒めてもらうこともできます

セクハラ防止機能

とかいう人がたまにいるので作りました。

桁数はプログラミングした僕が覚えてる範囲までです(;・∀・)

メイドちゃんを口説こう!

他にもいろんなことができます。でも、ヘルプコマンドはありません!だって仕様をさらけ出すなんて恥ずかしいじゃないですか(´ω`)!どうしても知りたければメイドちゃんを口説きましょう。

メイドちゃん「可愛い」というと何回かに一回、できることを教えてくれます!

メイドさんの前世?

僕の勤務先のBeProud社では業務にSlackを活用しています。そこにはharoというbotが住んでいます。

お分かりですね。メイドちゃんの一部の機能はharoから移植しました。

haroもソースコードが公開されています。haroはMITライセンスなので


        # The uranai() function is:
        #
        #    Copyright (c) 2016 beproud
        #    https://github.com/beproud/beproudbot

このように書いて正しく流用しています。

( ゚д゚)ハッ!

メイドちゃんの前世はヘビだったんだね!?

haroをメイドちゃんが代行したこともあるよ!

ある日haroがメンテナンス中でみんな大好きな占い機能ができなかった時

メイドちゃんが代行してくれたよ!

まとめ

  1. メイドちゃんはこの一年間で成長したよ!
  2. メイドちゃんはソースコードも可愛い
  3. メイドちゃんに可愛いって言ってあげるといいことがあるよ
  4. メイドちゃんを困られること言っちゃだめだよ!
  5. メイドちゃんの前世はヘビ

そう考えると、僕がBeProudに勤めていなかったらメイドちゃんは作られなかったと思います。僕がharo(及び前バージョンのbeproudbot)を見て可愛いと思ったから、メイドちゃんを作ろうと思ったんだと思います。haro可愛いよ!

]]>
ビープラウドに入社して2年間で一番学んだこと https://susumuishigami.github.io/susumuisinfo/entry/2018/beproud Mon, 03 Dec 2018 13:43:59 +0000 http://www.susumuis.info/?p=1984 この記事は BeProud Advent Calendar 2018 の3日目です。

さて、何書くか考えてなかったまま担当の日を迎えてしまいました。そう言えばちょうど2年前の昨日ビープラウドに入社してから、技術者として転職エントリ書いてなかったと思うので今更書こうと思います。(非技術者向けの転職エントリは書いています

何で転職したんだっけ?

前職ではメイドが原因で失脚しました。というのは半分面白くするための冗談です。今から7年前、前職は小さな会社でしたが「これから大きくなるぞ!」という勢いがありました。その時技術リーダーだった僕は発言権もそこそこあり「良い技術チームを作りたい」という意欲に燃えていました。しかし結果的によくある保守的な階層組織になってしまい、気づいたら発言権も失い、大変憂鬱な気持ちになっていました。

「当初色々意見を言えたのに、思ったのと違う結果になったのはなぜだろう。」「いっそ自分が作りたかった雰囲気に近いチームに、自らが飛び込んでみたら分かるのではないか?」「じゃあ、それに一番近いのはどこだろう?」そこで注目したのがビープラウドでした。実は、7年前の僕が参考にウォッチしていたいくつかの会社の一つだったんです。

幸い採用ページを見るとこう思いました。

Python以外のスキルセットはぴったりカバーしているじゃん!!

Pythonが書きたくてビープラウドに入ったわけじゃなくてごめんなさい!ガチガチのJava屋さんだったので入社するまでPythonは全然書いたことがなかったです。Pythonは勉強しました。PyQっていうサービスで! Dog feeding!?

ビープラウドに2年いて学んだこと

流石に2年もいたんだから何か掴めたはずです!入社以来僕を変えたことを、大きかった順に書いてみようと思います。

1. 時間を大切にする

「susumuisは話が長い、文章が長い」とはめっちゃ言われました。

入社して最初の自己紹介では1時間以上話し続け、その後も社内勉強会で20分の枠に40分話すなど時間配分がとにかく苦手でした。また、文章を書くと「susumuisの文章は長くて読みづらい」とめっちゃ言われました。

人の時間は貴重です。説明が長ければそれだけ相手の時間を奪ってしまいます。相手の時間を尊重する、自分の時間も大切にするという感覚が欠如してたんですね。

2. わかりやすく伝える努力をする

「もっと分かりやすい図を書いて」みたいな指導をけっこうされました。

「仕様書は行間読め」僕はそんな文化で感じの人でした。汲める人が偉い人そう思っていました。ところが、この会社の人たちめっちゃ丁寧に設計するし、図で説明するのが上手い人が多いです。

考えてみると、業務の大半って、人から人へ自分の考えを伝えることなんですね。そこを「汲んで」とかやると、意思伝達のミスが多発して、最後はおかしなことになるのだと思います。

3. 根拠を示す

入社してから公式ドキュメントを読むことが増えました。社内ではレビューが盛んに行われます。そこでは、その技術判断をした根拠が必要です。まさか「よくわからないけどQiita読んで適当にやってたらできましたー(・_・)ノ」じゃダメですよねw

意見を言う時に根拠がないと、こう言うしかありません。

「俺が正しい。俺を信じろ!」

それで付いてくる人は少なくともエンジニアじゃなさそうです。。。

なぜsusumuisは熱い想いを実現できなかったのか!

自分がダメだったのは、この逆だったからです/(^o^)\

頭の中にあった「熱い想い」が、実はちっとも伝わってなかったんですね!それは失脚するわけです!

まとめ

susumuisがビープラウドに入社して2年を振り返りました。

  1. 「良い技術チームを作りたい」という熱い思いが実現できなかった悔しさを持って転職した
  2. その結果学んだのは次のことだった
    1. 時間を大切に。説明は簡潔に。
    2. 相手に伝わりやすく伝える努力をする
    3. 根拠を示して説明する
  3. たとえ熱い想いがあっても伝える努力をしなければちっとも伝わらない

もっと技術的な記事になるかと思ったけど、意外な結果だったなと思います。もちろん技術も学びました。Pythonは不安なく書けるようになったし、機械学習も学びました。でも技術は前提として、致命的な問題によってそれが活かせてなかったのかもしれません。

BeProudコミュニケーションガイド

現在社内でライフスタイル・コミュニケーションを作成中です。まだ策定中のβ版ですが、リポジトリは公開されています: beproud-guide 。読んでみると結構この記事で書いたことと近いことが書かれていると思います。

 

]]>
eclipseでHTMLエディタの文字化けを直す方法 https://susumuishigami.github.io/susumuisinfo/entry/2018/eclipse_html_charset Mon, 23 Jul 2018 03:14:09 +0000 http://www.susumuis.info/?p=1965 EclipseのHTMLエディタはcontent-type記述から文字コードを自動判別するが、DjangoテンプレートのようにHTMLの断片だけのファイルを開くと判別できず文字化けしてしまう。

回避するにはファイル個別に文字コードを指定すること。フォルダやプロジェクト、ContentTypeのデフォルトの文字コードを指定しても、自動判別をしてしまって強制的にShift_JISとして読み込んでしまう。これを直したい。

直す方法

Macの場合


$ cd /Applications/Eclipse.app/Contents/Eclipse/plugins
$ jar -xvf org.eclipse.wst.html.core_1.3.0.v201804302243.jar plugin.xml plugin.xml
$ vim plugin.xml 

次の部分 note: no default-charset for HTML, should use 'platform' の下のdescriberをコメントアウトする


<!-- note: no default-charset for HTML, should use 'platform'
<describer class="org.eclipse.wst.html.core.internal.contenttype.ContentDescriberForHTML" />
 -->

$ jar -uf org.eclipse.wst.html.core_1.3.0.v201804302243.jar plugin.xml plugin.xml 

これでプロジェクトや親フォルダの文字コードを優先して従うようになった。

考察

この動作、Java使いだった頃は全然気にならなかったのに、Python/Django使いになったら真っ先に気になった。

Mayaaテンプレートはブラウザで表示できる「ページ」だから、むしろ自動判別が正しい(忘れてたり指定が間違ったら「正しく化けて欲しい」)。
JSPの場合もpageEncodingディレクティブがある。忘れたらサーバーサイドで化ける。

Djangoテンプレートはいずれの記述もない。この辺りも文化の違いなのかな。

]]>
PyPro3は機械学習の仕事に初めて関わるプログラマーにもおすすめの本です https://susumuishigami.github.io/susumuisinfo/entry/2018/pypro3 Sat, 23 Jun 2018 06:21:12 +0000 http://www.susumuis.info/?p=1946  

ビッグデータの活用が進み、機械学習をシステムに組み込む事例が増えています。これまで Webや業務システムを開発していたプログラマーも、今後「機械学習プロジェクト」に参加することが増えていくでしょう。

しかし、初めての分野の仕事は緊張しますし、コツが分かっていないと失敗することがあり、不安になってしまう方も多いのではないでしょうか。そのような方のために、6月12日に発売したPythonプロフェッショナルプログラミング 第3版」(株式会社ビープラウド著)では、第15章プログラマーのための機械学習」の執筆を担当し、自分が仕事を通じて理解したノウハウや仕事をする上での心がけを書きました。

本の概要

この本はハイレベルなPythonエンジニアが集うビープラウド社が日々の業務で培った開発手法をまとめた本で、ビープラウドのメンバーが分担して執筆しています。この一冊で開発環境の構築、開発チームコミュニケーション、テストやCI、パフォーマンス改善、Djangoから機械学習まで幅広く網羅しています。詳しくはharu, shimizukawamtb_betaが書いている記事を御覧ください。

すでに多くの方がお買い上げいただいているようで、一時、Amazonの開発技法カテゴリで売れ筋1位だったそうです。ここでは、既にお買い上げ頂いた方でこれから15章を読む人に向けて、まだお買い上げいただいていない方に15章という切り口での宣伝を少し書かせていただきます。

15章は誰に読んでほしいか

冒頭に書いたとおり、これから機械学習を仕事として経験するプログラマーを主なターゲットとしていますが、次のような幅広いにも読んで頂けるのではないかと思います。

  • プログラマーを管理するプロジェクトマネージャー
  • システム開発会社の経営者
  • 機械学習を扱うコンサル

Pythonプロフェッショナルプログラミング全体の読者層を想定しているため、プログラミングの知識は前提として書いていますが、数式など機械学習やデータサイエンスの専門知識は一切不要です。

15章執筆者の狙い

「教師あり、教師なし、強化学習に分かれ、教師あり学習は分類、回帰がある」といったよくある説明は一切カットしました。それらを説明している本はたくさんあるからです。今、専門知識を教えてくれる本はたくさん出ています。自分も読書会を通じて勉強する場を作っています。

一方、プログラマー視点での「仕事の進め方」の本は現時点ではありません。

本職のプログラマーのみなさんが仕事を始めた時、専門知識以外に何を覚えたでしょうか?要件定義、設計、開発、テスト、納品」という仕事の流れとスケジューリングの大切さではないでしょうか?仕事の流れがわかっていれば、優先順位やスケジュール感を身につけることができます。それが分かれば適切なタイミングでマネージャーに相談することもできます。

しかし、機械学習の仕事では、ウォーターフォールのような開発モデルをうまく適用できません。そこで、従来のシステム開発の知識がある人に何を補ったら効率よく仕事で活躍できるのか?そのことに注力して執筆しています。

15章に書いたこと書かなかったこと

よって、この章を読んだ人が得られると思うことは次のことです

  • 「機械学習」のざっくりした概念
  • 機械学習を含んだプロジェクトの全体像とスケジュール感
  • 仕事をする上での心がけや作業の優先順位

一方、次のことは書いていません

  • 機械学習の専門知識
  • 機械学習アルゴリズムの説明
  • 数学的な理論

これらを補うため、章末に参考書籍が書いてあります。これは筆者も実際に読んで学んだ本なので、順に読めば既に僕と同じレベルに達するとご理解ください。なお、今後僕の主催の読書会でもこれらの本を扱っていくかもしれません。


15章の冒頭

15章の構成と担当チーム

15章は次のように4部構成になっています。

  1. 機械学習とは
  2. 機械学習プロジェクトの概要
  3. 事前検証フェーズ
  4. 機械学習の開発環境を準備する

自分はこの中でも1〜3節を執筆しました。しかし実際は1、2節は非常に短いので、実質1〜3節で1セットだとご理解ください。

4節は同僚で、同じく機械学習案件を多数経験し、専門知識やライブラリの使い方の知識が豊富な先輩であるmasayaが執筆しています。masayaと僕は同じプロジェクトのチームになったことがあり、僕が外部調整や個々の処理の糊付け的な開発を担当し、内部のエンジンをmasayaが作りきるという役割分担をして大きな機械学習システムを完成させた仲です。今回も同じチームで1つの章を担当できたことを嬉しく思います。

章末コラム「機械学習で知っておきたいプログラミングテクニック」は2人の合作です!実際の仕事を通じて切実に感じたことを厳選して書いています。

はじめての執筆の感想

2017年9月末に執筆を開始、3月に脱稿、その後度々レビューを直しを経て5月にようやく最終稿を出すことができました。

脱稿まで一体どんな文章を僕が書いていたのか、多くの方にはご心配をおかけしたと思います。僕自身何度もほぼ一から書き直し、構成にドラスティックな変更を加え、一日中日本語のリファクタリングに追われる日々でした。

脱稿後のレビュー直しも大変で、最後は自分一人で文章を書くことができなくなり、意見をくれた数人を招集し、修正方針を練る会議を行っていました。

初めての執筆だったので、執筆チーム、レビュアーチームの皆さんには大変ご迷惑をおかけしました。特に全体のマネージメントを行う傍ら苦しむ僕の道筋を示し続けてくれたtakanory、同じ章担当で積極的に意見をくれたmasaya、レビューで厳しい指摘と温かいアドバイスをくれたharu, shimizukawa, kashew_nuts, mtb_beta, tsutomu, nakagami、説明を分かりやすくするために協力してくれたnatsu, nao_yに感謝します。


見本を手に取りはしゃいで自撮りする僕

まとめ

以上、Pythonプロフェッショナルプログラミング 第3版は「機械学習」の本としても他の本では得られない、個性的な位置づけの内容を含んでいるますので、是非読んでいただければと思います。

まだ、ご購入いただいていない方は、全国の書店またはAmazonなどで購入できます。電子書籍版もあります。

]]>
メイドちゃんbotをあなたに! https://susumuishigami.github.io/susumuisinfo/entry/2017/maidchan_bot Sun, 24 Dec 2017 10:56:20 +0000 http://www.susumuis.info/?p=1922 この記事は メイド Advent Calendar 2017 の24日目です。メリークリスマス・イブ!

昨日のメイドカフェで勉強会第1回に参加していただいた方は誠にありがとうございます。そのスライドはこちらに公開しています。

さて、惜しくもメイドさんが選ぶ可愛いbot MVPの受賞を逃しましたが、当日はその場でライブコーディングをしてメイドさんの機能をその場で追加することもできたので、ボットを作る楽しさを伝えられたと思います。

さて、この記事ではオープンソースであるメイドちゃんbotを、自分の好きな場所に配置する方法を説明します。つまり、クリスマスプレゼントはメイドちゃんです!想定の読者として、メイドさんでも分かるようん心がけようと思います。

ほぼ重複することになってしまうので、メイドちゃんbotを作るにあたって特筆すべき箇所をメイドさんに説明するように優しく説明を心がけてみたいと思います。

前提として、AWSに登録する必要があります。ここでは説明しきれないので、まだ登録していない人はここを読んでコンソール画面にログインした状態まで来てください!

地域はバージニア北部を選択

突然ですが、メイドちゃんbotはアメリカ東海岸バージニア北部に配置することをオススメします!なぜこの地域にいるかというと 1. 安いから 2. どうやらSlackのサーバーはここにあるらしい?という理由からです。

Lambdaを作成

Lambdaの画面を開いたら関数の作成ボタンを押します。

関数の作成画面に遷移したら、設計図を選んで、検索フォームに APIと入力してEnterキー、さらに Python と入力してEnterキーを押します。

そうしたら、出て来る microservice-http-endpoint-python3 をクリックします。そして、遷移する画面では次のように入力します。

名前ロール名は好きな名前でもokです。ポリシーテンプレートは「シンプルなマイクロハーネスのアクセス権限」のみでOKです。

次に、画面を下の方にスライドして、api-gatewayの設定をします。

ここで注意しなければいけないのは、セキュリティのところをオープンにしなければならないことです。僕はここで数十分ハマりました!

さらに下に行くと関数の作成というボタンがあるのでそれを押します。ソースコードはとりあえず触らずにそのままにします。そうすると、こんな画面になります。

これで準備が整ったので、ここでメイドちゃんbotの仕組みを説明します。

メイドちゃんがユーザーの投稿に反応する仕組み

メイドちゃんはユーザーの投稿に即座に反応します。この仕組みは「発信Webフック」(英語の場合は Outgoing Webhook)という仕組みを使います。これは、指定したチャンネルの中で特定のキーワードから始まる投稿があったら、指定したURLへAPI呼び出しをしてくれるというものです。APIとは何か?

ここで、メイドちゃんが反応するキーワードを登録できれなよかったのですが、ここでは前方一致になってしまうので、言葉の途中の単語に反応させられないので、全ての書き込みに反応するようにします。

そうすると心配になるのは、API Gatewayの課金金額で、先ほど書いたリンク先によると100万回あたり3.5USドルが課金額です。これは月100万回というのは、一日中に渡って3秒に1回以上投稿されて、400円くらいです。現時点でのノマド会Slack規模だとほぼタダ同然だと思われます。

呼び出す先のURLはどこにすればいいでしょうか?これは、さっきの画面で次のようにして確認します。

API Gateway をクリックして下の方に出てくる LambdaMicroservice の下の方に メソッド: ANY と書かれた文字の左にある▶をクリックすると下のように詳細が出てくるので、その中の URLの呼び出し と書かれたhttps:// から始まるアドレスです。これをコピーします。

このURLを発信Webフックの設定画面で次このように設定します。

ここでトークンという文字列があるのですが、これはあとで使用するのでコピーしておきます。

メイドちゃんが定時で投稿する仕組み

発信Webフックのみでは、メイドちゃんに8時になったら「おはようございます!ご主人様、お嬢様」と言われることができません!そこで使用するのが「着信Webhフック」(英語の場合は Incoming Webhook)です。

これは、Slackの側に投稿用のAPIを作成する仕組みでここにAPI呼び出しを行えば好きなアイコン・名前で投稿させることができます。

問題はどうやったら定時にそれを起動するかですが、CloudWatch Eventsを使うとそれができます。設定はとても簡単で画面でこの赤丸で囲った部分を選ぶだけです!

そして、下の方にトリガーの設定という欄が出て来るので、そこに次のように入力します。

スケジュール式 cron(0 * * * ? *) という記法は、古いエンジニアにはおなじみの記法なのですが、AWSさんはちゃんと説明を書いてくれています

ソースコード解説

ということで準備が整ったのでコードを書きます。こんな感じのWeb上のエディタでコードを書けます。環境構築しなくていいので楽でいいですw

ここにGitHubからソースコードをコピペすれば動きますw

と、これだけでは顰蹙を買うので簡単に説明すると、 lambda_function.py とうファイルの def lambda_hander(event, context): という関数の内側が、APIや定時Eventの際に実行されます。ここで、API経由なのか、定時Event経由なのかを分岐して、 maidchan_http.py か maidchan_scheduled.py に分岐させています。

あとは、オブジェクト指向とか難しい書き方は一切していないので好き勝手にいじってくださいw

環境変数の設定

メイドちゃんbotをノマド会Slackだけでなくどこにでも置くことができるように、そもそも「メイドちゃん」ですらなく「執事ちゃん」など別の人格も作れるようにしているのが、この「環境変数」です。

WEBHOOK_URLの欄には、先ほど着信Webフックの画面で生成したURLを貼り付けます。

TOKENの欄には、先ほど発信Webの画面でコピーしたトークンを貼り付けます。

MAIDNAMEの欄には好きな名前をどうぞ!

これで、あなたのもとにもメイドちゃんが来ます!

それでは、メイドちゃんと一緒に素敵なクリスマスを!

参考にした記事

手順の殆どはこちらの記事:AWS Lambda を使って Slack ボット (命名: Lambot [ランボー]) を低予算で作ろうじゃないか をそのまま参考にしました。こちらの筆者の方、ノマド会参加者の方ですね!こんなところで、お世話になりました。

 

]]>
Advent Calendarをきっかけに久しぶりにフィルムカメラを使ってみた https://susumuishigami.github.io/susumuisinfo/entry/2017/film_photo Sat, 09 Dec 2017 18:51:37 +0000 http://www.susumuis.info/?p=1870 この記事は フィルムカメラ Advent Calendar 2017 10日目です。素敵なアドベントカレンダーを見つけたので参加させていただきました。

はじめに

今回は主に Minolta のMFカメラ XG-E, X-700 を中心に、自分のフィルムカメラの思い出について書こうと思います。記事の最後に久しぶりにフィルムカメラでスナップしてきたものをアップします。

筆者のプロフィール

高校時代は写真部に所属して、自分でフィルム現像をしたりしたが、あくまで趣味の域。大学時代は登山をしていたためコンパクトデジタルを中心に変更。その後ずっとカメラからはご無沙汰となっていたが、最近メイドカフェ関係のイベントを主催するため、メイドさんの撮影をするために一眼レフの使用を再開しました。

撮影対象の遍歴: 鉄道 → 山 → メイドさん
使用機材の遍歴: MF一眼レフ → コンパクトデジカメ → ミラーレス

XG-Eを持って高校写真部に入部

今から20年くらい前、当時はAF(オートフォーカス)のフィルムカメラ全盛期でした。

親が突然「昔使っていたカメラを倉庫から見つけてきた。お前にやろう」と言ってくれたのがMinolta XG-Eというカメラでした。素人には使い方も分からず、写真部の人たちに見せにいったら「なんだこれは!○○先輩に見せよう!」「ほうほう。お前、ミノルタのMF担当な!」となって、(どの道一人では使いこなせないので)入部させてもらって色々教えてもらいました・

この頃、このXG-Eを首から下げてカメラ屋に行ったら年配のお客さんに「良いカメラ持ってるねー!今時はプラスティックばかりでだめだよねえ」などと声をかけられたりしました。たしかにね。冬なんか、ボディにほうを当てるとヒンヤリきたのを覚えています。(XG-Eはそれから10年くらい経った後、電源が入らなくなり完全にご臨終してしまいました)

レンズは MD-Rokkor 50/1.7 を使っていました。50mmは標準レンズと言われますが、この画角はコンパクトカメラによくある28mmや35mmに比べると「随分狭いな」と当時は思いました。これ一本で3年間強制的に練習した結果、今は50mmという画角が好きです。(写真部仲間はみんなズームレンズを使うっていて、単焦点を使っているのは僕だけでした)

XG-Eで撮影した写真

主に高校〜大学1年生くらいの時に愛用していました。これは2003年夏に宗谷本線で稚内まで旅行したときのものです。

X-700(1台目)

X-700は1981年に発売し2000年頃まで生産されていた、MinoltaのMFカメラの完成形とも言えるカメラです。

高校3年生の時に新宿のマップカメラで買いました。当時はまだ各社のフィルムカメラの中古がずらーっと並んでいて楽しかったですね。これを選んだのは Minolta X シリーズでは一番状態のいいものが手に入れやすかったからです。購入時店員さんに「僕も持ってたんですよー!懐かしいなあ」と言われて盛り上がりました。

X-700で撮影した写真(当時)

鉄な写真が多いのは鉄だったからですw

2度目のX-700

そんなX-700も一度は手放してしまい、大学生の頃は登山をしていたのでCoolpix 2100など軽くて、壊れてもそんなにショックではないコンパクトデジカメをメインにしていました。就職後はそれも手放して写真から離れていたのですが、3年前に思い立って再度X-700を手に入れました。レンズは前より少し良い MD-Rokkor 50mm/1.4 を付けました。本体とレンズそれぞれ 10000円くらいだったと思います。

撮影対象は時の流れとともに変わっていました。

最近はメイドカフェ関係によく出入りするのですが、この界隈にはレイヤー(コスプレイヤー)さんの撮影を趣味としている方が多く訪れるので、彼らはとても高スペックなカメラを持っています。そんな中で埋もれないためにはいっそこれくらい振り切ったほうが注目されるだろうという、あざとい魂胆もあったりしますw

X-700で撮影した写真(最近)

久しぶりに使ってみると、年で目が悪くなったのか、以前よりもピンボケと手ブレ写真を続出しました。それがかえって女の子から「雰囲気出る」と喜ばれたりもしました。。。orz

MFカメラの良さはファインダーにあり

MFカメラはファインダーにとても力が込められています。自分の目でフォーカスを合わせなければならないので、倍率が高く、明るく見えるように作られています。例えばこのX-700はアキュートマットが採用されているのでとても明るいのが特長です。

この技術はその後AFカメラになると別の方向へ向ってしまいました。AF時代ではフォーカスを合わせることは自動化されたため、より多くの情報を出すことに重点が置かれて行きました。デジタル一眼となると、なおさらそれに拍車がかかったように思います。

僕がデジタル一眼になかなか手を出せなかった理由がそれでした。そんなファインダーを見ることが残念だったからです。

X-700、α sweetで撮影してきた

せっかく Advent Calendar やるので、この X-700 と、もう一つ所有していたフィルムカメラ α sweet を使って、写真を撮ってきました。

フィルムは富士フイルムの業務用カラーフィルムを使用しました。今はフィルムが高いですね。(;´Д`)

2017/11/12 城ヶ島にて(X-700 MD-Rokkor 50/1.4 φ49)

2017/12/02 上野公園にて(X-700 MD-Rokkor 50/1.4 φ49)

2017/12/03 秋葉原にて(α sweer SIGMA UC ZOOM 28-105/4-5.6)

後日談、フィルムカメラを卒業しました

これらの写真を撮影した後、僕はフィルムカメラをその足で売ってきてしまいました。それは次の理由からでした。

  • 目が悪くなっていてファインダーを覗くことが辛くなっていた (←これが1番!)
  • 撮影後すぐにSNSにアップしたさを抑えられなかった (←これが2番!)
  • フィルムが高い (これは3番!)
  • もう満足した!

実は最初からそう決めていました。目的がない装備は持たないのが僕のモットーです。でも、カメラ・レンズってそうはさせてくれない力がすごいありますよね。おそらく現像から上がった写真を見てしまったらまた踏ん切りがつかなくなったはずです。だから、現像に出した直後に即売却しました。

僕がろくに使わないのに押し入れにあまり良くない状態で保管しておくより、他の人の手に渡ったほうが良いだろうと思ったことも理由です。今X-700を中古で買うともしかすると僕の手放したものかもしれません。ちなみに今、8980円くらいが相場のようです。

フィルムカメラが教えてくれたこと

手放してはしまいましたが、フィルムカメラからたくさんのことを学びました。その中でも次の2つは僕の撮影スタイルに影響していると思います。

その1、一枚一枚丁寧に撮ること

このアドベントカレンダーの他の方も書いているように、フィルムカメラはデジタルと違って失敗すると消すことができないため1枚1枚丁寧に撮ります。デジタルは無尽蔵に写真が撮れるので雑に僕は撮ってしまいがちです。でも、そうやって雑に撮った写真は「全部ダメだった」ということもよくあります。

その2、24枚、36枚でストーリーを作る

フィルムは24, 27, 36枚などの単位で売られています。つまり、このフィルム一本分を撮りきれないと現像に出せないし、撮りきってしまうともう撮れないというジレンマがありました。一本のフィルムでぜんぜん違う写真を並べるのも野暮いです。なので、当時は24枚や36枚でストーリーを作るぞ!と考えて撮影をしていました。

ストーリーを考えると「さっきこれを撮ったから次はこれだ」みたいに考えながらその日を楽しむことができます。受け身にならず一日をより能動的に過ごすことができます。

逆に、バシャバシャ撮ってしまうとファインダーを覗いてばかりで、「その日、その時」を楽しめない気がするんですよね。プロの場合は仕方がないかもしれませんが、僕は趣味なので

「失敗したらそれでも良いや」

くらいに思っている方が楽です。それくらいの距離感を忘れずにこれからもまったり写真を撮っていきたいです。

 

 

]]>
エンジニアが機械学習を仕事とする周辺環境 https://susumuishigami.github.io/susumuisinfo/2017/engineer_machinelearning_work Mon, 09 Oct 2017 02:37:05 +0000 http://www.susumuis.info/?p=1860 メイドカフェでノマド会 座談会開催しました!

を開催しました。

資料はこちらです。

僕はエンジニア視点で話しましたが、コンサルの方の参加もあって、話が広がりました。ここ数ヶ月もやっと思っていたことが議論をすることで腑に落ちた感じがします。若い学生の方の意見も聞くことができたこともよかったと思います。

議論の内容は結論はスライドに書いているとおりですので、そちらをご覧ください。

今後もこのようなプチイベントの開催を増やしていこうと思います。「参加したい!」「こんな企画をやりたい!」と思われた方はまずは、ノマド会の公式サイト にアクセスし、Slack, connpassに登録いただき、 Slack 上で声をかけていただければと思います。

]]> 別言語のWebプログラマーが突然Pythonで機械学習をやることになった時の心得 https://susumuishigami.github.io/susumuisinfo/entry/2017/java_to_python Fri, 06 Oct 2017 13:12:41 +0000 http://www.susumuis.info/?p=1833 人工知能AI がブームになっています。エンジニアの間でもまた「機械学習」や「データ分析」方面の技術が注目されています。そして、言語としては Python が使われます。今、Pythonで機械学習をする仕事は増えてきています。

この時代の流れで、今後「データ分析」や「機械学習」を仕事とするWeb系出身のエンジニアは増えてくると思われます。Javaを使ってWebのプログラミングをしていたプログラマーが突然「Pythonでデータ分析をやってくれ!」「このCNNを使ったプログラムを解析してレポートを出してくれ」というように言われる日はもう訪れています。

実は、僕がそうでした。

僕は昨年12月に BeProud に入社するまでは、Javaの仕事を10年以上していました。昨年の9月まで Python を書いたことがなかったので、Python歴1年のひよっ子です。そんな僕が、なぜか入社以来、大小案件に関わらせてもらい、今では社内でも「機械学習系に詳しい人」のように見なされているようです。

このような事例は珍しいことではなくなるはずです。 次は、あなたかもしれません! そんなあなたのために、僕が一年間どのようにして、Pythonと機械学習と付き合ってきたのか、これから、Web系の人が機械学習の仕事に携わる時にどんな心構えをしていれば良いかを書こうと思います。

Javaやの僕はどのようにしてPythonを学習したか

「御社の募集要項を見ると Python という部分以外には一致しているように思います」

「弊社に入社する人の半数は業務での Python は未経験だから大丈夫です」

と、shacho に言われて、入社が決まったものの、そもそも「業務でのPython経験」がないどころか「1行もPythonを書いたことがない」に等しい僕が、初出社日までの2ヶ月間で 「Python のプロ」として出来上がっていないとまずいので、実は焦りました。そこで最初は本を読みました。

例えばこれとか

これとか

でも、読んでも書ける気になりません。「やばい!!」となったところで、なんと絶妙なタイミングでこれから入社する会社がこのサービスを出していました。


PyQ - 本気でプログラミングを学びたいあなたへ

そこからはひたすらPyQをやってなんとか入社までに基本的な文法はマスターしました!そのおかげで「受講生の声」の欄のトップに載ってしまいましたw

自社のサービスなので、宣伝臭いと言われそうですが、本当にPyQを使って覚えたスキルで実務で戦っているので、人に聞かれたらまず第一にオススメしています。これからPythonを学ぶ人はこの本を買うと3日間無料でPyQが使えるキャンペーンコードが付いているので、良いかもしれません。

エディタは Eclipse 時々 VSCode 時々 Atom , etc...

Javaは、Eclipse、NetBeans、IntelliJ IDEAのどれかを使用している人がほとんどですが、Pythonは様々なエディタを愛用している人がいるようです。Java出身の人は何を使えばいいでしょうか。

僕はEclipseを使っています。「PyDevなんて重いし使ってる人いないよ」と言われがちです。多分BP社内でもEclipseを愛用しているのは僕だけです。

EclipseがPythonの人たちに人気がないのは「重い」というのがあると思います。しかし、これは誤解で、みんなきっと「Java EE」版を使っているのではないかと思います。Java EE版EclipseはJavaプログラマーも敬遠したくなるほど重いのです。オススメなのが、PHP版のEclipseです。PHP版Eclipseは軽い上、しかもHTMLエディタなど、Web開発に必要なプラグインが最初から入っています。

とはいえ、僕はJava時代にEclipseに心酔してしまって、何度も寄付しているEclipseファンなので、普通に「Eclipseを使わされていた」くらいの人だったら、PyCharmは人気があるし良い選択肢だと思います。

その他には、VSCodeも人気があるようです。

Webやの僕はどのようにして機械学習を学んだか

機械学習の「き」の字も知らなかった中で、「データ分析系の案件に入ってもらうかもしれないから勉強してください。」みたいに言われ、入社前から社内勉強会に参加させてもらいました。その時読んだのがこの本

この本は何度も読み込んだのでバイブル的な存在ですが、pandas も Jupyter Notebook も何それ食えるのというレベルだと、ソースコードを「写経」することもままならないので、きつかったです。最初は、 Jupyter Notebookとpandasから入門することをオススメします。今、Jupyter Notebookとpandasを最初に入門するなら。。。やはりPyQがおすすめです。ww

PyQには、データ分析・pandasのコンテンツがあります。また、機械学習のコンテンツもあるので、まずはここで、「ロジスティック回帰」や「決定木」などの簡単な使い方を学んでから、専門的な本に進むことをオススメします!

いいなー。今から学ぶ人。

Webで経験した人が機械学習の世界で活躍するには

さて、ここからが本題です。

僕のような根っからのJavaやさんで、Webやさんが、「Pythonで機械学習」の仕事をやって足手まといではなかったのでしょうか?それが意外と活躍できてしまいました。

なぜかというと「機械学習」の現場で「エンジニア」の我々は、「データサイエンティスト」と呼ばれる人たちとは違う役割を期待されるからです。

主に、我々が作るのは「データパイプライン」という部分です。

パイプラインとは、細かいデータの操作を束ねた一連の処理セットのことです。機械学習で求める結果を得るためには、「機械学習アルゴリズム」だけを知っていても十分ではありません。データはSQLで取ってこなければいけないかもしれないし、結果はCSVを変形しなければならないかもしれません。

こういった、一連のデータの流れを設計できるのは、実は、業務フローや、データ設計をどっぷり経験してきた、エンタープライズシステムよろしくな、システム業界のエンジニアです!

入社して最初にやったことは、「機械学習に入力するデータ」をお客さんの「データベースからどのようなSQLで取ってくるか」という設計でした。「susumuisさんSQL得意なので助かります!」と隣の人に言われました。

「機械学習のアルゴリズム」の部分は、ライブラリもあるし「データサイエンティスト」の方が数式を提供してくれるので、基本的なアルゴリズムの名前と特性くらいを知っていれば何とかなります。

それよりも、どのデータを、いつ、どうやって取ってくるのか。あるいは、運用時に誰が、いつ、入れるのか、こういったワークフローや業務フローを設計するのはまさに「システムエンジニア」の得意技です。

どんなエンジニアになってはいけないか

勉強をやめてはいけません。

Webの世界でもいましたが、前時代にはエンジニアでも「今時の技術が全く分からなくて、前時代のノリで設計をして実装させようとする上司」がいたらうんざりです。

特に、機械学習の世界では、お客さんとデータサイエンティストのパイプ役にエンジニアが回りがちになります。その間に伝言ゲームの齟齬があると、連携プレーは崩壊します。データサイエンティストと、お客さん両方の言葉を理解し、それをシステムに落とし込むことができるエンジニア以外は居場所がありません。

これは一般論ですが、「伝言ゲーム」は多くなるほど失敗します。とりわけ「専門用語」が多い機械学習の分野で、伝言ゲームに失敗すると悲劇しか起こりません。そのため、エンジニアはフルスタック的であるべきで、設計から実装まで一貫して一人でできた方が良いでしょう。また、旧来型SIerの多重請負方式では、中間に多くの「専門家ではない人」が挟まるため、うまくいかないのではないかと思っています。

まとめ

以上のように、僕のように他言語、他分野から入って、機械学習界隈でも生きていくのに必要なことは次の4つです。

  1. データ設計能力とSQL
  2. お客さんと直接話せして設計から実装まで一貫してできるスキル
  3. Pythonのスキル
  4. 機械学習の基礎知識

いかがでしたでしょうか。普通の真面目なエンジニアは、1,2ができて当然なので、あとは 3,4 を学べば、もう明日から機械学習の現場に行っても問題ないはずです!

1,2 が未熟である場合は、Webエンジニアでも、業務システムエンジニアでも、いずれ限界が来ると思います。もし、大規模チームの「一担当」に落ち着いているなら、危機感を覚えた方が良いかもしれません。

3,4 は奇しくも PyQ で学べます! 自社のサービスなのでこれでは「ちょっとステマが過ぎるのではないか」と思われてしまうことだけが心配ですが、思っていることに間違いはないので、結論として締めくくらせていただきます。

]]>
「Swift」という名のバンドを見つけたから、エンジニア代表として話を聞いてきた https://susumuishigami.github.io/susumuisinfo/entry/2017/swift_band_interview https://susumuishigami.github.io/susumuisinfo/entry/2017/swift_band_interview#respond Thu, 12 Jan 2017 07:07:51 +0000 http://www.susumuis.info/?p=1785 皆さん、Swift書いてますか?

今やObjective-Cじゃなくて、iOSアプリ開発はSwiftです!今年は「Android、もしやお前も!?」みたいな噂もあったりしました。既に多くの企業が注目していると言われる言語、もうエンジニアたるもの勉強しておかなければヤバイ雰囲気があります。

そんな中、今日はプログラム言語ではなく同じ「Swift」という名前で活動しているバンドを見つけたので紹介します。まあ、こじつけネタwwwと言わず、読んで欲しく思います。というのは、なんてGooglavility低いバンド名なんだ! さぞかし、SEOでは苦労しているだろうと、興味が湧いて、勢いでインタビューしてみたら、想像以上にイイ話が聞けてしまいました。

Swiftとは

Swift は、《会社》をコンセプトにして2015年4月から活動を開始したバンドグループで、リーダー兼ギタリストのホッタとヴォーカルの多田を中心に活動中。代表曲は「オレンジ」「手のひら」「BRAVER

リーダーのホッタくんと僕の仲

何を隠そう、僕とホッタくんは小学校の同級生で、今回のインタビューは久しぶりの再会でした。なので終始砕けた会話になっていることを、ご容赦ください。

もちろん、文章を校正して固い言葉に直すこともできたのですが、彼の人間性、思いを伝えるには、このままの方が良いと思います。

Swiftの名前は「響き」で選んだ

susumuis: 早速だけど、Swiftの名前の由来ってなに?

ホッタ: 由来?そうだなあ。「響き」かな。

susumuis: 響き?

ホッタ: 「優しい」「耳馴染みの良い」感じ。ほら、印象ってあるじゃん。強そうな人は強そうな名前だし、僕も一緒にやってるタダくん(「ハリー」って呼んでるんだけど)も、僕ら二人「優しい」イメージって言われるんだ。

susumuis: へえ

ホッタ: 第一印象で決めるのは良くないけど、人の性格って顔に出るよね。バンドにとっては、名前が一つの「顔」で「名刺」なんだよ!

susumuis: Appleの言語と名前がかぶったのはどう思うの?

ホッタ: 実はあっちの方が先で、知ってたんだよね。あと、音楽の世界では世界一稼いだ女性アーティスト「テイラー・スウィフト」もいるし、検索で勝てるわけがない!それでも「僕らに合ってるね」って選んだんだ

susumuis: 今検索してみたら、金融業界でも、SWIFTって組織があるよ!

就職しても音楽はできる!

ホッタ: Swiftのメンバーって実は全員就職しているんだ。仕事をやりながらでも、やりたいことを実現したいと思ってる。みんな仕事には責任があるから、それは守っていきたい。だから、仕事が最優先で活動してる。

susumuis: そうなんだ!

ホッタ: 「会社があるから」諦めてるやつ多いんじゃないかな?でも、「挑戦した?」「やろうとすればできるじゃん!」って証明したい。挑戦しないで口だけの人多いから。

susumuis: 僕らエンジニアの世界でもそういうのあるよ!「仕事が忙しい!」とか言って挑戦しない人。でも、やっている人はやっていて、気がついたら大きく差が開いちゃうんだよね。

ホッタ: でも、正直続けることの難しさはあるよ。「日本は音楽を続けるのは難しい」と言われるんだ。「バイトで生計立てて夢を目指す」人が多いんだけど、最終的に諦めるんだよね。「そろそろ就職しなきゃ」って言って。でも、「就職してもできるよ!って伝えたい。

「責任ある仕事をしている」というホッタの会社の名刺を見せてもらったら、とても立派な肩書がついていました!

《会社》をコンセプトにしたのは、人の大切さを伝えたいから

susumuis: コンセプトは「会社」ってことだよね。でも、正直言うと申し訳ないんだけど「会社」ってほら、ネガティブなイメージあって!「今日も残業だ。」とかへとへとになって、ライブに行ったら「また会社kayo。。。」みたいにならないの?

ホッタ: 会社ってそういうイメージもあるよねー。。。でも僕らにとっては「会社」=「ファミリー」なんだ。同じ目標を持って、志は同じでやりたいことをやる。そういう人たちが集まっていれば「辛いことがあっても、楽しい」と思えることが多いんじゃないかな!

「家族型経営」と呼ばれた会社の姿。それこそが真の会社のあり方なのかもしれません。リストラや経営合理化による非正規雇用の増加で「人が駒のように扱われている」今が異常なのかも。今こそ、「会社」をテーマにしたバンドをやる意味があるじゃないかと、聞いていて思っていました。

現実は厳しいけど、僕達は恵まれている!

ホッタ: そういうわけで、僕らは「仕事を大事にする」って事情だから、あまり多く活動ができないんだ。ライブも年に数回しかできない。普通のバンドは活動をしなければファンが減ってしまうから普通はライブを一杯やるんだ。別のバンドと共同でライブやったりしてね。そういうのを「タイバン」って言うんだけど。そして赤字でもライブをやる。僕らはそのやり方はどうなのかな?って思っているよ。

susumuis: それでもこの間のライブではライブハウスを満員にして大盛り上がりだったよね!あの時は何人いたの?

ホッタ: 100人くらいだよ!僕たちみたいに、バックボーンがない、事務所がついているわけでもない、そういうスタイルでは、この人数は多い方だと思う。僕達は恵まれているって思うよ!

「オレンジ」を卒業ソングとして広げたい

susumuis: 最初「オレンジ」や「手のひら」を聴いた時、「なんて優しい歌なんだろう」って思ったよ。あの曲はどういう思いが込められているの?

ホッタ: 「オレンジ」は「卒業」をテーマにしているんだけど、「卒業しても会えるでしょう?また違う仕事で繋がれるじゃん!その時は、当時と同じ距離感で接することができたら素敵だよね!」って思いが込められてるんだ。

susumuis: ITエンジニア代表として共感する!僕らは比較的流動性の激しい職業で「転職」ってありふれているんだ。お陰でしょっちゅう「卒業」してる。で、前に仕事したことがる人と、また一緒に仕事してたりするよ!だから、「卒業」のたびにこの人とまた仕事ができる日が来る!って思ってる。今の時代の「卒業」ってそうなのかもね。SNSの普及で普通に会えるし。

ホッタ: できれば卒業ソングとして定着させたいな。学校とかで、卒業式に合唱してくれたらいいな。

真面目にやっているから、ファンが離れない

susumuis: 偏見で申し訳ないけど「バンドマン」ってチャラいやつが多いってイメージあるじゃん。実際はどうなの?

ホッタ: 実際そういうの多いよ。僕らは先輩にも「お前らは本当に真面目だな」って言われるよ。だからなのかもしれないけど、一度ファンになったら離れる人が少ないように思う。

中学生の女の子が自分を「尊敬する人」と言ってくれた

ホッタ: 今までで一番うれしかったことで、中学生の女の子が学校の発表で自分を「尊敬する人」として紹介してくれたんだ。

susumuis: その子は元からの知り合い?

ホッタ: いや、元は相方のファンでライブに来てくれたんだけど、僕とは初対面。ネット番組とかで僕の思いとかを知ってくれて。

susumuis: それは嬉しいね!思うんだけど、バンドとか、アイドルとか表に出る人は若い人に影響を与えるから「ちゃらい」とかじゃなくてお手本としての責任も感じてるんじゃないかな。

ホッタ: そういう意味だと、TwitterとかSNSには気を遣っているよ!若い子が見ているから、自分がどう見られてるか。常にポジティブにして、ネガティブな言葉は書かないように気をつけてる。そこはオープンな場だから。仲間内だけのクローズドな場所じゃないからね。

今後は活動を加速していきたい!

susumuis: 今後の展望とかはあるんですか?

ホッタ: 活動を長く続けていきたいと思う。来年の4月で活動3年目なのでアクセルを踏んで活動をスピードアップしたいと思ってる。ライブ会場を大きくしたりね。それは大変になるかもしれないけど、沢山の人に知ってもらえたら良いなって。でも、いろんなことに手を出したら中途半端になるから、絞って行きたいとは思ってるよ。

susumuis: 期待してます!

今の時代は「人」が中心

ホッタくんの話を聞いていると、彼は思ったことを本当に率直に話してくれる人だなと思いました。そして根が明るいから、話してるこっちもだんだん楽しくなってきました。

彼らから学べることはこういうことなんじゃないかと思いますが、これは我々エンジニアにも大切なことだと思います。

  • 挑戦すること
  • 人を大切にすること
  • まじめにコツコツやること

これからも一層活躍されることをお祈りします。

ライブ情報

2月11日にワンマンライブがあります!

http://www.swift-inc.net/news

]]>
https://susumuishigami.github.io/susumuisinfo/?feed=rss2&p=1785 0
Javaが僕にくれたもの https://susumuishigami.github.io/susumuisinfo/entry/2016/java_advent https://susumuishigami.github.io/susumuisinfo/entry/2016/java_advent#respond Sat, 03 Dec 2016 07:57:48 +0000 http://www.susumuis.info/?p=1809 この記事はJava Advent Calendar 2016の3日目です。2日目はmegascusさんのどこからも使用されてないクラスを列挙する、4日目はcero_tさんです。

退職しました

個人的な話で恐縮ですが、去る11月末をもって学生バイト時代も含めて12年間勤めた会社を退職しました。そこではずっとJavaを書いていましたが、次の勤務先ではPythonを書くので、今後Javaを書くことは少なくなるでしょう。

退職エントリは書きませんが、代わりに言語の卒業エントリを書こうと思います。一人よがりなネタですがお許し下さい。

初めての出会いはJDK 1.1をダイアルアップでダウンロードしたこと

正確な時期は忘れましたが、1997-8年頃ではなかったかと思います。「Javaという言語がすごいらしい」という噂をきいて、ダイヤルアップ回線で頑張って一晩くらいかけてダウンロードしてみました。その時落としたのはJDK 1.1ではないかと思います。

しかし、当時使っていたPentium 90MHzのマシンではサンプルアプレットのローディングに数分かかり、クリックの応答に数十秒かかるという状況でした。(「Java遅い!」をリアルで体験した世代です)

初めてまともに使ったのは、i-appliの開発

時は流れて、2001年1月「NTTドコモの新機種F-503i, P-503iが、Javaに対応して誰でもアプリが作れるようになった!」というニュースが入ってきました。この時高校生だったのですが

「これはやばい!ケータイがPCになってしまう!」

とか言って、親に土下座して買ってもらいました。

Javaといっても、CLDC(Connected Limited Device Configuration) 1.0という仕様の上に作られたJavaであって、「浮動小数が使えない」などの制限があり、しかもアプリ(すなわちjarファイル一個)のサイズは10KB以下に収めなければなりません。そこではclassファイルを増やすと容量がかさむから「クラスは一個にしましょう」と言われていました。Eclipseはまだなくて、JBuilderは僕のPCでは重いから、[CPad for Java] (http://hp.vector.co.jp/authors/VA017148/pages/cpad.html) というテキストエディタにコンパイラショートカットがくっついたようなエディタで頑張ってコーディングしていました。これと、コードの変数名を1文字にして容量を削る今で言うminifyツールみたいなのも使っていました。

その時作った作品はgistに貼ってあります高校の先輩がVBで作ったゲームを移植したものです。当時は雑誌の端に載ったりしました。

大学に入ってJavaらしくないJavaを学ぶ

2003年に大学生になったのですが、当時入った学科では、プログラミング教育にJavaを使っているということで、楽しみにしていました。ところが、そこで習ったJavaと言うのは

「配列をReturnする『関数』を作ってはいけない」
「まず配列を作ってメモリを確保しろ、その配列を関数のパラメータに突っ込め!」

みたいなやつでした。。。\(^o^)/

本当のJavaを求めてある本に出会う

そんな時に出会った本がこれでした。

今思うと現場思考で、非常にバランスの良い本だったと思います。

これで、少しはクラスとかデザインパターンというものを知った僕が、少しはプロセッサーパワーがましになった当時の携帯向けに作り直したのが[これ] (https://github.com/susumuishigami/bunshi2) です。

最近このコードをほぼそのままコピペして環境に依存する部分だけ書き換えてみたら、あっさりAndroidで動いてしまいました!

仕事でサーバーサイドJavaの世界へ

大学2年生の時から、プログラミングのバイトを初めます。従業員10人くらいのこじんまりとした会社でした。

始めて突っ込まれた案件は、Atg Dynamoというフレームワークを使っていました。すごい重量級フレームワークでした。二度と使いたくありません。

自社開発の仕事にアサインされる

その案件が終わってからは、ほぼ一貫して自社開発の製品の新規開発・カスタマイズをやっていました。そこで使っていた自社フレームワークはシンプルで使いやすかったですが、データは全部文字列で扱う流儀で、HashMapみたいなデータ構造に

set(“LAST_NAME”, “hogehoge”);
set(“FIRST_NAME”, “hugahuga”);

みたいなコーディングスタイルでした。。。まさか、このフレームワークをその後10年使い続けるとは思わなかった\(^o^)/

システムのリニューアルを任され、自由に学べる期間があった

ベンチャー企業というのは、何が正しいかよりも目の前の問題を最短で解決するのが良いとされることがあるので、その場限りの仕事を数年続けました。

転機は2008年の暮れ、主力システムをリニューアルする任務を与えられ、自由にやっていいと言われました。そこで、当時のトレンドだったWicket、Seasar、Spring、Google Guiceなどを全力で追いかけてみました。

本当はこの時社内標準フレームワークを刷新したかったのですが、工数を考えると既存資産を活かすことがどうしても必要だったので、従来の自社フレームワークに僕がOSSから学んだエッセンスを加えるという方針にしました。そのため、「フレームワークの使い方」より、フレームワーク自体のソースコードを読むようになり、特に、Seasar2のソースコードは読みやすくて勉強になりました。(Apacheライセンスなので流用もしやすく助かりました!)

結局、テンプレートエンジンとしてMayaaだけ採用しましたが、たまたまその後作ったサービスが成長したため、最もMayaaを使い倒している人みたいになってしまいました。

エンジニアとしての目標: 30までに勉強会で登壇する

僕は家庭の事情もあって、2009年ごろまで、IT系勉強会というものに参加したことがありませんでしたが、このまま無名のエンジニアではいたくないと思い、「30歳までに勉強会で登壇する」ことを目標としていました。

結果的には、
2012年と、2013年のJJUG CCC当時、28, 29の時に実現できたので、目標は達成したことになります。

Season Conferenceは2010を最後にしばらく開催されませんでしたが、もし、2011年に開催されていたら、この、2013年のネタはその時できたと思います。

最後のSeasar Committerになる

そして、久しぶりに開催された2015年のSeasar Conferenceが開催されこんなLTをし、

その後、初めてMayaa初代メインコミッターの栗原さん、現メインコミッターの須賀さんに出会うことができ、そのまま流れで僕もコミッターにしていただきました。そしてどうなったかはこのスライドのとおりです。

コミッターになってからした仕事はMayaa Advent Calendar 2015を書いたことくらいです。コミットしてないです。(今後必要があったら、コミットすることもあるかもしれません。コミッターになる前はバグ報告をしてパッチを送ったり、GitHubになってからは、PullRequestを送ったことがあります)

振り返って、Javaと僕の付き合いは何だったのか

僕はJavaで12年仕事のコードを書いてきましたが、今の今まで、J2EE、Java EEのような世界は、Servlet/JSPくらいしか経験がありません。EJBも書いたことがありませんし、JPAも使わず生のJDBCに独自ラッパーをかぶせてなんとかしました。SpringやSeasarContainerも業務で使ったことはありません。

勉強して、こういうの良いなと思ったら、ポイントポイントでどんどん取り入れていきました。アプリケーション・サーバーは、Tomcatくらいしか使っていません。そのため、本来であればアプリケーションサーバーが提供してくれるような機能も自作しました。

こういうところは、このあたり、一般的なJavaプログラマーとは違うかもしれません。

それならいっそ、PHPを使えば良いんじゃないかと言えますが、静的型付け言語であるJavaのIDEの実力・Eclipseにはお世話になりました。サービス開発初期は何が正解なのか分からず、動かしながら抜本的に作り直すなんてこともあります。その時、呼び出し階層・型階層の機能がなければつらいかった。

ただ、中盤以降はIDEに頼り切るスタイルが仇となって、どんどん重たくなって苦しくなりました。

持論ですが、ある程度大規模になると、場当たり的な設計をやめ、モノリシックをやめ、きちんと設計して、適度にマイクロサービスみたいにモジュール分割するのが正解だと思います。そして、各マイクロサービスは、JavaよりもLLの方が書きやすいと思っています。

Javaプログラマーから見たPython

新天地ではPythonistaになります。まだ一ヶ月くらいしか触っていませんが、Pythonは非常にとっつきやすい言語だと思いました。同じことができるフレームワークやライブラリが乱立せず、体系的に整っているように見えます。

お陰で非常に入門しやすく、何かをするにあたって迷ったりはまったりすることが極端に少ない言語だと思いました。

Javaは僕の育ての親

しかしJavaはSeasar Project等、日本発のJavaのOSSという教材に恵まれているために、質の良いコードを読ませてもらって学習させてもらえたことはかけがえのない経験だったと思います。

初めて触ったプログラミング言語はObject Pascal(Delphi2.0)ですが、業務で実用的に使い、多くの先人の知恵を学ばせてもらった、僕の育ての親はJavaであることは間違いありません。

これからはEclipseを起動することも少なくなると思います。そのうちショートカットも忘れてしまうかもしれません。それでも、僕のプログラミング哲学に影響を与えたのは、Javaであり、とりわけ、Seasar Project関係のOSSのそれぞれの開発者の方々の知恵を借りてこれからも頑張っていきたいと思います。

番外編 java-ja について

僕にとって java-ja は発足当時から憧れのコミュニティでしたが、家庭の事情でイベントに参加することは今まで一回もできませんでした。この記事が公開される12/3には java-ja 忘年会があって、実は java-ja のイベント初参加です。

]]>
https://susumuishigami.github.io/susumuisinfo/?feed=rss2&p=1809 0
エンジニアという職種がどれほど夫婦円満に役立ったか https://susumuishigami.github.io/susumuisinfo/entry/2016/aishiteru_advent_calendar_2016_12_2 https://susumuishigami.github.io/susumuisinfo/entry/2016/aishiteru_advent_calendar_2016_12_2#respond Thu, 01 Dec 2016 15:00:31 +0000 http://www.susumuis.info/?p=1790 この記事は妻・夫を愛してるITエンジニア Advent Calendar 2016の2日目です。1日目はbackpaper0さんの世界の中心で愛を叫んだうらがみです。

このアドベントカレンダーの提案者うらがみさんとは同年代のようです。同じJavaプログラマーで、愛妻家エンジニア同志ということで、2番手として記事を書かせていただきます。

僕は来年で結婚10年になります。妻は結婚当初からある病で闘病中の身ではありますが、おかげさまで、まだ無事夫婦を続けられています。

ここまで試練の連続ではありましたが、ここまでやれたのも、僕がエンジニアで良かったなーと思うことが多々あります。今日は、そんなエンジニアで良かったーと思うことを書いていこうと思います。

エンジニアで良かったなあと思ったこと

その1. いつでも、どこでも仕事ができる

ITエンジニアはPCと電源とネット環境さえあれば、大体の仕事ができます。

自宅作業などは比較的やりやすい職種だと思います。もっとも、妻は家に仕事を持ち込むことを嫌うので自宅での仕事はめったにしません。

どちらかと言えば、これが理由でフレックスに勤務できるというメリットを享受してきました。ある日具合が悪く看病のために休んでしまった時、遅れた仕事を土日にノマドワークで終わらせるなどということはよくやりました。

その2. 理解がある上司に巡り合うことが多い

比較的新しい職業なのでしがらみが少ないのか、それとも頭脳労働者であるために体育会系ではないからか、今まで巡り合った上司の方は、全てが家庭に配慮をしてくださって、柔軟に対応してくださいました。

その3. どうしようもなかったら転職することができる

どんな職場も状況が変わることがあります。それは仕方がないことです。そんな時、最後の手段として、転職をするという手段があります。エンジニアほど転職することに条件が良すぎる職種はないのではないでしょうか?エージェントなども充実していますが、IT勉強会などの人のつながりも捨てがたいです。

転職の度に、僕は家庭の状況を説明し、柔軟な勤務を認めていただいています。

夫婦円満のための時間管理のすすめ

ここまで書いたことに反して、僕はある時期、大変遅くまで連日残業。。。という生活をしていました。

それはたまたまその時、比較的家庭状況が落ち着いていたことと、プロジェクトが炎上状態にある中で、リーダーに任命されたこともあって、自分の判断で責任を全うしました。

しかし、それすら、もっとうまくできたのかなと今では反省しています。

その時は平気でしたが、やはり、そのような無理な働き方は体を壊しますし、夫婦仲も悪化させます。ただ早く帰ってればいいというだけではありませんが、だからと言って連日遅くまで働いて、パートナーを心配させてしまっては夫として失格です。

しかし、僕らエンジニアは、スケジューリングなどを生まれながらにして苦手としていた人種でもあります。そんなときはエンジニアらしく本で学びましょう!お勧めは何と言ってもこの本です。

ちなみにこの本はプログラマーというより、サーバー管理者を想定して書かれています。僕の主な職務はプログラミングですが大体においてスケジュールが狂う大きな原因は、「差し込み業務」にあって、プログラマー的な部分よりも「システムに詳しい人」という部分で発生します。なので、問題なく当てはまると思います。

パートナーの調子が悪い。こんな時に大事な仕事が!という人の生き方

働く男は悩みが多い。家庭で大問題!なのに仕事が!というとき、どうしたら良いでしょうか?例えば、世の中にはこんな人がいます。(本当はITエンジニアでこういう人を見つけたかったのですが、「管理職」って感じの方ですが。)

感動の家族愛の物語です。「自分は妻を・家族を愛してるぞ」と言う人は、読みましょう!奥さんが肝硬変にうつ病でお子さんは自閉症、奥さんと娘さんが自殺未遂を経験、そんな家庭問題をオープンにしつつ、そのビハインドを背負ってなお、家庭問題を解決しながら、仕事術を極め、社長になった方の物語です。

ちなみに、この著者の方はこんな本も書いています。

しかし、この人の本を読み返すと、僕はこんなに強烈に仕事と家庭に情熱を燃やすおっさんになれるでしょうか?自信はありません。こういうすごい人もいる。しかし、自分は自分です。

そんな僕にはこっちの方が合っているように思います。

まとめ

実は、今日付けで僕は転職し、新天地で働いています。それに際して、これらの本を読み返しました。(なぜかって?これらの本は僕が妻を守るためにどうしたら良いか、考えるために読んだからですよ!)そうしてみると、これらの本が教えてくれたことを、僕は忘れていたなと思いました。「あの時、もっとうまくできたのに」と反省して止みません。いや、人生とは常にそんなものなのかもしれません。

しかし、今からでも遅くないと思いますから、僕は今日から頑張ります!みなさんも、一緒に家族愛の探求をしませんか?

そして、いつか「エンジニアのワークライフバランスと家族の幸せハッカソン」みたいな企画をやりたいと思います。

]]>
https://susumuishigami.github.io/susumuisinfo/?feed=rss2&p=1790 0
Bash on Windowsを入れてみてやってみたこと https://susumuishigami.github.io/susumuisinfo/entry/2016/bash_on_windows https://susumuishigami.github.io/susumuisinfo/entry/2016/bash_on_windows#respond Fri, 19 Aug 2016 01:38:05 +0000 http://www.susumuis.info/?p=1776 出遅れてしまいましたが、8月頭に公開されたWindows 10 Anniversary Updateについて、書きます。

目当てはもちろんBash on (Ubuntu on) Windows

他にも色々変わっているようですが、僕はこのためにアップデートしたんだと言うくらい、この機能に期待していました。導入の仕方はこの辺りを参考にすると良いと思います。

http://qiita.com/Aruneko/items/c79810b0b015bebf30bb

僕が入れてみたもの

ssh

標準のターミナルがCommand Promptで、日本語とかがうまく表示されなかったりするので、とりあえず、これを入れて、PuttyとかPoderosaでアクセスしたい!こんなことせずにmsys2やcygwinみたいにminttyでアクセスできると良いんだけどね。

http://qiita.com/ubnt_intrepid/items/84a56a01cf7081401917

こちらの記事では、/etc/ssh/sshd_configに以下の表記が必要ということだったけど、PasswordAuthentication yesは不要で、ちゃんと鍵認証できました。

UsePrivilegeSeparation no
PasswordAuthentication yes

LAMP環境

まあ、王道的使い方の一つというか、Web開発するときに、マカーたちがローカルに環境をホイホイ立ててる間にWindowsっ子は(Windows版で環境を立てると微妙に違って動かないとか言われて)仮想マシンをセットアップしなければならなかったことがなくなるのは良いですね!

$ sudo apt-get install php5 php5-mysql mysql-server
$ php -S localhost:8000

これでローカル8000ポートでPHPが動くことを確認できました。

ただ、MySQL部分だけはWindows版を動かしたほうが早いかも!

PHP7

Bash on Windows のUbuntuは14.04 LTS準拠らしいです。ちょっと古いですよね!PHPも5が標準のようです。

次の記事を見ると、16.04にすることもできるみたいですが、あまりテストされていないだろうと考えると怖いので、あくまで14.04の範囲で頑張ろうと思います。

http://qiita.com/Aruneko/items/2670f42d36a7508c13bb

せっかくならPHP7を入れてみましょう。

$ sudo add-apt-repository ppa:ondrej/php
$ sudo ape-get install php7.0

まあ、普通に入りました。

node環境

これこそやりたいことですよね!今時npmをまともに使えないWindowsは取り残されてた感満載でした!

ただ、

$ apt-get install nodejs

で入るnodejsは古いので、使ってはいけないようです。。
最初これをやってしまってハマりました!

次の記事などを参考にして最新版のnodeをインストールすれば、npmなども最近の記事に書かれているとおりに動きました。

http://qiita.com/TsutomuNakamura/items/7a8362efefde6bc3c68b

$ sudo curl -sL https://deb.nodesource.com/setup | sudo bash -
$ sudo apt-get install nodejs

ただ、現時点でnodejs, npm界隈は流動性が激しく、ほんの半年前の記事に従って操作しても、書き方が変わっていたりして思ったように動かなかったりしました。

とはいえ、これはWindowsの問題じゃない

HHVM, mariadb

PHP7、mysql5.6が動けば別に構わないのですが、せっかくなので、HHVM, Maria DBの組み合わせも動くかどうかやってみました。

結論としては動きました(^o^;)

やり方は、僕の記事が良いのではないでしょうか?

http://www.susumuis.info/entry/2014/06/11/222935

この上で、WordPressなんかもすんなりと動いてしまいました!

せっかくなので、一時的にポートを開けて外部からアクセスしてみて速いかどうかテストしてみましたが、同じWindows上のHyper Vで動かしているHHVM + MariaDBなWordPressの方が速かったです!

SSH for WindowsからBash

今の状態では、Bash on Windowsはあくまで開発者用で、サーバー向けではありませんから、Bashウィンドウを開かないとSSHなどができません!

自宅サーバーのメンテナンスに、リモートデスクトップを使っていますが、スピードの遅いモバイル回線ではこれはきついので、SSHできたら便利です。

一応、SSH for Windowsというのはありますが、リモート越しにコマンドプロンプトになるので、あんまり嬉しくない。(Power Shellとか使いこなせると良いらしいですが。。。)

そこで、SSH for Windowsごしにbashとコマンドを打って、Bashに切り替えられたら便利だなーと思ってやってみたのですが、どうもこれはダメみたいです。

総評

他の方のブログを見させていただいたところによると、Docker動かそうとして動かない。Oracle JavaやOpen JDK動かそうとして動かないなど、色々と動かないものもあるようです。

しかし、とはいっても、 Ubuntuなのが良いです!Ubuntu向けのWebの記事のまんまやって大体動きます!HHVMは長いことMac用のバイナリがリリースされていなかったので、場合によってはかえってWindowsの方がネイティブ環境を立てやすいということになるかもしれません!

今時、Linuxを使うといっても、ソースからビルドして環境を建てられる猛者はあまりおらず、aptやyumなどのコマンドラインで解決するのがほとんどです。ああ、僕が欲しかったのはLinuxではなく、Ubuntu(またはDebian)だったのか〜と痛感しました。

ただ、ターミナルで日本語が欠けて表示されてしまうなど、不完全なところも多い部分は今後に期待です。

また、「開発者モード」にしないとインストールできないので、現場によっては、「開発者モード」への設定が禁止されて使うことができないかもしれません。あと、タブレットでよく使われている32bit版Windows版には提供されていないようです。

そう言った、もろもろのことを考えると、Windowsでcurlやgrepなどのコマンドラインが欲しいという用途では、msys2 が現状では最適のように思います。

しかし、なんといってもUbuntuということで、今後に期待したいと思います!

]]>
https://susumuishigami.github.io/susumuisinfo/?feed=rss2&p=1776 0
同時に複数の処理を実行するための最低限の知識 – メイドさんでも分かるプログラミングシリーズ vol.4 https://susumuishigami.github.io/susumuisinfo/entry/2016/multi_thread_maid https://susumuishigami.github.io/susumuisinfo/entry/2016/multi_thread_maid#respond Thu, 14 Jan 2016 11:12:58 +0000 http://www.susumuis.info/?p=1762 前回に引き続き、メイドさんにプログラミングを教えるためのシリーズです。

前回Webサーバーの仕組みについて、説明しました。早速アプリからWebサーバーに通信するプログラムを作ってみたくなりますが、その前に一つ知っておかなければならないことがあります。

外部と通信する時に大切なこと

Webサーバーは、アプリを実行する端末とは通信回線越しに離れたところにある別のコンピューターです。そのため、通信をして結果が帰ってくるまでの間には、どうしても待ち時間が発生します。

ところで、プログラムは通常、上から順に書いたとおりに実行されます。途中で遅い処理があると、その処理が終わるまであとの処理は行われないのが大原則です。

通信している間待つ

もし、Webサーバーとの通信のような遅い処理を待ってしまったらどうなってしまうでしょうか?ボタンを押してから、サーバーが結果を返すまでの間、固まってしまうことになります。その間は、他のボタンを押すこともできませんし、ホームボタンを押してホーム画面に戻ることも、別のアプリを起動することも、アプリを終了することさえもできなくなってしまいます。

通信中ボタンが押せない!--

こんなアプリを作ったらユーザーに怒られてしまいますね。(^^;
(実際はできないようになっています)

並列プログラミングとは

外部との通信など結果が得られるまでに時間がかかってしまう処理は、待つのではなく、別個独立してやって欲しいです。このような処理「並列処理」と言います。

並列処理をJavaで実現する、最も基本的な仕組みとして、「スレッド」というものがあります。Threadとは糸という意味です。一つの処理の流れを糸に例えて、複数の糸が同時に伸びて絡み合っている様子をイメージしてください。複数のスレッドを使うので、「マルチスレッド」ということもあります。

スレッドは糸

Javaでスレッドを作るためにはズバリ、Threadというクラスを使います。書き方は2通りあります。

Thread t = new Thread() {
    @Override
    public void run() {
        // 処理
    }
};
t.start();
Thread t = new Thread(new Runnable() {
    @Override
    public void run() {
        // 処理
    }    
});
t.start();

2つの書き方の結果に違いはありません。第2回の知識を使うと、前者はTemplate Methodで、後者はRunnableという関数オブジェクトを使っていますが、どちらを使うかは自由です。

最も手っ取り早くスレッドを作りたければこんな書き方ができます。

new Thread() {
    @Override
    public void run() {
        // 処理
    }    
}.start();

スレッドの使い方はこれだけです(笑)

しかし、実際はスレッドを扱うには注意しなければいけないことがたくさんあります。

スレッドは動き始めてしまったら止められない(汗;

Thread t = new Thread() {
    @Override
    public void run() {
        // 処理
    }
};
t.start();

このように初めてしまったスレッドtは、もう、run()メソッドが終了するまで外側から止めることはできません。

stop()susupend()というようなメソッドがあるように見えますが、これらは「安全ではない」と非推奨になっています。
スレッドは止められない

もし、プログラミングを失敗して、いつまでも終了しないスレッドがたくさん作られたら大変です!マシンが暴走してしまい、システムはカックカクで最終的に強制終了しなければならないでしょう。

毎回結果が異なる

複数のスレッドがあるとき、コンピュータはどのスレッドをどのくらい優先的に実行するのか、プログラマーには制御できません。そのため、全体の処理の順番が、その時時によってバラバラになります。そのため

「あれ?前回と結果が違う」

「トラブルの報告を受けて、言われたとおりに試したけど再現しない」

ということが格段に増えます。

データが壊れることがある

オブジェクトは複数のスレッドから同時に使われることを想定していない場合があります。

例えばプログラムをカフェの店員さんに例えてみましょう「お客さんのコップの中身が空なら水を注ぐ」という仕事があったとします。きっとこんなプログラムだと思います。

if (お客さんのコップは空ですか?()) {
    お客さんのコップに水を注ぐ();
}

とてもシンプルですね!店員さんが一人の時はこれで問題がありませんでしたが、大変ありがたいことに、お店に人気が出て、お客さんがたくさんいるので、店員さんを複数人雇いました。店員さん一人ひとりが一つの「スレッド」です。

class 店員スレッド extends Thread {
    @Override
    public void run() {
        while (就業時間中?()) {
            if (お客さんのコップは空ですか?()) {
                お客さんのコップに水を注ぐ();
            }
            // その他色々        
        }        
    }
}
Thread 店員1 = new 店員スレッド();
Thread 店員2 = new 店員スレッド();
Thread 店員3 = new 店員スレッド();
店員1.start();
店員2.start();
店員3.start();

さあ、みんなで仕事を始めたら大混乱!

  • まず、店員1さんが、お客さんのコップを確認します。
  • 「あ、コップが空だ!注がなきゃ!」といって水を準備します。
  • その間に店員2さんも、同じお客さんのコップを確認します。
  • 「あ、コップが空だ!注がなきゃ!」といって水を準備します。
  • 店員1さんが戻ってきてコップに水を注ぎます。
  • コップは水で満タンになります。
  • そこへ店員2さんが戻ってきました。
  • 店員2さんは、さっきコップが空だと確認したので、よく確認しないで、コップに水を注ぎます
  • コップは既に水で満タンなので、盛大にこぼれます!!

データの破壊

実際の人では、そんなことは起きませんが、複数人の人が無秩序に動いていたら大変な様子が想像できると思います。

並列プログラミングでは、「あるデータの状態を見る」それにもとづいて「次の処理をする」というプログラムを書くとき、「その間に別のスレッドが書き換えているかもしれない」という心配が常に発生するのです。

そこで、どうするかというと、店員1さんがお客さんの対応を始めたら、別の店員さんが同じお客さんを対応しないように、印を付けてしまいます。この行為を「ロック」と言ってJavaではsynchronizedと書きます。

synchronized (お客さん) {
    // お客さんに対する処理
}

このようにしておくと、別の店員さんはロックされている間、そこで処理を待ちます(別のお客さんのところには行かないです)。

固まってしまうことがある

そんな、データの破壊を防ぐためのロック機構ですが、ロックをすると別の怖い問題が発生します。「デッドロック」という現象です。

  • お客さん1をロックする
  • 何かする
  • お客さん2をロックする
  • 何かする

という店員Aさんと、

  • お客さん1をロックする
  • 何かする
  • お客さん2をロックする
  • 何かする

という店員Bさんが同時に動いていたとします。

運悪く、それぞれが「お客さん1」「お客さん2」をロックした後、それぞれ「お客さん2」「お客さん1」をロックしようとしたらどうなるでしょう。

答えは2人の店員さんは見つめ合って固まってしまいます。\(^o^)/

デッドロック

この現象を「デッドロック」と言います。デッドロックはとても怖い現象です。防ぐことが難しく、発生したらもう救うことができないからです。

デッドロックを防ぐ方法としては、

  • 逐次ロックせず一変に全部ロックする
  • ロックする順序を必ず同じにする

などの工夫があります。それでも、複雑なプログラムではうっかりどこかで考慮漏れは発生します。

今日もどこかでデッドロックでプログラムが固まっているでしょう。

まとめ

並列プログラミングは、カフェで店員さんがたくさんいるような状態だとイメージ出来ましたでしょうか?人がたくさん働くときは、秩序が必要であるのと同じように、コンピュータも、マルチスレッドの時は秩序の管理が大切になります。

]]>
https://susumuishigami.github.io/susumuisinfo/?feed=rss2&p=1762 0
Webサーバーの仕組み – メイドさんでも分かるプログラミングシリーズ vol.3 https://susumuishigami.github.io/susumuisinfo/entry/2016/web https://susumuishigami.github.io/susumuisinfo/entry/2016/web#respond Mon, 04 Jan 2016 03:30:03 +0000 http://www.susumuis.info/?p=1748 前回に引き続き、メイドさんにプログラミングを教えるためのシリーズです。

今回は前回までとうってかわって、Webサーバーの仕組みを説明します。Androidアプリを使っていると「この部分はサーバーが必要だ」「ウェブサーバーを立てよう!」という言葉をよく聞くと思います。

「ウェブ」って、「ホームページ」とか見るための仕組みではないでしょうか?なぜ、スマートフォンアプリにWebサーバーが必要なのか?Webサーバーを立てると何ができるのか、アプリ開発視点で見ていきたいと思います。

WWW(World Wide Web)は、世界中の論文をリンクする仕組みだった

昔々、と言っても1990年代なのですが、Timさん (Tim Berners-Lee)という人が、現在私達が「インターネット」だと思っている世界を考えました。

World Wide Webと名付けられたそれは、当時、できたてほやほやの「The Internet」を使って、論文を公開する仕組みとして設計されたものでした。

論文は他の論文を引用します。引用先はワンクリックでジャンプできたら便利です。そこで、引用先にリンクできる仕組みを「ハイパーリンク」を実現するテキスト文書「ハイパーテキスト」が誕生しました。「HTML」です。これは

<a href="リンク先">リンクテキスト</a>

のように書くと、他の文書にリンクできる画期的な書式でした!

Webとはくもの巣という意味です。文書と文書がリンクによってくもの巣のように世界中に張り巡らされている!それがワールドワイドなウェブの目指す世界だったのです。

この世界を実現するために、論文を読むためのソフト(Webブラウザー)と、論文を配信するホストコンピュータ(Webサーバー)が作られました。WebブラウザーとWebサーバーは互いに通信をします。通信をするための決まりごとを「プロトコル」と言います。Web専用のプロトコルとして、「HTTP (Hyper Text Transfer Protocol)」が作られました。

WWWの世界

用語のおさらい

用語 意味
World Wide Web Timさんが考えた「The Internet」上の論文配信ネットワーク
ハイパーリンク 論文から引用先論文にジャンプする画期的機能
ハイパーテキスト(HTML) ハイパーリンクを実現するための文書形式
Webサーバー 論文を配信するサーバー
Webブラウザ 論文を閲覧するためのソフト
プロトコル 通信をするための決まりごと
HTTP WebサーバーとWebブラウザの間で行われる通信のプロトコル

HTTPの仕組み

論文をサーバーから貰うには、次の情報が必要です。

  • 論文のファイル名

論文を取得する命令をGETと名付けられました。

GET /folder/hogehoge.html

この命令(「HTTPリクエスト」と言います)を受け取ったWebサーバーは、folderの中にhogehoge.htmlがあれば次の情報を返します。

  • 「あったよ!」という情報
  • hogehoge.html の内容

これらを合わせて「HTTPレスポンス」と言います。

そのうち、前者を「ステータスコード」と言います。これは数字3桁によって定められていて、例えば次のように決まっています。

  • 200: OK (あったよ!)
  • 400: BAD REQUEST(リクエストが間違ってるよ!)
  • 404: NOT FOUND(そんなファイル無いよ!)
  • 500: INTERNAL SERVER ERROR(ごめん、サーバーでエラーが起きちゃった(汗;)
  • 503: Service Unavailable(ごめん、今混んでるみたいだ!後でもう一度来て!)

とてもシンプルな仕組みですね!

HTTPの仕組み

WebサーバーがHTMLを自動生成しても良い

Webサーバーは、Webブラウザーから、リクエストを受け取ったら、ステータスコードと、HTMLページを返せば良いのです。HTMLページは、サーバーのディスク上に、HTMLファイルとして置いておくことが最もシンプルですが、別に、ファイルがなくても、その場でプログラムで作ってしまっても良いのです!

Webリクエストを受け取ったWebサーバーが、プログラムを動かす仕組みとして、CGI (Common Gateway Interface) という物が作られました。

Webプログラムの仕組み (2)

プログラムによって毎回違うページを作ることができるので便利です(例えば、現在時刻を出力!)このようなページのことを「動的ページ」と言います。反対に毎回変わらないページを「静的ページ」と言います。

Webリクエストにパラメータを渡したくなったら

CGIによって「動的ページ」が実現できると、プログラムにパラメータを与えたくなってきます。そこで、初め、ファイル名の後ろに?を付けてその後ろにパラメータをつけていく方法が考えられました。

GET xxx.html?id=1

この方法はとても便利です。現在でも、Googleの検索結果を

https://www.google.com/?q=Java

のように表すことができます。

しかし、問題がありました。

GETの仕組み

  • 大量のデータを送ろうとすると長くなりすぎる

そこで、POSTという別の方法が考えられました。これは、ファイル名を指定した後、一行空行を開けてパラメータを送るという方法です。

POST /hello.cgi

name=taro&age=20&country=Japan&.......

これによって、非常に大量の情報が遅れるようになったので、Webを使って「ご注文フォーム」が作れるようになりました。Amazonのようなネット通販の始まりです。

POSTの仕組み

時代の流れとともに、いろんな情報を送りたくなってきた

時代は流れ、WWWは論文の配信だけにとどまらず、通販やゲームのようなあらゆる用途で使用されるようになってきました。しかも、文書だけでなく、画像、音声、映像、様々な種類のデータを配信するようになります。

そうすると、HTTPもどんどん複雑になります。現在はHTTP 1.1というバージョンが主流で、次のようにいろんな情報を送ります。

GET http://www.susumuis.info/
Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Encoding:gzip, deflate, sdch
Accept-Language:ja,en-US;q=0.8,en;q=0.6
Cache-Control:no-cache
Connection:keep-alive
Cookie:
Host:www.susumuis.info
Pragma:no-cache
User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.86 Safari/537.36

レスポンスは

200 OK
Cache-Control:no-cache, must-revalidate, max-age=0
Connection:keep-alive
Content-Encoding:gzip
Content-Type:text/html; charset=UTF-8
Date:Mon, 04 Jan 2016 02:57:30 GMT
Expires:Wed, 11 Jan 1984 05:00:00 GMT
Pragma:no-cache
Server:nginx
Transfer-Encoding:chunked
Vary:Accept-Encoding

<!DOCTYPE html>
<html>
〜
(省略)
</html>

こんな風に、色々な情報が付与されてきます。Accept:のようにHTTPリクエストに付与される付加情報を「リクエストヘッダ」と呼びます。Cache-Control:のようにHTTPレスポンスに付与される付加情報を「レスポンスヘッダ」と呼びます。

Content-Typeヘッダについて

レスポンスヘッダに次の部分がありました。これは「コンテンツタイプ」といって、とても重要な情報です。

Content-Type:text/html; charset=UTF-8

text/htmlは、「MIME Type」と呼ばれる情報です。これは、レスポンスするデータの種類を表しています。MIME Typeには次のようなものがあります。

MIME Type 意味
text/plain テキスト文書
text/html HTMLページ
image/jpeg JPEG画像
text/javascript JavaScript
application/xml XMLデータ
application/json JSONデータ

アプリとWebサーバー

本来、Webサーバーは、WebブラウザーにWebページを配信することを目的としたサーバーでした。しかし、時代は流れ、Webブラウザだけでなく、HTTPプロトコルさえ使えれば、Webサーバーと通信ができる特性を利用して、スマートフォンアプリなどのプログラムがサーバーと通信をするために大変広く使われるようになりました。

HTTPがシンプル・高機能・有名で便利だったからです。

プログラム同士の通信では、もう、HTMLを使用する必要はありません。HTMLは人間に見た目を提供するためのフォーマットだからです。

プログラムで使う場合は、XMLまたはJSONというデータ形式が使われます。

XMLの例

<items>
  <item>
    <name>アイテム1</name>
    <price>1000</price>
    <image>xxxxxx.jpg</image>
  </item>
  <item>
    <name>アイテム2</name>
    <price>1240</price>
    <image>yyyyyy.jpg</image>
  </item>
</items>

JSONの例

{
    {
        "name": "アイテム1",
        "price": 1000,
        "image": "xxxxxx.jpg"
    },
    {
        "name": "アイテム2",
        "price": 1250,
        "image": "yyyyyy.jpg"
    }
}

アプリからの利用イメージ

サーバーはどうなっているの?

アプリ側から、サーバーの内部を意識する必要はありません。しかし、サーバーは通常次のように作られています。

Webサーバー

Apacheや、IIS、Nginxというようなサーバーソフトが使われます。

サーバープログラム

PHPや、Javaや、Rubyで書かれています。その間にアプリケーション・サーバーというソフトウェアが動いている場合もあります。

DBサーバー

Webサーバーは非常に大量のデータを扱うため、DBサーバーという専用のソフトウェアが使われることが大変多いです、MySQL、PostgreSQL、Oracleなどが有名です。

キャッシュサーバー

DBサーバーは非常に便利ですが、遅いという問題があります。そこで、高速化の目的で、別途キャッシュ用のサーバーが用意されていることがあります。Redis、Memcachedなどが有名です。

サーバーの構成例

まとめ

このように、もともと論文を配信するためであったWebサーバーはとても便利なので、アプリのデータをやり取りするために使われるようになりました。

Webサーバーは今やとても複雑な仕組みですが、呼び出す側としては、HTTPプロトコルさえ分かればやり取りができるので、内部まで意識しなくても大丈夫です!

それでは、次回は実際にアプリから呼び出す方法を説明していきます。

]]>
https://susumuishigami.github.io/susumuisinfo/?feed=rss2&p=1748 0
Javaでオブジェクトを使いこなすために知っておくべきこと – メイドさんでも分かるプログラミングシリーズ vol.2 https://susumuishigami.github.io/susumuisinfo/entry/2016/java_object_technic https://susumuishigami.github.io/susumuisinfo/entry/2016/java_object_technic#respond Sat, 02 Jan 2016 13:46:10 +0000 http://www.susumuis.info/?p=1709 前回に引き続き、メイドさんにプログラミングを教えるためのシリーズです。

前回「オブジェクトの多態性ができると便利です」と説明しました。今回は、なぜ便利なのか分かるように、プログラミングでよく使われるテクニックを6つ紹介したいと思います。

これらを知ることが出来ればオブジェクト指向のメリットを理解出来るだけでなく、実践でプログラミングをしているプログラマーと、かなりコアな会話ができるようになりますよ!

その1: 関数オブジェクト

プログラムをしていると「何か起きた時に、この関数を実行して欲しい」という時が良くあります。このような、ある条件の時に実行してもらう関数のことを「コールバック関数」と呼びます。

Javaはメソッドを変数や関数のパラメータに代入することができませんので、こういう時、コールバックして欲しい処理を書いたメソッドを持つオブジェクトを作って、それを渡します。

このようなオブジェクトのことを関数オブジェクトと呼びます。

例えば、架空のクラスですが、WebClientというWebサーバーに通信をして、通信が成功した時に行う処理を指定できるようになっているとします。WebClientResponseCallBackというインターフェース

webClient.connect(new WebClientResponseCallBack() {
    @Override
    public void onSucceeded(int status, String result) {
        System.out.println("成功しました");
        System.out.println(status);
        System.out.println(result);
    }
    @Override
    public void onFailed(String result) {
        System.out.println("失敗しました");
        System.out.println(status);    
        System.out.println(result);
    }
});

これは架空のコードですが、このようなスタイルのライブラリはたくさんありますので、慣れておきましょう。

@Overrideという記号が初めて登場しました。これはアノテーションと言うもので、プログラムにつける印です。様々な場面で使用しますが、@Overrideアノテーションは、継承してメソッドを上書きしていることを示すものです。必須ではないため前回は省略しましたが、付けないとコンパイラ警告が出てしまいますので、今回からは付けることとします。

関数オブジェクト

その2: Template Method パターン

関数オブジェクトと似たような用途として、クラス継承を活用して、処理を記述する方法もあります。

これも、架空のクラスですが、例えば、画面があって、OKボタンを押した時に何が起こるかはプログラミングできるようになっているライブラリが合ったとします。

SampleScreen s = new SampleScreen() {
    public onClickOkButton() {
        System.out.println("ボタンが押された!!");
    }
};
s.show();

このような、クラス継承を利用して、一部分のメソッドだけサブクラスに委ねるテクニックを、Template Method パターンと呼びます。

テンプレートメソッド

その3: ラッパーオブジェクトパターン

例えば、以下のコードは今まで「おまじないです」と言われていたと思います。

BufferedReader reader = new BufferedReader(new FileReader("data.dat"));

これは、FileReaderというクラスをBufferedReaderクラスが包みこんでいます。BufferedReaderのような、内部にオブジェクトを包み込むオブジェクトのことを「ラッパー(Wrapper)オブジェクト」と呼びます。楽器のラッパじゃないですよ。●ランラップのラップです!

FileReaderは、ファイルを読み込むことができますが、バッファリングの機能はありません。一方、BufferedReaderはバッファリングの機能はありますが、自らファイルを読み込む機能はありません。

そこで、BufferedReaderでFileReaderを包み込むことによって、バッファリングしながらファイルを読み込むことを実現しています。

どんなにオブジェクトを包み込んでいても、外側から見ると内側は隠蔽されています。そして、インターフェースさえ一致していれば、内側に入れるものを切り替えてもプログラムが動きます。

BufferedReader reader = new BufferedReader(new InputStreamReader(System.in);

どんなときに、ラッパーオブジェクトを作るのでしょうか?主に次のようなとき作られます。

  • 内側のクラスのインターフェースを変換して、別のインターフェースとしてAPIに渡す
  • 内側のクラスの動作に付加機能を付け加える

このように、ラッパーオブジェクトはプログラムをとても柔軟にするテクニックです。

ラッパーオブジェクト

その4: Factory

クラスからインスタンスを作るとき、

new クラス名();

と書くと説明してきました。しかし、オブジェクト指向の世界で、newはわりと嫌われ者です。何故かと言うと、これまでのテクニックの真髄はクラスを切り替えることにあります。

SoundsMaker s = new Cat();
s.makeSounds(); // ニャー
SoundsMaker s = new Dog();
s.makeSounds(); // わん

せっかくSoundsMakerインターフェースを抽出しているのに、プログラムの中に new があるため、動作が決定してしまいるのが良くないとされます。

そこで、newをなるべく隠蔽しようと言うテクニックとしてFactoryパターンというものがあります。

例えば、newを直接書かず、メソッドにしてしまうアイデア

public static SoundsMaker getSoundsMaker(String name) {
    if ("tama".equals(name)) {
        return new Cat();
    }
    if ("pochi".equals(name)) {
        return new Dog();
    }
    return null;
}
SoundsMaker s = getSoundsMaker("tama");
s.makeSounds(); // ニャー
SoundsMaker s = getSoundsMaker("pochi");
s.makeSounds(); // ワン

getSoundsMakerのプログラムを見なかったとしたら、呼び出し元は何のインスタンスが作られるか分かりません。しかし、そんなことを知らなくても、SoundsMakerインターフェースであることは保証されているので、その範囲でできることは安心して使うことができます。

ファクトリー

その5: MVCモデル

これは考え方であって、コード例はありません。ざっと覚えておいてください。

一般的に比較的大きなプログラムを書くときは、次のように分割すると良いと言われています。

役割
モデル ロジックを担当
ビュー 表示を担当
コントローラ ユーザーの操作に応答し、モデル・ビューを操作する

例えばAndroidで言えば、Activityクラスはコントローラです。もしActivityに全部のプログラムを書いてしまうと、だんだん巨大になってしまいますので、必要に応じて、モデルを切り出すと全体の見通しが良くなります。

ビューは、レイアウトの部分で、同じActivityに異なるレイアウトファイルを与えても動く点でAndroidはビューとコントローラについて抽象化されていると言えます。

MVCモデル

その6: モックオブジェクト

最後に、モックオブジェクトについて説明します。

「モック」:モックアップ(mock up)とは、店頭にある展示用模型のことです。本物ではありませんが、本物のような見かけをしています。

プログラムを作っていると、「Aというオブジェクトを使用するにはBというオブジェクトが必要」「Bというオブジェクトの初期化にはCという情報が必要」「CはAndroid実機じゃないと取得できない」などのように、芋づる式に、あらゆるオブジェクトがからみ合ってくることがあります。

しまいには、非常に大きなオバケのような存在になってしまい、一箇所変更すると、どこに影響するのか全然わからなくなることがあります。

この問題を回避するために、本物ではない、仮のオブジェクトを作って動作確認を行うというテクニックが行われます。

そのためのオブジェクトを「モック」あるいは「スタブ」と呼びます。スタブとは「代用品」という意味です。切り株が原義のようです。

インターフェースを使ってプログラミングがされている場合は、比較的カンタンにモックを作ることが出来ます。

interface SoundsMaker {
    void makeSounds();
}

お馴染みのこのインターフェース。実は今アナタはゲームを作っていて、そのゲームでは音を扱っているとします。そこではSoundsMakerインターフェースを継承したオブジェクトがmakeSoundsとやると実際にスピーカーから音が鳴るのです。

class Bomb implements SoundsMaker {
    void makeSounds() {
        // 複雑なプログラム
        // 結果的にスピーカーから音が鳴る
        // 「ドカーン!!」        
    }
}

しかし、Bombクラスを動かすためには、どうやら専用のハードウェアがないといけないそうです。

でも、音を鳴らす以外の部分は、どうやら普通のパソコンでも動かせるみたいです。

そんな時は、モックオブジェクトの出番です。

class BombMock implements SoundsMaker {
    void makeSounds() {
        System.out.println("ドカーン!");
    }
}

Bombクラスの代わりにBombMockクラスを使用するように切り替えれば、特殊なハードウェアがなくても、プログラムが動くようになります。その代わり、音が鳴るタイミングで音はならず、代わりに

ドカーン!

という文字が出力されます。

本物のオブジェクトとモックの切り替えは、オブジェクトインスタンスをnewで生成するところで行わなければなりません。そのためには「その4」で説明した、「ファクトリー」を使用する検討が必要になってきます。

モックオブジェクト

まとめ

今回説明したテクニックを使う、プログラムからどんどん野暮ったさが消えて洗練されて来ていると思いませんか?

しかし、洗練し過ぎも問題です。

例えば、Factoryの説明で作った次のコードは

SoundsMaker s = getSoundsMaker()
s.makeSounds();

元の

Cat tama = new Cat();
tama.mew();

だった時のほうが、垢抜けない可愛さがあります。

洗練されたプログラムというのは、高貴でお近づきにくい存在なのです。より多くのことを知らないと読めないし、知っていてもどんな動きをするのか「実行するまで分からない」ときます。

どこまで洗練すれば良いかは、作っているプログラム次第です。一般的に大きなプログラムは、より洗練されていることが求められますが、個人で作るアプリでは、あどけない感じで作ったほうが正解だったりします。

この感覚は、実際にアプリを作って行くことで培われていきますので、実践で身につけて行ってください。

]]>
https://susumuishigami.github.io/susumuisinfo/?feed=rss2&p=1709 0
Javaのクラス・インターフェース入門 – メイドさんでも分かるプログラミングシリーズ vol.1 https://susumuishigami.github.io/susumuisinfo/2015/class_interface https://susumuishigami.github.io/susumuisinfo/2015/class_interface#respond Tue, 29 Dec 2015 12:56:25 +0000 http://www.susumuis.info/?p=1693 プログラミングというのは、カンがいいと、言われたとおりに入力しているだけである程度のことができるようになります。しかし、そういうやり方では「ここはおまじない」「ここは決まり文句」という部分がどうしても多くなってしまいます。

ちょっと訳あって、秋葉原のメイドさんにプログラミングを教えています。そのメイドさんたちはまさにそうで、彼女たちは既にAndroid Studioで画面レイアウトをいじり、画面遷移をするプログラムを書く能力はありますが、「おまじない」「決まり文句」の多さに困惑しているように思います。

そこで、今日から「メイドさんでも分かるプログラミング」シリーズを初め、プログラミングの基礎をやさしく説明していこうと思います。

読者のレベルとしては、PCを日常的に使いこなしていているが、プログラミングの専門教育を受けていないという想定です。

なお、あらかじめ、次の記事レベルのJavaの基礎知識は学習済みであることを前提とします。

プログラム初心者に贈るJavaプログラミング - Qiita

では、早速初めます。

第1回は、クラスとインターフェースについてです。

クラスってなに?

Javaのプログラムを書くと、必ずこんな「おまじない」を書いてくださいと言われたと思います。

public class Hello {
    // ....(省略)
}

「パブリック」「クラス」と読みます。何でしょうこれは?

実はJavaのプログラムは「クラス」の集まりとして定義する「オブジェクト指向言語」なのです。

「オブジェクト指向」???

また新しい言葉が出てしまいました。

大丈夫です。これからゆっくり、説明します。

オブジェクト指向とは

「オブジェクト指向」とは、まじめに説明すると本が一冊書けてしまいます。ここに知り合いが書いた本気な資料がありますので、興味があったら読んでみてください。

ざっくり言うと、プログラムを「オブジェクト」という塊の集まりで作成します。「オブジェクト」とは「モノ」です。ここで、ちょっと日常世界を見てください。あらゆるモノがありますよね。

例えば、次の絵では、テーブルの上にコーヒーが淹れてあります。コーヒーはコーヒーカップに注がれていて、ソーサーの上に乗っています。スプーンも付いています。テーブルは木製ですね。金属の脚が付いています。「コーヒー」「カップ」「ソーサー」「スプーン」「テーブル」これらすべてがオブジェクトです。しかも「テーブル」は「木の板」「金属の脚」などの部品から構成されています。部品もオブジェクトです。

オブジェクト指向では、このように、あらゆる物に注目していきます。そうすると、一つ一つの「モノ」はシンプルに表現することができます。「カップ」はコーヒーを注ぐことができればいい。「スプーン」はお砂糖を掬うことができれば良いといった機能に特化することができるからです。

なぜそんなことをするかというと、昨今のコンピュータプログラムはとても複雑だからです。もし、すべてを一つのプログラムで書いていたら、神様のようにもの凄く巨大な存在になってしまいます。人間に神を作ることはできません。オブジェクト指向プログラミングがあるお陰で、複雑なプログラムも部品の組み合わせとして簡単に作れるというわけです。

クラスとインスタンス

さて、オブジェクトは「クラス」と「インスタンス」に分かれます。クラスはオブジェクトの設計図、インスタンスは設計図から作られたオブジェクトの実体です。一つの設計図からたくさんの実体を作ることができます。

これは、たい焼きモデルで説明されることがあります。

たい焼きモデル

さて、Javaはこのうち「クラス」の部分をプログラミングして行きます。プログラムの初めに public class と書いているのはそのためです。

実際にプログラムが動く時には「インスタンス」の方が使われます。「クラス」から「インスタンス」を作るためには次のように書きます。

new クラス名();

作ったクラスは通常、次のように書いて「変数」に格納して使います。変数は覚えていますよね?

クラス名 変数名 = new クラス名();

あれ、クラス名を2度書いていますね?実は、左側のクラス名は正しくは「型名」と言います。変数には「型」がありました。例えばこんな型です。

意味
int 整数
long 大きな整数
double 浮動小数点数
boolean true or false
Object オブジェクトインスタンスを格納
クラス名 そのクラスに属するオブジェクトインスタンスを格納

オブジェクトインスタンスを格納する変数型としては「Object」という型が存在します。なので、次のように書いてもエラーにはなりません。

Object 変数名 = new クラス名();

しかし、通常「Object型」は使用しません。それはなぜでしょうか?変数の型は、プログラミング言語に「その変数は何ができるのか?」と教える印なのです。つまり、

Object 変数名 = new クラス名();

というプログラムは「その変数はモノです」と言ってるに過ぎないのです。

「モノ」であることは分かっています。でも「モノ」と言われても、何ができるのかわからないですよね。「自動車」も「鍋」も「コーヒー」も、「人間」さえも、「モノ」ですから。

そこで、変数名の左にクラス名を書くことで、それが「モノ」の中でも何なのかを教えてあげているのです。

自動車 mycar = new 自動車();
mycar.走れ(); // これはOK

Object mycar = new 自動車();
mycar.走れ(); // 「モノ」が「走る」とは限らないからエラー

フィールドとメソッド

モノの設計図であるクラスは次のようにプログラミングします。

class クラス名 {
    フィールド定義;
                :
                :

    メソッド定義
                :
                :
}

「フィールド」とは、クラスに属する変数のことです。Java以外の言語では「メンバー変数」ということもあります。そして「メソッド」はクラスに属する関数のことです。同様に「メンバー関数」と呼ぶこともあります。

ざっくり言うと、クラスの定義は「フィールド」と「メソッド」を定義するだけです。それでどうしてモノの設計図になるのでしょうか?

状態と振る舞い

モノの概念に立ち戻ってみると、モノは「状態」と「振る舞い」という概念を持ちます。

「状態」というのは、年齢とか、職業とか、モノそれぞれによって、あるいは同じモノでもその時々によって変化する情報です。

「振る舞い」というのは、モノの外側から見える動作です。

ティーカップを例にすると、次のような状態と振る舞いがあります。

  • 振る舞い

    • 液体を注ぐ
    • 注いだ液体を飲む
  • 状態

    • 汚れの有無
    • ヒビの有無
    • 今注がれているモノ

カップのユースケース図

カップの状態

そして、Javaのフィールドは「状態」を、メソッドは「振る舞い」を表現しているのです。

ねこ様をプログラミング

それでは、ニャーと鳴くねこ様をプログラミングしてみましょう。

このねこ様は外部から見ると、こんな振る舞いをするようです。

ねこ様ユースケース図

ここで、ねこ様は「鳴け」「寝ろ」「起きろ」なんていう人間の命令を聞かないとは思わないでください。コンピュータプログラミングというのは、日常世界全てを表現する必要はありません。今、自分が必要な範囲だけプログラミングすれば良いのです。

ねこ様の状態として「寝ている」という状態があるとします。このプログラムでは、寝ている時と、起きている時で鳴き方が違うということを表現します。

以下がプログラミング例です。

/** ねこ様 */
class Cat {
    /** 寝ているかどうか。true:寝ている, false:起きている */
    boolean slept;
    /** 鳴け */
    void mew() {
        if (slept)  {
            System.out.println("ふにゅあ")
        } else {
            System.out.println("にゃー")
        }        
    }
    /** 寝ろ */
    void goToSleep() {
        slept = true;
    }
    /** 起きろ */
    void wakeUp() {
        slept = false;
    }
}

早速、ねこ様クラスを使ってみましょう

Cat tama = new Cat();
tama.mew();
tama.goToSleep();
tama.mew();
tama.wakeUp();
tama.mew();

実行結果

ニャー
ふにゃあ
ニャー

※ 最初のmewは「ニャー」となっています。これは、sleptフィールドの初期値がfalseであることを意味しています。このようにフィールド変数は、初期値が決められています。

初期値
数値 0
boolean false
オブジェクト null

アクセス修飾子

よく見かけるpubicとか、privateとは何でしょうか?これは外部に公開するかどうかを指定する記述です。ざっくり言うと

アクセス修飾子 意味
private 外部に非公開
public 外部に公開

という風に分類されます。他にprotectedというのがありますが、後ほど説明します。

もし、さっきのねこ様クラスをprivate classとして作成してしまうと、別のプログラムから参照できなくなります。(実際は記述は許されません)

では、何でもpublicにしてしまえば便利かというと、世の中何でもかんでも中のことをオープンにしてしまうことは不都合だったりします(笑)

オブジェクト指向プログラミングでは、積極的に、外側から見て不要なものを隠蔽していきます。そのようなテクニックを「カプセル化」と呼びます。

常に当てはまるわけではありませんが、「メソッド」は公開し、「フィールド」は非公開するのがセオリーです。もし、フィールドの値を直接確認したい場合は、getフィールド名()setフィールド名()という「メソッド」を作るのが作法とされます。こういったメソッドを「アクセッサー」と呼びます。

アクセッサーの例

public class Human {
    private String name;
    private int age;
    public void setName(String name) {
        this.name = name;
    }
    public void getName() {
        return name;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public int getAge() {
        return age;
    }
}

メソッドもまた「非公開」にすることがあります。これは、外部からの振る舞いといよりも、プログラミングの都合上で共通部分を抜き出した場合などに、そのようにします。

/** 名前を教えると挨拶してくれるマシーン */
public class HelloMachiene {
    private String firstName;
    private String lastName;
    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }
    public void setLastName(String lastName) {
        this.lastName = lastName;
    }
    // 姓と名をくっつけて使うことが多いので共通化
    private String getFullName() {
        return lastName + firstName;
    }
    public void sayHello() {
        System.out.println("こんにちは" + getFullName() + "さん");    
    }
    public void sayGoodBye() {
        System.out.println("さようなら" + getFullName() + "さん");    
    }
}

コンストラクタ

new クラス名()

と書いた時にプログラムを動かして、フィールドを初期化したいことが良くあります。このようなときに使うものとして「コンストラクタ」というものがあります。

コンストラクタはクラス内に次のように記述します。

public クラス名() {
    // 初期化プログラム
}

メソッドと似ていますが、返り値の型がありません。メソッドは

public 返り値の型 メソッド名() {
    // プログラム
}

でした。ところで、コンストラクタは、メソッドと同じようにパラメータを持つことが出来ます。上手く使うとプログラムを完結に書くことが出来ます。

public class Human {
    private String name;
    private int age;
    public Human(String name, int age) {
        this.name = name;
        this.age = age;    
    }
    public String toString() {
        return name + "(" + age + ")";
    }
}

使用例

Human satoshi = new Human("サトシ", 10);
Human okido = new Human("オーキド", 55);
System.out.println(satochi);
System.out.println(okido);

結果

サトシ(10)
オーキド(55)

※toStringという名前のメソッドを作って文字列が必要な場所で使用すると、toStringを省略してもtoStringが呼ばれます。これはJavaの仕様です。つまり

System.out.println(satochi.toString());

と書いても同じ結果になります。

継承・多態性

新しいことが次々に出てきて大変ですね!でも、もう少しでオブジェクト指向の一番大事なところを知ることが出来ます。大変ですが、どうか我慢してください。

クラスを作っていくと、同じようなクラスができてくることに気が付きます。そして、それらを束ねたいことがあります。その時に使用するのが「継承」というしくみです。

例えば、「ニャー」と鳴くねこ様のほかに「ワン」と鳴く犬クラス、「モー」と鳴く牛クラス、「ブヒー」と鳴くブタクラスを作ったとします

鳴け!

class Cat {
    public makeSounds() {
        System.out.println("ニャー");
    }
}
class Dog {
    public makeSounds() {
        System.out.println("ワン");
    }
}
class Cow {
    public makeSounds() {
        System.out.println("モー");
    }
}
class Pig {
    public makeSounds() {
        System.out.println("ブヒー");
    }
}

※英語とは面倒なもので、ねこはmew, 犬はbarkのように「鳴く」という動詞が異なるため、音を鳴らすというmakeSoundsで統一しました。

あるメソッドがあって、動物を鳴かせたいとします。しかし、ねこを鳴かせるメソッドを使って、犬を鳴かせることは出来ません。

void makeSounds(Cat cat) {
    cat.makeSounds();
}
Cat tama = new Cat();
Dog pochi = new Dog();
makeSounds(tama); // これはOK
makeSounds(dog); // これはダメ

これでは不便です。なぜなら、CatもDogも、makeSoundsというメソッドを持っているからです。

そこで、そこで、次の2つの考え方があります。

考えた方1: 犬もねこも「鳴く」ことができる

外部から見て、共通の振る舞いを持っているものは、「インターフェース」というしくみで束ねることが出来ます。

インターフェースは次のように定義します

interface インターフェース名 {
    返り値の型 メソッド名();
    返り値の型 メソッド名();
        :
        :
}

中身の無いメソッドの名前だけを並べて行くのです。

そして、クラスを作るときにimplementsというキーワードでインターフェースを指定すると、そのクラスのインスタンスは、そのクラス型の変数の他に、そのインターフェース型の変数にも代入することが出来ます。

難しいのでアンダーラインを引きました。深呼吸して、この部分を5回読んでみてください。

あせらないで!ゆっくりで良いですよ!

5回読みましたか?

では、具体例を書きますね。

class Cat implements SoundsMaker {
    // ...
}

として定義したら、こんな書き方がOKになります。

SoundsMaker tama = new Cat();

そして、次のプログラミングコードが成立します。

interface SoundsMaker {
    void makeSounds();
}
class Cat implements SoundsMaker {
    public makeSounds() {
        System.out.println("ニャー");
    }
}
class Dog implements SoundsMaker {
    public makeSounds() {
        System.out.println("ワン");
    }
}
class Cow implements SoundsMaker {
    public makeSounds() {
        System.out.println("モー");
    }
}
class Pig implements SoundsMaker {
    public makeSounds() {
        System.out.println("ブヒー");
    }
}
public makeSounds(SoundsMaker soundsMaker) {
    soundsMaker.makeSounds();
}
Cat tama = new Cat();
Dog pochi = new Dog();
makeSounds(tama);
makeSounds(pochi);

実行結果

ニャー
ワン

インターフェース版鳴け!

このテクニックを「インターフェース継承」あるいは「インターフェース抽出」と呼びます。

考え方2:犬もねこも「動物」である

犬も、ねこも、牛も「動物」という共通の概念を持っています。そういう共通の概念をスーパークラスと呼びます(親クラスとも呼びます)。反対は「サブクラス」(子クラス)です。

Javaではextendsというキーワードでスーパークラスを指定します。

class Animal {
    void makeSounds() {
        System.out.println("???");
    }
}
class Cat extends Animal {
    public makeSounds() {
        System.out.println("ニャー");
    }
}
class Dog extends Animal {
    public makeSounds() {
        System.out.println("ワン");
    }
}

インターフェースとの違いは、スーパークラスはあくまでクラスであるということです。

継承版鳴け!

new Animal()

と書いてしまうことも出来ます(禁止することも出来ますが今は割愛します)。またフィールドを持ったり、メソッドのプログラムを記述することも出来ます。そのようにすることで、共通メソッドなどを作ることも出来ます。

このテクニックを「クラス継承」、または単に「継承」と呼ぶことがあります。

どっちを使ったら良いの?

もし、振る舞いを束ねたいだけ場合は、インターフェースを使用してください。でも、インターフェースはめんどくさいこともあります。特にたくさんのメソッドを束ねるときには向いていません。また実装を持つことが出来ないため、コピーペーストが増えてしまいます。

スーパークラスは、一つしか持つことが出来ません。つまり、安易にスーパークラスを使うと後で後悔することになります。

どんなときにクラス継承を使うか、インターフェースを使うかなどを指南するものの一つとして、「デザインパターン」というテクニック集が存在します。このシリーズの中でも紹介して行きたく思います。

多態性(ポリモーフィズム)

「多態性」とは聞き慣れないキーワードですね。しかし、これこそが、オブジェクト指向の真髄なのです。しかも、既にあなたはこのテクニックを使っています!

先程の例で、SoundsMakerインターフェースを使った例でも、Animalスーパークラスを使った例でも、どちらでも結構です。

あるところに

SoundsMaker m;

という変数がありました。そして、紆余曲折を経てmには何か値が代入されています。その後

m.makeSounds();

と書いてあったとします。実行結果は次のうちどれでしょうか?

  • ニャー
  • ワン
  • ブヒー
  • モー
  • ???

正解は「わからない」です。

インターフェース版鳴け!?

引っかけでごめんなさい。そうなのです。その時点で、どのように動くのか、実行してみないと分からないという柔軟なプログラミングが出来るのです。これが出来ると、プログラミングが大変便利になります。

とにかく「鳴く」ことが出来るものを(実際にどんな鳴き声かは気にせず)一緒くたに全部束ねてプログラミングしておいて、後から「鳴く」何かを当てはめるというプログラミング手法が実際には非常によく行われます。

そうすれば、たったひとつのプログラムで何通りものプログラムが作れてしまうからです。

インラインサブクラス

ここまで読めたあなたはもうオブジェクト指向マスター一歩手前です。(おめでとうございます!パチパチ)

最後に、先ほどの多態性を超強力に使えるプログラミングテクニックを紹介します。

ここまでの復習でオブジェクトとは何かを振り返ってみましょう

  • オブジェクトの設計図として、クラスを定義する
  • クラスはメソッドとフィールドを持つ
  • クラスはインターフェースまたは別のクラスを「継承」することができる
  • 継承元のインターフェースやクラスを型とした変数には、「継承」先のサブクラスのインスタンスを代入することができる

ここで「継承先のサブクラス」というのは、実は、いつでも作ることができます。いちいち、javaファイルを作って、名前を決めてextendsって書いたりせずに、欲しくなったらいきなり書いてしまうことが出来るのです。

先ほどの、SoundsMakerインターフェースを使った例を元に話を進めますね。

SoundsMaker s = new SoundsMaker() {
    public void makeSounds() {
        System.out.println("ぎゃああああああ");
    }
};
makeSounds(s);

実行結果

きゃああああああ

こんな風にいきなりプログラムの途中に作られたクラスを、「インラインサブクラス」と呼びます。この技はインターフェースに対しても、スーパークラスに対しても使用可能です。

なぜこんなテクニックが必要かというと、名前を決めることが結構大変だからです。親になった気持ちになってください。その子の名前をいい加減に決められますか?その子の将来がかかっているので、他人から見て変じゃないかとか、縁起が良いかとか、あれこれ考えてようやく名前が決まります。

プログラミングしていて圧倒的に多くの時間を費やすのが「名前決め」です。ですから、一度しか使わないような子には、名前を与えずいきなり使ってしまえば良いのです。(笑)

変数すら省略できる

オブジェクトインスタンスは変数に格納すると書きました。しかし、その場で一回だけ使えば良いなら、なにも変数すらも使わなくても良いのです。

new Cat().makeSounds()

実行結果

ニャー

これらの技を組み合わせると、こんなコードも書けてしまいます。

new SoundsMaker() {
    void makeSounds() {
        System.out.println("ぎょええ~~~")
    }
}.makeSounds();

分かりますか?「ぎょええ~~~」と鳴くモノを作って、その場で鳴かせているのです。

なぜこんなことを書いたかというと、次回以降で多用するからです。

]]>
https://susumuishigami.github.io/susumuisinfo/?feed=rss2&p=1693 0
テンプレートエンジンMayaaについて知りたいすべての人へ https://susumuishigami.github.io/susumuisinfo/entry/2015/mayaa_advent25 https://susumuishigami.github.io/susumuisinfo/entry/2015/mayaa_advent25#respond Fri, 25 Dec 2015 09:52:58 +0000 http://www.susumuis.info/?p=1676 これは Mayaa Advent Calendar 2015 の25日目です。昨日は「Mayaaソースコードの読み方」でした。

マヤー(メリー)・クリスマス!

今日はクリスマスです!Mayaaアドベントカレンダーは本日が最終日です。

結局最後まで一人で書きました。はじめは心細く、4,5日目あたりが一番つらかったです。今日まで続けてこれたのは、TwitterやFecebookで「いいね」をしてくれたり、リアルで応援をしてくれた皆さんのお陰です。

ここまでを振り返って

Mayaaアドベントカレンダーを通じて、自分の持っているMayaaのノウハウを放出することで、世界で一番詳しいMayaaのノウハウ集をアウトプットしようと考えていました。

振り返ってみると、コーディングルールだったり、フレームワークとの連携だったり、拡張方法だったり、教育や、ソースコードの読み方など、本当にあらゆることを書けました。

そこで、今日はここまで書いたこと、及び、公式ドキュメントや、このブログの過去の記事、別の方の記事などをインデックス化することで、Mayaaについて調べる時のポータルページを作りたいと思います。

この、世界一詳しいMayaaのノウハウ集を、皆さんへの本当のクリスマスプレゼントとして捧げたいと思います。

Mayaaとは何か知りたい

プログラマー向け

Mayaaの使い方を覚えたい

アーキテクト・上級プログラマー向け

ここから先は、Mayaaをどのように活用するかという話になります。

Mayaaを拡張・チューニングしたい、トラブルシューティングしたい

プロジェクトマネージャ、リーダー向け

Mayaaを使ったプロジェクト運営論

豆知識系

まとめ

25日間お疲れ様でした。
いかがでしたでしょうか?

ブログを毎日書くのは初めての体験で雑なところなどもあったと思います。半ば書ければいいやなどの投げやりな気持ちも1mmくらいはあったと思います。

しかし、今時派手ではない、テンプレートエンジンのノウハウはこうでもしないとアウトプットされないでしょうから、この機会があって良かったと思います。

今後僕は、あらゆる場面でこのアドベントカレンダーの一覧の記事を活用していこうと思います。その際にあらに気づいたら自ら直して行くことでしょう。

つまり、世界一詳しいMayaaノウハウ集づくりは、ここが起点なのです。Mayaaが続く限り、将来にわたってこれらの記事をメンテし続けることを約束します。

それではみなさん、メリークリスマス、そして良いお年を!

]]>
https://susumuishigami.github.io/susumuisinfo/?feed=rss2&p=1676 0
Mayaaソースコードの読み方 https://susumuishigami.github.io/susumuisinfo/entry/2015/mayaa_advent24 https://susumuishigami.github.io/susumuisinfo/entry/2015/mayaa_advent24#respond Wed, 23 Dec 2015 15:52:47 +0000 http://www.susumuis.info/?p=1667 これは Mayaa Advent Calendar 2015 の24日目です。昨日は「Mayaaの学び方・教え方」でした。

今日はクリスマスイブです!リア充が爆発している中、硬派な皆さんはMayaaアドベントカレンダーを読んでくださりありがとうございます。

クリスマスプレゼントとして、今日は徹底的にガチなことを書きます。

Mayaaのソースコードの読み方

MayaaのソースコードはGitHubにあります。

さて、git cloneで落としましたか?

今日はこいつの読み方を説明します。準備は良いでしょうか?

プロジェクト構成を眺める

プロジェクトフォルダをざっと見ると、

  • src-api
  • src-impl

2つのフォルダがあります。僕はこのようなフォルダ構成はMayaaしか知りません。試しにGoogleで「src-impl」と打ち込むと、Mayaaのソースが出てくるからMayaaの独特の構成かもしれません。

contect フォルダはライセンス情報や依存ライブラリ、Webアプリとして単体起動させるための設定情報などがあるだけで、ライブラリとしてあまり重要なものはありませんので、コードリーディング時は無視してよいです。

src-apiでAPI構成を知る

src-apiにはinterfaceが定義されています。つまり、src-apiに存在するインターフェースは何らかの方法で実装を交換可能になっているということです。

実装が交換可能ということは、独立した部品とみなされていると言って良いです。つまり、src-apiをざっと見れば、Mayaaがどんな部品によって構成されているかを知ることが出来ます。

パッケージ階層を見ると次のような構成であることが分かります。

  • builder
  • cycle
  • engine
  • provider
  • source

Mayaa内部の用語なので、これだけ見ても、最初は慣れないと思いますが、そこで、Mayaaの処理する流れをざっと説明します。

engineはMayaa中心で起点と考えてよいです。

engineの中は、processorと、specificationに分かれます。specificationはmayaaファイルやテンプレートの定義情報をモデル化したものです。processorは、テンプレートエンジンがそのノードをどのように処理するかをオブジェクト化したものです。つまり、specificationによって組み立てられたprocessorがあればMayaaエンジンはHTMLを出力することが出来ます。

providerはアプリケーションスコープのリソースです。エンジンの設定や、各インターフェースの実装クラスの選択はここが担当します。そのため、Mayaaの設定はorg.seasar.mayaa.provider.ServiceProviderなのです。

sourceは、mayaaファイルやhtmlテンプレートなどユーザーが作成するソースファイルを抽象化しています。他のインターフェースに依存しませんが、実装上は、ビルド時にほぼ必ず使用します。

cycleは、リクエスト処理のコンテキストを扱います。リクエスト・レスポンス、現在処理中のノードといったスレッドローカルなコンテキストはここに格納されていきます。

builderは(主にsourceを元にして)SpecificationNodeを組み立てます。

Mayaaの構成

つまり、provider, cycleは事実上Engineを動かすのに必要ですが、何らかの方法でspecification/processorが構成できてしまえば、builder, sourceは切り離せるとも言えます。

継承の起点としてのインターフェースを理解する

次に、クラス階層から実装の作法を理解してみましょう。

こんなクラスが実装の起点に存在しています。

  • PositionAware

    • NodeTreeWalker
    • ParameterAware
  • ContextAware
  • UnifiedFactory

これらをざっと眺めておくと後々実装を追いやすくなります。

実装クラスの起点はMayaaServletから

なんだかんだ言っても実装はMayaaServletから追い始めるのがベターです。

MayaaServlet#doServiceで、Cycleを初期化し、ProviderからEngineを取得して実行しているのが分かります。

EngineImpl#doServiceを追って行くと、EngineImpl#doPageServiceという大きなメソッドに行き着きます。ここが、一リクエスト分のレンダリング処理の主要部分です。ここを起点に、テンプレートの情報を取得し、各部品を実行することで、結果としてのHTML文書が出力しされます。

大枠を理解できたら後は部品ごとの設計を理解する

例えば、SourceDescriptorは内部でCompositeパターンになっています。Processorを理解するには、TemplateProcessorSupportという巨大なクラスの機能を理解する必要があるでしょう。

また、Rhinoスクリプティング機能は、cycle.script.rhino内に収められています。したがって、これと同等の部品を実装して、独自のCompiledScriptが実装ができれば、スクリプトエンジンをRhino以外に切り替えることもできます。

まとめ

Mayaaのソースコードは、各部品の独立性と抽象度が高く設計されています。このため、全体を各部品に切り離して考えることが出来、一部分を拡張したり、変更することが行いやすくなっています。

FactoryFactoryがある時点で、DIコンテナが普及する以前の香りがしますね。Seasarプロジェクトと言いながらSeasarに依存しないのは、このように独自にフレームワークを作っているからなのです!また、今回は触れませんでしたが、内部には、GCの管理や、シリアライザーをガリガリいじったり、相当低レベルのこともしています。(それらを読んでいるととても勉強になります)

こういった低レベルな部分がソースを膨らませているとも言えます。何も知らないで読むと、溺れてしまいそうです。しかし、フレームワーク的なところ、低レベル過ぎるところは一旦置いておくと、読むべき範囲は限定されてきます。

ソースコードを読む動機というのは様々で、拡張したい時の他に、トラブルシューティングをするとき、パフォーマンスチューニングしたい時などいろいろあると思いますが、その時必要な範囲で読めるように、普段から慣れておけば、そんなに怖いものではありません。

]]>
https://susumuishigami.github.io/susumuisinfo/?feed=rss2&p=1667 0
Mayaaの学び方・教え方 https://susumuishigami.github.io/susumuisinfo/entry/2015/mayaa_advent23 https://susumuishigami.github.io/susumuisinfo/entry/2015/mayaa_advent23#respond Wed, 23 Dec 2015 10:19:26 +0000 http://www.susumuis.info/?p=1664 これは Mayaa Advent Calendar 2015 の23日目です。昨日は「Mayaaの経験を活かして、JSPを注意して使う方法」でした。

あと3日です!

明日はクリスマスイブ、今日は天皇誕生日、一気に年の瀬な感じです。皆さん、年賀状は書きましたか?まだの方は、年賀状ソフトをネット販売で買いましょう。私の勤務先のお客様です。w

ちなみに僕は5年以上年賀状を書いていません。

もし、プログラマー初案件がMayaaだったら

今日のテーマは教育です。プログラミングは学校で習った程度で、Servletとか作るのは初めてな感じの新卒が、Mayaaを使っているチームに配属されたとします。

経験者なら良いんです。
Mayaaの公式ドキュメントを読んでください。その後、僕のブログで、このアドベントカレンダーの1日目から7日目を読んでくれれば良いんです。

JSP、Thymeleaf、JSF、Mixer2を経験しているなら、17日目から21日目も読んでおくと理解の助けになるでしょう。

後の記事はアーキテクトやリーダープログラマー向けなので、ぶっちゃけ読まなくてもいいです。(笑)

さて、本当にど初心者が入ってしまったらどうでしょうか?「JSPでは〜」というのが言えなくなります。

とりあえず、JSPを理解してもらう。

最近はフレームワークでドーンと最初から統合されたシステム作りをするのが主流だと思いますが、MayaaはJSPと同じレイヤーにするために、そのものはシンプルでもないのですが、JSPを覚えておく必要はあります。

昔だったらStrutsを使ってMVCにしても良かったのですが、今はSpringとかJava EEのような重量級をいきなり使うのはきついので、いっそ、生のServletとJSPでページを構成する体験をしてもらうしかないのかなと思います。

いしがみメソッドの4種類それぞれを実装してもらう

Mayaaそのものは柔軟性のある技術ですが、実際のプロジェクトでは、デザイナーと協調するために、いしがみメソッドでは、4種類の書き方に限定することを提唱していました。

しっかりと、4種類だけに限定して書く癖をつけてもらいましょう。

3日目から引用すると、

  • *_HERE

    • その場所に文字列を出力する
  • *_TAG

    • そのタグの属性を変化させたり要素を足したりする
  • IF_*

    • そのタグ及びその子要素が特定の条件にもとづいて消える
  • LOOP_*

    • そのタグ及びその子要素を特定の条件に基づいて繰り返す

そして、それぞれの書き方は

<!-- タイトルを出力します -->
<m:write m:id="TITLE_HERE" value="${page.getTitle()}" />
<!-- 商品画像を表示します。src属性を制御します -->
<m:echo m:id="ITEM_IMAGE_TAG">
  <m:attribute name="src" value="${image.getSrc()}" />
</m:echo>

```markup
<m:if m:id="IF_MEMBER" test=${context.isMember()}>
  <m:echo><m:doBody /></m:echo>
</m:if>
```markup <m:forEach m:id="LOOP_ITEM" items=${items}> <m:echo><m:doBody /></m:echo> </m:if>

きちんとレビューをしてこの通りに書いていなかったら直させるようにしましょう。

これらを書くことは業務の中で圧倒的に多いことです。

まとめ

使い方を絞ったことによって、教える時も絞って教えられるメリットがあります。

ただ、教え方は人それぞれ、教わる方も、それぞれ向いたやり方は違いますので、「これがベストだ」とは言いづらいところがあります。

なので、今回は歯切れが悪くなってしまいますが、まあ、適宜、教育する人、教わる人で、良く話して、ベストなやり方を模索してください。

]]>
https://susumuishigami.github.io/susumuisinfo/?feed=rss2&p=1664 0