Flash

お正月にやるつもりだった,RESTful Web サービスやら Windows Live ID やらは停滞気味(はてしなく放置気味).いまは何故か,Flash なんかをやってたり.

初めてのFlash Video

初めてのFlash Video

動画系は全く疎くて,swfってなに?みたいな状態からスタートです.昨日Flash CS3の体験版をダウンロードし,今日は第1章を打ち込んでました.慣れの問題が大きいのでしょうけど,Flash CS3のどのメニューにどの機能があるか,試行錯誤しながらやってます.
ちなみにそもそもの発端は,とある人からの質問,「swfファイルをsilverlightを使って再生できないの?」でした.現段階の見解としては,「そりゃ,無茶でしょー」なんですが,実際のところどうなんでしょうね.

人を動かす

最近仕事は管理がメインで,技術調査が全くはかどりません(言い訳).しかし,そうはいっても管理は大事なので,真剣にやってます.以前は管理者に対して誰でも出来そうな気がして,全くいいイメージを持っていなかったのですが,やってみると重責ですね.
一番大変なのは,やっぱり経営(?)戦略でしょうか?あまり詳しく書けないのですが,現在のクライアントとの契約形態に変更がありそうで,それにあわせてどういう戦略を練っていくか.競合他社との住み分け・差別化をどう図っていくか,みたいなことを考えてみたり.当然その中で弊社の売上目標をいかに達成していくか,そしてそれを来年度だけでなく,いかに継続させるか,そのための仕組みをどう作るのか,みたいなことを悶々と考えてたりします.
この業界では人の管理も,とても重要です.自分が主に管理しているSEチームは4名ですが,そのうち2名は退場することが決まっています.交代要員として1名が2月から参画していただいてますが,それでも1名足りない.SEは,誰でもなれるものではないし,技術力があれば出来るものでもありません.なにより,SEチーム内でうまくやっていけそうかというところが一番気になるので,めぼしい候補には自分が直接面接します.わずか数十分で人となりを判断するのは難しいのですが,最も大事な仕事の1つなので真剣に取り組んでいます.


さて,今日はそんな身の上話ではなく,2月から参画しているSEのこと.
この方は面接官として,会った瞬間に心の中で採用印を押していました.女性なんですが,コミュニケーションスキルが異常に高く,その場にいる人を惹きつける魅力があります.すごい人が現れたなと思いました.その勢いでクライアント面接も見事合格.実はクライアント面接も同席していたのですが,その面接では少し緊張していたらしく,彼女本来の実力が発揮できていないようでした.しかしそんなことはもろともせず,あとでクライアントに聞いてみた感じでは,やはり第一印象でクリアしてたようです.大物ですね.
一昨日,何気なくその人の所属会社のホームページを見たのですが,なんと彼女はその会社の広告塔として,ブログを掲載してました.昨年の八月くらいからスタートしているようですが,彼女自身の仕事に関する考え方や取り組みなどが赤裸々に書かれています.なんか,すごいなと.オレ負けてると,ちょっとへこみました.でもそのポジティブな文章から,少し元気をもらいました.元気のおすそ分け,どうもありがとうございました.
彼女の最近のエントリを見ると,彼女にとって新しく始まるプロジェクトに対し,とても期待・希望に満ちているようでした.期待を裏切らないようにしないといけませんね.いきなりのプレッシャーです.でも,こんな奇跡は今後ないかもしれないので,お互いに後悔しないように行動したいと思っています.

Windows Live ID

RESTful Webサービスを読んでて少し引っかかったのは,認証に関してでした.いくらSSL(HTTPS)を使用するとはいえ,Basic認証ってどうなの?と.自分は仕事で認証関連をテリトリーにしていることもあり,勉強用ではあってもBasic認証を実装する気にはなれませんでした.
http://msdn2.microsoft.com/en-us/library/bb404787.aspx
というか,前から気になってたんですよね.これを機会に調べたかった,というのが今回のモチベーションの50%以上を占めてたり.
Windows Live IDというのは,以前Passportと呼ばれていた認証技術の後継である,みたいなことが書かれています.特徴として,

  • 通常認証に必要なパスワードを自分のサイトで管理しなくてよい(Windows Liveの認証サーバに管理してもらう)
  • そのためパスワードを忘れたユーザに対するフォローとか,パスワードの強度・有効期限といったことを意識する必要がない
  • UIがWindows Liveっぽくて,ちょっとかっこいい(?)

