沖縄のプログラマーコミュニティ「Java Küche」の会長をさせて頂くことになりました。

2017年10月7日に行われたイベント「いま注目のMicrosoft最新テクノロジーをキャッチアップ ~ Azure、Cognitive Services、Xamarin ~ - Java Küche | Doorkeeper」の中でも報告させていただきましたが、沖縄のプログラマコミュニティ「Java Küche」の会長をさせて頂くことになりました。

Java Kücheは2006年7月から続く歴史あるコミュニティで、僕で4代目の会長になります^^

これから一年、他の役員の皆さんに支えてもらいながら、いままで繋いできたコミュニティの文化を継続させつつ、さらに沖縄のエンジニアの皆さんが楽しく、そして何より自分自身が楽しめるようなコミュニティ活動をしていきたいと思いますのでどうぞ宜しくお願い致します!

「いま注目のMicrosoft最新テクノロジーをキャッチアップ ~ Azure、Cognitive Services、Xamarin ~」というイベントで企画運営・登壇をしてきました。

2017年10月7日(土)にJava Küche主催の「いま注目のMicrosoft最新テクノロジーをキャッチアップ ~ Azure、Cognitive Services、Xamarin ~」と題した勉強会を企画運営し、登壇もしてきました。

java-kuche.doorkeeper.jp

なぜMicrosoftテクノロジーに関する勉強会を開いたのか?

Java Kücheというコミュニティでは1年に1回、自分たちの活動内容や予算をどのように使ったのか、そして次の一年をどのように活動するのかというに報告をコミュニティに行う「総会」というイベントを行うのですが、そのイベント時に一緒にどのような勉強会をしたいかというアイディア出しを行いました。

そのときに、近年のMicrosoftが発表してきた様々の技術についての興味があるがキャッチアップできるような勉強会が沖縄だとないことや、つい最近からXamarinやAzureなどのMicrosoftテクノロジーを仕事に使い始めたメンバーがいたことから、じゃあ自分たちでキャッチアップするための勉強会を開催しようと企画をしました。

イベント内容について

Microsoftのすべてのテクノロジーを網羅することは難しいため、Webアプリケーションを乗せるPaaSとしてAzure、様々なAI・機械学習の技術がサービスとして提供され気軽に利用できるCognitive Services、AndroidiOSのモバイルアプリをC#で両方同時に開発することができるXamarinの3つに絞ってセッションを用意しました。

登壇者にはエクセルソフトセールスエンジニアでXamarinコミュニティJXUG主宰でもある田淵 義人さん、日本マイクロソフト株式会社のテクニカルエバンジェリストの大森 彩子さんのお二人にわざわざ沖縄まで来ていただきました。

そしてAzureについては仕事でAzureを採用しているぼくが登壇させて頂きました。

Xamarin概要と活用方法

田淵さんの発表では、Xamarinが使われている事例やそもそものXamarinがどういうテクノロジーなのか、そしてXamarinの使い所などを話して頂きました。

個人的にはXamarin.FormsとXamarin.iOS / Xamarin.Androidとの使い分けのポイントが知れたのが良くて、やっぱりXamarin.Formsでサクッとクロスプラットフォームアプリが作れるときがXamarinの力が発揮できるユースケースなんだろうなと思いました。

はじめてのAzure App Service for linux と Web App for Containers

www.evernote.com

次は僕が「はじめてのAzure App Service for linux と Web App for Containers」という題名で登壇させていただきました。

今年の9月に公式版となったAzure App Service for linuxとWeb App for Containersについての概要と実際にAzureの管理画面を使いながらWeb App for Containersのアプリをデプロイしていくデモを行いました。

デモを選んだ理由ですが、沖縄県内のクラウド事情はAWSが一番多く、一部GoogleCloudPlatformを使っている方もおられるのですがAzureを採用している事例を聞いたことがなかったので、この機会に管理画面の使い方やAzure独自の概念についての説明を実際に動くデモを通してお伝えしたいと考えたからです。

実際に会場にいらしたら方はAzureを使っている方は32人中2~3人程度で、実際のデモを見せる事ができてよかったな〜と思います。 一部デモが動かないところがあって大成功とはいえないですが。。。^^;
次回また頑張ります。

AIを手軽に使える時代がやってきた!"人工知能パーツ" Congnitive Services 入門