他に,Large ScaleとかSecurityとかQuality of ServiceといったこともIntroductionには書いてあります(これらは自分自身で評価できないので紹介のみ).
そんなわけでこの3連休は,それらの調査と組み込みをしてました.が,現時点でまだ完成していません.結構いいところまでいってるとは思うんですけどね.残念...orz
それにしてもWindows Live ID,日本語情報が少なすぎですね.うまく組み込めたら,この日記で組み込み方を書きたいと思います.

ASP.NETでRESTful Webサービスを実装してみる

休暇が終わり時間が取りづらくなりましたが,ちびちびと実装を始めています.
題材はブログシステムです.

URL設計

URL設計ですが,とりあえずGET系でこんな感じで考えています。

  1. /home.aspx
  2. /{user}.aspx
  3. /{user}/{year}.aspx
  4. /{user}/{year}/{month}.aspx
  5. /{user}/{year}/{month}/{day}.aspx
  6. /{user}/{year}/{month}/{day}/{seq}.aspx

本当だったら拡張子の.aspxは付けたくないところですが,付けないとIISからaspnet_isapi.dllにルーティングしないはず(IIS 6.0の場合.IIS7については未調査)なので,とりあえず付けた形で考えます.
1でユーザの一覧を取得します.2だとユーザの書いたブログエントリのタイトル(とリンク)を新しい順に取得します.3から5までも同様に,年・月・日の単位でタイトル(とリンク)を新しい順に取得します.6だと,そのブログエントリのタイトルと本文(=ブログエントリ全体)を取得します.
更新系は,

  • 1のPOSTで,ユーザの作成
  • 2のPOSTで,ブログエントリの作成
  • 2のDELETEで,ユーザの削除
  • 6のPUTで,ブログエントリの更新
  • 6のDELETEで,ブログエントリの削除

といったところかな?とりあえず必要最小限で考えています.使いやすいかどうかは?ですが,とりあえずはhackableにはなっているんじゃないかなと思っています.

HTTPハンドラ

通常ASP.NETでページを作成する場合,例えばDefault.aspxというファイルとそのコードビハインドであるDefault.aspx.csというファイルを実装します.すると当たり前ですが,/Default.aspxというURLでアクセスした際に先ほど実装したコンテンツが表示されます.しかし今回のURL構造の場合,そのようなやり方で無限にファイルを実装することは出来ません.さらに,そもそもレスポンスが(X)HTMLとは限りません.XMLかもしれないしJSONかもしれない.なのでちょっとやり方を変える必要があります.
そこで今回はHTTPハンドラを使うことにしました.HTTPハンドラとは何か,を説明するのは自分には荷が重すぎるので止めることにしますが,知りたい人は「ASP.NETパイプライン」といった単語でググるとよいでしょう.
このあたりでブログシステムのアプリケーション構成を説明します.

  • MyBlogSite
  • MyBlogController
  • MyBlogDao

MyBlogSiteは通常のASP.NET Web Site,下2つはClass Library(DLL)です.DaoをModelと言い切ってしまえば,(まぁ)MVCアーキテクチャといってもよいかもしれません.しかし今回Siteの出番はほとんどありません.とりあえず当面は,web.configに以下の設定を加えておくだけです.

<httpHandlers>
  <add verb="*" path="*.aspx" type="MyBlogController.MyBlogHandler, MyBlogController"/>
</httpHandlers>

これで,拡張子が.aspxのファイルについて,MyBlogControllerアセンブリのMyBlogHandlerクラス(名前空間:MyBlogController)で処理できるようになります.
MyBlogHandler:

public class MyBlogHandler : IHttpHandler
{
  public bool IsReusable{ get { return true; } }

  public void ProcessRequest(HttpContext context)
  {
    IMyBlogCommand command = MyBlogCommandFactory.Make(context);
    command.Execute(context);
  }
}

ProcessRequestメソッドのなかで,今回やりたい事をやります.具体的には以下のようなことです.

  • URLとメソッド(GET/POST/PUT/DELETE)から,要求を取得する
  • 正しい要求であれば,要求に合った正しい表現を返す(メソッドによってはサーバの状態を更新)
  • 不正な要求であれば,適切なステータスコードを持ったレスポンスを返す

この最初の部分をCommandFactoryクラスが,2番目と3番目をCommandクラスが,それぞれ担います.
CommandFactory#Makeは要求を取得し,適切なCommandにディスパッチします.この実装をどうするかが腕の見せ所,なのですが,とりあえず現在はベタに書いてます.(なので,晒しません)
Commandクラスですが,1のGETはこんな感じです.(コメントも入れました)

internal class UserListCommand : IMyBlogCommand
{
  public void Execute(HttpContext context)
  {
    // ユーザテーブルからデータを取得.
    IUserDao userDao = UserDaoFactory.CreateInstance();
    DataTable data = userDao.GetUser();

    // data.WriteXmlでDataTableをXMLに変換.
    string xml = CommandUtility.DataTableToXmlString(data);

    // XML宣言<?xml version="1.0" encoding="utf-16"?>を削除.
    // これをしないと,最終出力時に,UTF-8に変換できないという
    // エラーが出るので暫定対処した.
    // 本当にXML宣言をとってよいのか,未調査.
    string result = CommandUtility.RemoveXmlDeclaration(xml);

    // XML形式で出力.
    // もし(X)HTMLで出力する場合は,ここでは処理せず
    // ViewであるSiteのaspxにURL Rewriting.
    // DaoのデータはHttpContextを使って引き渡す.
    context.Response.ContentType = "text/xml";
    context.Response.StatusCode = 200;
    context.Response.Write(result);
  }
}

ここもなにかしらパターン化されそうではあるのですが,いまはこのままです.
Daoは特に変わったことはしていません.(TableAdapterを使うもよし,DLINQを使うもよし……)
以上がキーとなるコンセプトです.


少し長くなったのでまとめると,HTTPハンドラによるシングルコントローラを作って,Viewは軽くする.その分コントローラが重くなるが,そこはプログラマの腕とセンスが問われるところ.設定ファイルを使うか,それともコードの自動生成をするか,あるいは規約で縛る(要求に制限を設ける)のか.ここから先は,いろいろ試行錯誤しながら考えていくことになりそうです.


さて,このまま先に進んでもよいのですが,その前に考えておきたいことがあります.
認証・許可制御をどうするか?これについて次回考えてみたいと思います.

RESTful Webサービス

読了.休み期間中という目標だったのですが,なんとかクリアできました.

RESTful Webサービス

RESTful Webサービス

これは自分にとってとてもいい本でした.これまでばらばらだった知識の断片が結びついていく,そんな感覚を味わいました.Web開発に携わっている人は必読だと思います.
自分は主にASP.NET/C#を業務で使用していますが,それらを使ってどのように設計・実装したらよいかと,そんなことばかり考えながら本を読んでました.アイデアがいろいろと浮かび,熱い血がこみ上げてきます.とりあえず今は,簡単なブログサービスを作り始めてます.この日記のネタにすることがあるかもしれませんね(あるいは全く日記の更新が止まるかもしれませんけど).
ところで,WCFの最新版(.NET Framework 3.5のもの)では,RESTサービスもサポートされてたような記憶があります.これもチェックする必要がありますね.

一年振り返って

得られたこと、よかったこと

  • JavaScriptの基礎を勉強した.オブジェクトの考え方が特殊で面白い.自分の中で引き出しが1つ増えた感じ?
  • WebサービスWCFについて,実際に調査・設計してみて勘所がつかめた.WFもちょっとだけ動かしてみた.
  • Setupプロジェクトの作り方が,だいたい分かった.
  • ちょっとだけ出世した.
  • 仕事に関しては,大きな事故もなく無事遂行できた.自分なりに業務改善を提案したりして,評価もまずまず……な気がする.
  • 引越し.いろいろと大変なこともあるけど(ローンとか),快適.