大森さんの発表では、Cognitive Servicesで作られたアプリケーションのデモから、そもそも誤解されがちなAIとは何ぞやという話、そして多種多様なCognitive Servicesの紹介や利用例などを説明していただきました。

AIというと「たくさんデータをいれたら良い感じの答えを出してくれるすごいやつでしょ?」という勘違いをしてしまいがちだったんですが、AIの定義の正しい説明をしっかり説明していただき、ちゃんと理解をすることができたので面白かったです。

あとなによりも、AI時代の開発者のあり方「#早く面白いことやったヤツが優勝」というパワーワードを頂いたので、僕もCognitive Servicesを触ってみておもろいものを作っていきたいと思います^^*

さいごに

わざわざ沖縄まで講師としてやってきていただいた田淵さん、大森さんほんとにありがとうございました!!

沖縄に限らず地方だとどうしても技術の多様性が乏しく、今回のようなMicrosoftテクノロジーに精通した話を聞く機会が少なかったのでお二人にこのような機会をつくって頂けたのはとてもありがたかったです!

また、イベントに参加して頂いた方もありがとうございました!

これからも沖縄ではなかなか話をする機会が少ない登壇者をお招きして、沖縄にいるエンジニアがまず楽しく、そしてスキル上達の手助けにもなるイベントを企画していきたいと思いますのでどうぞ宜しくお願いします!

Webアプリケーションプログラムにおいて、「良いコードを書く」ための基本的な方針

自分はフレームワークを用いてWebアプリを書くことが多いのですが、その上で可能限り「良いコード」を書くように心がけています。

ただ、この「良いコード」というのがかなりの曲者で、プログラミングにおいてのイディオム的なことからオブジェクト指向の話、デザインパターンプログラミング言語においてのベストプラクティス、使用しているフレームワークのベストプラクティス、さらに広げるとドメイン駆動設計の話までかなり広い範囲が含まれてしまいます。

チームによっての技術レベルや目標としているものはもちろん違うので、基本的には現場現場で話し合って自分達の目指す「良いコード」を定義することが重要になるでしょう。

今回はMCVフレームワークを使ってWebアプリケーションを良いコードで書く上で、どの現場でも理解できて、かつ実践できるであろう私の頭にある「良いコードを書く」ための基本的な方針をまとめてみました。

まとめる上で、出来る限りオブジェクト指向エンタープライズアーキテクチャなどの用語を使わないように意識しています。

特に真新しいことはなにもなく、当たり前になっているとは思いますが、自分の頭の中を吐き出すためにこのブログを使おうかと。

基本的な方針

1.やっていることが違うコードは分離して名前をつける

管理画面などをMVCフレームワークで開発をしていてたまーにあるのが、おなじURLにPOSTされていても送信されてくるデータによって新規作成になったり、更新になったり、または違うテーブルのデータを更新する処理にかわったりすることです。これは管理画面を作る際に関連のある2つのテーブルのデータをユーザビリティのために一つの画面で更新できるようにした場合に発生します。

この時に愚直にコントローラー内の一つのアクションにすべての処理を書いていくと、コードが長くなりますし不用意に別の役割をしているコードに依存した処理を書いてしまいバグの温床になることがあります。

出来るだけ違うことをおこなうアクションは別にする。 もしUX上別に出来ない事がある場合はおなじアクションを叩くにしても内部上では別のメソッドを分離して、そのメソッドに処理を行わせるようにしています。

もちろんこれはコントローラーだけではなく、その他のプログラムにおいても同じです。

分離したメソッド名を適切な名前にすると、その名前をみるだけで何をしているのかわかるので可読性も上がります。

2. どこに責任を持たせるのかを決める

例えば商品を表現するDBのテーブルproductsがあり、各商品の識別子(ID)は企業名を表すアルファベット二文字(PKやITなど)とインクリメンタルの数値の8桁でないといけないというルールがあるとする。

そのようなルールがあったときに、商品の作成処理をおこなうControllerで毎回ID作成のためのロジックを書くのはコードの重複が増える上にプログラマーがルールを常に覚えていないといけないため問題です。

その問題を避けるため、商品の識別子を作成するためのメソッドを定義し、商品識別子の作成ロジックの責任はこのメソッドのみに持たせます。