出来なかったこと(来年以降持ち越し)、わるかったこと

  • silverlight: 気になってはいるものの,まだ動かせていない.
  • Windows Service+MSMQ: 業務で使っているが設計がイマイチなのでフルスクラッチしたい.せっかくなのでWCF+WFがいいなー.
  • AJAX.NET: これはそんなに悔しくないけど.
  • データベースは相変わらず鬼門になっている.そこそこ書籍を買ったりして投資はしているんだけど,開発者としてストプロ作ったりパフォチューしてないので,なんとなく苦手意識がある.
  • 管理職になったことで,管理業務とかをするようになったことorz
  • 管理職になったことで,年収が(多分)減ったことorz. もっとも来年以降は増えるはずだけど(?)
  • 日記の更新が極端に少なくなったことについてorz

現在やっていること

  • RESTについて,RESTful Webサービスで勉強中.とりあえず仕事で設計したものは,REST原則にあっていないことを確認...orz.この休み期間中に読み終えることを目標にする.
  • C#におけるAOP実装について.RealProxy/LCG/Expression Treeみたいなところで情報収集中.
  • LINQ(当然).
  • 英語の勉強(テスト受けないと)


トータルでみて,そんなに悪い一年ではなかったと思います.来年はどうかなー?いろいろと不安要素もありますが,あまり深く考えず,一つ一つ積み上げていきたいと思っています.
来年もよろしくおねがいします.

100までの素数を求めるプログラム、その後(2)

どうも,もやもやしています.
前回は元ネタからif文とfor文を取り除き(if文は3項演算子に書き換え),関数言語風にしてみました.もちろんこんな実装だと,スタック消費が激しく,パフォーマンス的に使い物にならん,というのはありますが,そこはスルーの方向で.それよりは,本当に関数型言語的といえるのか?ってところがもやもや...
もちろんC#自身が純粋な関数型言語でないのは承知しているつもりです.この気持ちはちょうど,オブジェクト指向に出会ってすぐ,とりあえず継承を多用していたころに感じていたことと,なんとなく似ているような...(意味不明なたとえですみません)


前回のものをさらにいじってみます.
addListヘルパー関数(ラムダ式)は,ListのExtension Methodとして定義したほうがよかったかも...というわけで,早速書き換え(あんまりよく分かってないけど,こんな感じ?)

internal static class MyExtensions
{
  internal static List<T> AddAndReturn<T>(this List<T> v, T e)
  {
    v.Add(e);
    return v;
  }
}

あとは,GetEnumerator()周りをいろいろいじって.PrimeListクラスは以下のようになりました.

internal class PrimeList : IEnumerable<int>
{
  Func<List<int>, int, Func<List<int>, int, List<int>>, List<int>> rec = null;

  internal List<int> GetPrimes()
  {
    return rec(new List<int>(), 2, (list, i) => list.All(j => i % j != 0) ? list.AddAndReturn(i) : list);
  }

  internal PrimeList(int count)
  {
    rec = (list, i, func) => i < count ? rec(func(list, i), ++i, func) : list;
  }

  public IEnumerator<int> GetEnumerator()
  {
    foreach (var prime in GetPrimes()) { yield return prime; }
  }

  IEnumerator IEnumerable.GetEnumerator()
  {
    return ((IEnumerable<int>)this).GetEnumerator();
  }
}

なんとなく,見た目すっきりしたようにも見えるけど,何がしたいのか自分でもよくわかりません(^^;;
さらにコンストラクタ.引数countを直接ラムダ式に埋め込むのではなく,あるラムダ式の引数に渡してその結果(戻り値)がラムダ式になるようなもの(Haskellでいう部分適用のイメージ)を使うことにすると,こんな感じになるのかしら?

  internal PrimeList(int count)
  {
    Func<int, Func<List<int>, int, Func<List<int>, int, List<int>>, List<int>>> partial = m => (list, i, func) => i < m ? rec(func(list, i), ++i, func) : list;
    rec = partial(count);
  }

目が痛くなること請け合い...