責任を持たせるメソッドを定義することによりコードの重複が減り、かつビジネス上のルールをコードで表現することで可読性が上がります。

3. Web以外のインターフェースがあることを意識する

Webアプリケーション開発においてMVCフレームワークを使って開発をしているとき、注意をせずに開発をすると重要なビジネスロジックがコントローラー側に漏れていく事が多くあります。しかしControllerはWebのRequestとResponseが交わる場所になるので、ここにビジネスロジックを書くとWebのRequestとResponseに依存したプログラムになってしまいがちです。

そんなときに困るのが、同じような機能を提供する別の画面を作ったり、WebのUIではなくWebAPIを作ったり、またはコマンドラインのタスクを作ったりなど別のインターフェースから同一の機能を提供しようとしたときに、ロジックを抽出するのが難しくなってしまいます。

そのため、重要なビジネスロジックを書くときには常に今のUIとは別のUI・インターフェースから使われるときのことも意識し、Controllerから分離してコードを書きます。

4. 小さなプログラムを組み合わせて大きなプログラムを書く

大きなプロダクト一塊にして書くよりも小さなプログラムを作って細かく分割し、それを組み合わせて大きな機能を作ります。

そうすることで依存性も低く再利用性も高い小さいなコード群がたくさん生まれ、別の機能を作るときにそれらのコードを使ってより早く開発することができます。

おわりに

もちろん上記以外にも考えることは多いのですが、私が特に意識しているのがこの4つです。

こういうのを「単一責任の法則」的な法則名で意思疎通できると、話は早いんだろうなー。

PHPのループで書くと約30時間かかる大量の画像アップロード処理を、Clojureのcore.asyncで1時間以下に短縮できた話。

1つのVPSで動いている既存システムのAzureへの移行を進めています。

その上で既存サーバーに入っている画像ファイルをBLOBストレージ(Azureのオブジェクトストレージ、AWSでいうS3)に移すという作業が必要になりました。

最初はバックアップから画像ファイルをループでひとつづつアップロードする処理をPHPでシンプルに書きました。

require_once 'vendor/autoload.php';

use WindowsAzure\Common\ServicesBuilder;
use MicrosoftAzure\Storage\Common\ServiceException;

// Create blob REST proxy.
$connectionString = "";
$blobRestProxy = ServicesBuilder::getInstance()->createBlobService($connectionString);

// imagesディレクトリから画像ファイルを取得
$images = getImagesFromDirectory('images');

 foreach($files as $file){
        $blob_name =  $path = "images/".$file;
        try {
            $content = fopen($path, "r");
            $blobRestProxy->createBlockBlob('imgcontainer', $blob_name, $content);
        }catch(Exception $e){
            echo "Exception Occers: ".$path;
            echo "\n";
            $code = $e->getCode();
            $error_message = $e->getMessage();
            echo $code.": ".$error_message."\n";
        }
}

最初は100枚だけで試してみたんですが、100枚をアップロードするだけで50秒ほどの時間がかかりました。 ただ画像ファイルはその時点で約23万枚ほどあり、単純計算でざっくり30時間ぐらいかかるとわかりました。

つらい。。。

30時間はつらい。。。

覚悟を決めて30時間ぶん回ししてもよかったのですが、「もし間違いがあった場合にまた30時間やるの辛い」 、「画像はいまも増えていくので再アップロードも必要になる」という理由から、なんとかもっと速く終わるようにプログラムを変えることにしました。

PHPは基本同期処理のプログラムなので、上記のやり方だとファイルアップロードの待ち時間の間処理が止まってしまいます。 その待ち時間がボトルネックだということは目に見えていたので、複数プロセス、非同期処理に変えてアップロードの待ち時間もバンバン他のファイルをアップロードするように変えれば確実に速くなります。

PHPでそのような処理を書く方法もあると思いますが、Clojureという言語のcore.asyncを使うと簡単に実装できるということを知っていたのでClojureで実装し直すことにしました。

core.asyncとは、Clojureで並行プログラミングをするときによく使われるライブラリです。 協調スレッドという軽量なスレッド(ネイティブスレッドではない)を作り、channel経由でスレッド間の通信を安全に行い非同期処理を行うプログラムを書くことができます。

golangを使ったことがある人には、goroutineと同じようなものだと考えるとわかりやすいと思います。

今回の画像アップロード処理をClojureのcore.asyncで書き直すと以下のようになりました。

(ns azure-storage-clj.core
  (:require [clojure.java.io :as io]
            [clojure.core.async :as as
             :refer [>! <! >!! <!! go chan buffer go-loop
                     close! thread alts! alts!! timeout]]
            [clojure.tools.logging :as log])
  (:import [com.microsoft.azure.storage CloudStorageAccount]))

(def connection-str "")

(def storage-account (CloudStorageAccount/parse connection-str))

(def blob-client (.createCloudBlobClient storage-account))

(def blob-container (.getContainerReference blob-client "imgcontainer"))

// 画像を置いてあるディレクトリ以下からファイルだけを取得する
(def filelist (filter #(.isFile %)
                      (file-seq (io/file "resources/images"))))

(defn image-upload [file]
  (let [f-source file
        filename (.getName file)
        blob (.getBlockBlobReference blob-container (str "images" "/" filename))]
    (.upload blob
             (new java.io.FileInputStream f-source)
             (.length f-source))))

(defn files-upload []
  (let [file-chan (chan 100) ;; バッファ100のチャネルをつくる] 
    ;; チャネルからファイルをとり、アップロードする協調スレッドを100個つくる
    (doseq [n (range 100)]
      (go-loop []
        (let [f (<! file-chan)]
          (do
            (log/debug "image-upload : " f) // ログ出力
            (image-upload f))) ;; 画像アップロード
        (recur)))
    ;; 画像ファイルのリストをひたすらチャネルに入れていく
    (for [f filelist]
      (>!! file-chan f))))

処理は以下のようなイメージです。

f:id:arakaji-yuu:20170524091829p:plain

この実装を朝の4時くらい起きて実装し、100枚、500枚と試してみて大分速くなることは確認できたので、 一気に全ファイル対象にして実行して二度寝へと向かいました(それが5時ごろ)。

7時くらいに目が覚めてPCの様子を伺うと、なんともう完了しているではありませんか。。。

ログを見ると約1時間程度で終わっていたようです。

感無量。。。。

Clojureを使うことで並行処理を簡単に実現できて、結果タスクにかかる時間も短縮できました。 やはりいろんなパラダイムの言語を知っておくとその時々の問題にあった手段を選べるのでいいですね。

第10回 Apache Cordova勉強会 @ Sony City Osakiに参加してきました!

今日は別件でアポがあって東京出張に来ていたのですが、上手くスケジュールが重なって(というか重ねて) 第10回 Apache Cordova勉強会 に参加してきました。

アシアル株式会社の田中さんによる「Vue 2についての発表(仮)」にはじまり、(株)ジェイアイエヌの佐藤さんによる「WEBエンジニアの可能性を広げるJINS MEMEのアプリ開発」、最後にソニーネットワークコミュニケーションズ㈱ の緒方さんによる「Cordova を使って本気で商用ハイブリッドアプリケーション開発をやってみた」という発表をして、その後に懇親会という流れでイベントは進みました。

みなさん興味深いお話をして頂きとても楽しかったのですが、個人的に一番インパクトがあったのが緒方さんよる発表で、開発したアプリを見せて頂いたのでしたがUI/UX、アニメショーンの動きなどがとてもハイブリッドアプリで作ったとは思えない程の完成度でとても衝撃を受けました。

Cordova使ったハイブリッドアプリの開発者なら誰もが「ハイブリッドアプリだからネイティブアプリのような体験は作れない」と諦めてしまいがちですが、「ユーザーにはネイティブもハイブリッドも関係ない、ユーザーの期待値はネイティブ」、「ハイブリッドアプリのメリットはネイティブをそれぞれ作る以上の生産性、そこを失ってはいけない」とクオリティと生産性を両立させるための高い基準を設定し、それを達成するために行ったさまざま工夫やノウハウを今回の発表や懇親会でのコミュケーションを通して共有して頂きました。

スケジュール、技術的制約、高い達成基準などがあるなかでしっかりとそれを達成するために開発に向き合う姿勢はエンジニアとして尊敬するとともに、現在のモバイルアプリの環境であればネイティブにも遜色ないUXをCordovaでも作れるという可能性を見せて頂けたとても良い会になりました。

Cordovaを使ったハイブリッドアプリ開発、がんばろ!!

2017年3月1日をもって、琉球インタラクティブからPayke(ペイク)に転職しました

2017年2月28日を持って4年間働いていた琉球インタラクティブを卒業し、Paykeに転職しました。 沖縄のネット系ベンチャーから沖縄のアプリ系スタートアップへの転職という形になります。

前職について

初めてプログラマーとして職をついたのがこの会社だったのですが、ECサイト、公共施設の予約システム、WordPressを使ったサイト構築、エンジニア向けイベント情報サービスの機能開発や沖縄の求人サービスの開発など様々なWebサービス開発にメインのエンジニアとして入る事ができ技術力をとても鍛える事ができました。

また最後の1年半はバイトや外部パートナー含めて最大10名のエンジニアチームのマネジャーも経験させて頂きました。

ベンチャー特有の急激な環境の変化や無茶振り、抜擢人事などはいろんな意味で大変なことも多いですが、 たとえ問題が起きても誰か一人の責任にせずに、誰もが協力して問題解決に取り組む文化、 プロセスは担当者に任せて結果重視で評価することで、様々なプロセスを担当者レベルでどんどん改善出来る文化、 結果を出している人は報酬やランクアップを通して積極的に評価する文化などは 自分のこれからのキャリアを作る上での大事な下地になったともに、個人的にとても働きやすい会社でした。

最終出社日の記念写真 f:id:arakaji-yuu:20170309114130j:plain

自分は新たなチャレンジのために卒業しましたが、もし沖縄でもベンチャーの荒波に揉まれてジェットコースターのようなキャリアを歩みたいという方はぜひ琉球インタラクティブのリクルートを覗いてみて下さい^^*

なぜPaykeに転職したのか

自分のエンジニアとしてスキルやキャリアを高めるために新たな環境に身をおきたいと思い、半年程かけて転職活動を粛々として行っていまして、その間様々なベンチャー企業やスタートアップから声をかけていただきました。

どの会社も非常に優秀なエンジニアが揃っていたりとても魅力的なプロダクトが揃っていたのですが、Paykeを選んだ理由が一番課題や可能性が多くておもしろいと感じたからです。

Paykeのサービスはアプリでバーコードをスキャンすると、その商品情報が多言語で閲覧できるというインバウンド向けサービスなのですが、 メインのユーザーが訪日外国人であるためいつも自分が使うアプリとは違う視点で考えて開発しないといけないことや、 大量のスキャンデータや商品情報を扱うためのデータ分析基盤を作ること、 スキャンして表示する商品情報の数が数百~数千万、または億まで行ったときに出来ることや スキャン時得られる商品情報をよりユーザーに最適化した情報を出せるようにすることなど、 現時点で様々な課題と可能性があり、そこにエンジニアとして挑戦することに強い魅力を感じてJoinすることに決めました。

自分の技術力を高めてプロダクトに反映し、機会があればその経験をシェアしていきたいと思います。 今後ともよろしくお願いします。

オフィスの風景

f:id:arakaji-yuu:20170307193608j:plain

初出社日の満面の笑み

f:id:arakaji-yuu:20170301110039j:plain

受託開発は狩り、自社サービス開発は稲作

昨日ふと思っただけなんですが、受託開発は狩りっぽくて自社サービスは稲作っぽいなと。

受託開発がメインの場合は狩りをしている感覚で、自分の獲物がたくさんいる領域を探したり、大きな獲物を数多く確実に捕らえられるように牙を磨いている。大きな狩りに成功すればしばらくは安泰ですが、しっかり次の獲物を探しておかないといけないので、ずっと研ぎ澄ましている感じ。

自社サービスがメインの場合は稲作している感覚で、実りが出るまでは辛いんだけど実りが出るようになれば安定的に食料にありつけるようになる。ひとつの稲作に成功したらそれである程度食料は確保できるので、今度は違う種類の食材に挑戦したり、より大きく収穫できるように工夫していく。

なんでそんなことを思ったかというと、ただ偶然にYouTubeでレキシっていう人の「狩りから稲作へ」っていう曲を聞いたからなんですが。


狩りから稲作へ

あ、特に結論のようなものはないですよ?