日本の経営者が人材不足を嘆いてる件2015年05月28日 15時39分15秒

おいらのブ米。

微レ存どころじゃないですね…(^^;

Twitter ではここからさらに @shimashima35 の人とこんなやり取りを交わしていたのですが…

これはもう本当にそのとおりで、大きい会社が人事管理を補助するためのセクションとして人事部を持つのは理解できるけど、採用も含めて人事全体を人事部が主導して全部取り仕切る、なんてのが日本では慣習化していて、部署ごとの都合なり技術的な専門性なりを理解できてないような人が求人広告書いたり面談やったり全社的な都合を押し通すような異動を決めたりなんてやってたらそりゃあミスマッチで溢れますって、って話なわけで。

ブ米での反応としては、日本の経営者を責めるような発言もまあまあ見られましたね。 id:fromdusktildown の人の米が実に示唆的。

世界で最も人材不足が深刻な国は日本(調査結果)

経営がうまくいかない時に「労働者のせいだ」と考える経営者は「人材不足」と答え、「経営が悪いせいだ」と考える経営者は「人材は足りている。間違っているのは経営のやり方だ」と答える。日本は前者が多い国。

2015/05/27 12:36

ところで、ブ米では「育てないから人材が不足するんだ」といった発言もちらほらと見かけたのですが、これについては少々疑問です。日本では新卒採用が慣習化しているので、タイミングさえ外さなければ、未経験者に対する雇用の間口は開かれている方だとも言えます。職種にもよるのかもしれませんが、そうした企業は職業経験を最初に構築し始める場としても機能していて、そこである程度の年数を在籍することによって、以降の転職活動等における経歴評価の土台を形成した人たちが、ひとつの場所にしがみつかなくともなんとかうまいこと生きながらえているというケースもままあるのではないでしょうか。

多くの会社が採用の際にその人の能力を職歴 (と面談してみた際の第一印象) ぐらいでしか評価できてないっぽいことについてはそれはそれで問題だとは思うのですが…。

日本の企業が他国に比べてどの程度の人材育成に金や時間を費やしているのかについてはあまり承知していないのですが、その点について単純比較した場合においてはそこまで何もやってないということもないんじゃないかと思うんですよ。むしろ頑張っている方なのかも。(OJT を育成に含めて良いのか否かについてはなんとも…)

ただ、技術継承の閉鎖性というか、ローカルノウハウばかりが大事にされてしまっているが故に、ある企業では通用していた人員が、同業他社に転職した時に全く通用しない、あるいはある人に任せていた仕事が、その人がいなくなった途端に全く回らなくなってしまった、みたいなことが頻発しているんじゃないかな、ということの方が、おいらとしては気になっています。ガラパゴスという言葉でよく物事が揶揄されていた時期がありましたが、これ、本当は日本という国単位でのスコープに当てはめるべきなのではなくて、日本に存在する 1つ 1つの企業単位でのスコープに当てはめるべき話なんだと思うんですよね。

日本でも雇用の流動性を上げるべきだ、という声は、特においらがやっているような業界界隈ではよく耳にするんですが、この辺の問題をよく認識しないまま、雇用の流動性だけ上げても、大抵の企業は業務の効率性を上げられないばかりか、むしろ落としてしまう一方だと思うし、それをある程度のところ以下には落ちないように、個々の作業の単純化を推し進めていった結果が、今の派遣期間工などに見られるような、よそでも通用するようなスキルが全く身につかないまま使い捨てられる非正規雇用の現実として、既に現れちゃってるんじゃないかな、っていう気もします。

アポ無し突撃とノウハウの継承2015年05月27日 10時49分52秒

Twitter 使ってると、 TL 上のアーリーアダプタ () な人たちがいろいろとRT してくれるので、ネタに困らなくていいですね。^^

最近はバラエティとかでもアポ無しで突撃って多いですよね。ロケに行ってる芸人さんに行き当たりばったりでやらせちゃうやつ。あれなんてスタッフは楽だよなーとか思うんですよね。特にプロデューサーは楽でしょうね。番組制作スケジュールとか、そんなに緻密に考えなくてもいいんでしょうしね。

個人的にはこういうのって、古臭い因習としての「テレビ様」的価値観が未だに蔓延っている問題、というよりは、番組制作のノウハウが継承されないために、プロデューサーとかの制作首脳陣が無能化していっているとか、そっちの方の問題なんじゃないかなぁとか思うんですよね。本当は出来るんだけどやらないんじゃなくて、それをうまいこと順序立てて完遂する方法を、実はあんまりしっかり心得ている作り手が減ってきてるんじゃないかな、っていう。

とっくの昔に番組制作会社=テレビ局ではなくなってますし、下請け孫請け構造は複雑化の一途を辿っていらっさるようですし、局やめて独立した人が局から仕事をもらってきてた下請け会社が、その会社起こした人たち周辺とかもう定年で辞めちゃってたりしてて、そんな中で予算も時間もないしもういいやって感じでテキトーなやり方で番組作るのが習慣化しちゃってから、更にその中の人が独立して孫請け作ってとかやってたら、そりゃちゃんとやってた頃のノウハウなんて、継承されるはずもないでしょうしね。

気まぐれ再開2015年05月26日 13時29分04秒

思うところあって、これからまたしばらく、なるべく毎日時間を割いてブログを書こうと思う。といっても、あまりこれにばかり時間を割いてもいられないので、その日その日で話題になっていることなどについて、ぶっきらぼうに書き殴るスタイルでいくつもり。そりゃもう、その程度の内容なら Twitter でもいいんじゃないの? っていうぐらいの勢いで。

しかしまぁ、 40 近くにもなって今更… ねぇ? (謎

Ubuntu 14.10 で M-AUDIO Fast Track C400 を使用する2014年12月04日 12時17分24秒

alsamixer でのボリューム調整の様子

最近、仕事用のメインマシンを Ubuntu で運用している T.MURACHI です。

音楽ツールの開発にいい加減取り掛かりたいので、 GCC が使いやすい環境ということで Windows 離れを図ったのですが、ここしばらく、使用しているサウンドデバイスである Fast Track C400 から音が出ない現象に悩まされておりました。しかし実際のところ、なんてことのない原因だったことが先日判明したので、お恥ずかしい話ながら、似たような USB オーディオデバイスの Linux での使用を検討している方向けに、情報を開陳しておこうと思った次第であります…。

音量の設定は PulseAudio 側のみではなく alsamixer でも必要ですよ!!

…要点としては以上になります(恥)。

よくわからない方のために一応手順を示しておきますね。

  1. Ubuntu 14.10 (14.04 LTS でもいいや) をインストールする。この時点で、 Fast Track C400 であれば、 USB で接続されていれば認識されている。
  2. 「システム設定」を開き、「サウンド」アイコンをダブルクリック。「サウンドの出力先」に「Fast Track C400」を選ぶ。「モード」は、普通にステレオで使うのであればどれでも構わない (実際に 4.1/5.0/5.1ch 使うのであれば、好きなのを選べば良い)。
  3. ターミナルを起動する。 Windows キーを押すと出てくるリソース検索窓の入力欄に「terminal」と入力すると、「端末」という名前のアプリケーションが候補に出てくるので、それを選んで起動してあげれば ok 。
    • どうせ Linux とか使う奴はしょっちゅうターミナル使うことになるんだろうからドックにアイコン登録しとけ。
  4. ターミナル上で「alsamixer」とタイプし、 Enter する。 alsamixer が起動する。
  5. カーソルキーの左右で、チャンネルと端子の対応を選択することができる。例えば、「PCM1-Out1」は、 ch.#1 のサウンドを Out1 端子から出力する、という意味になる。カーソルキーの上下で、選んだ組み合わせのボリュームを変更できる。こうした操作により、任意の組み合わせのボリュームを調整する。
    • 例えば単にステレオにしたい場合で、 Out1 端子を左スピーカーに、 Out2 端子を右スピーカーに接続している場合、「PCM1-Out1」と「PCM2-Out2」のボリュームを Max にしてあげれば ok 。
  6. 音を鳴らす任意のアプリを動かして、ちゃんと音がなることを確認する。

alsamixer での設定は、通常は一度設定してしまえば OS を再セットアップするんでもない限り保存される模様。ただし、ふとした時に音が出なくなったとお悩みの際には都度この設定を確認してみるといいと思う。

Ubuntu 14.04 を最初に設定した時には音がなっていたような気がしていたのだが、もしかしたらその時にも調べて alsamixer でボリューム調整していたのかもしれない。で、カーネルが更新されたとかのタイミングでリセットされたとか… 設定できる内容を見る限りデフォルトは全チャンネルボリューム 0 じゃないとおかしい気がするので、多分そんなところだったんじゃないかなぁと反省… orz

プログラミングをやりたいのか自己啓発をやりたいのか2014年09月06日 10時25分14秒

前回「極力更新し続けたい」とか書いておきながらいきなり 2週間も空けちゃってるわけですが… もうどうしようもないですね、習慣づかないものは。

最近は Qiita などというプログラミングなどの開発周りの技術ネタしか投稿されないブログっぽいサイト (こういうのも SNS っていうんですかね?) でちょいちょい拾い読みすることが多くなりました。これまで、ソフトウェア技術者が集まりやすそうなサイトというのはいくつかあったと思うのですが、 Qiita みたいな、基本的に技術ネタのみという縛りがあって記事を寄せ合うサイトって、そういえばあんまりなかったなぁ、というか…。通常のブログサイトだと、やっぱりプログラマーであってもプログラミング以外のネタ (単なる日記であったり、一般に報じられているニュースや話題への反応であったり) も投じられていることが多くて、 /.-j なんかも基本はニュースサイトですし、そこで ID 持ってる人の日記も必ずしも技術ネタではないということが多かったので、 Qiita みたいなサイトが今後ますます盛り上がっていくんだとすれば、それはとてもいいことだと思うんですよね。

おいら自信も、今社長ブログの方で書いてる API デザインのネタも、本当は Qiita みたいなサイトで書いてたほうが色々と反響も得られていいのかなぁとか思い始めています (どーせアフィリエイト儲からんし)。そもそもコード引用して載せたりするのに WordPad 全然便利じゃないよね、っていうのもフラストレーションとしてはあったりもするのですが…。

で、先日、クラスの命名のアンチパターンという記事がまあまあ興味深かったので、ストックした上でさらにはてブでブクマしたのですが、後日ブクマページ覗いたら 700以上ものブクマ集めててびっくり、ということがありまして、さすがにクラス命名ぐらいのわかりやすい話だと興味示す人も少なくないんだなぁなどとも思ってみたり。 oop 全般ということで開発言語を選ばない話題ともなるとさすがに耳目も集めるものなんですかね。 ID 生成の話題なんかも結構ブクマ集めてましたし。

その一方で、もう少し専門性の高い話題、例えば特定のプログラミング言語やフレームワークなどの環境を限定する話題であったり、ソフトウェア工学やセキュリティ界隈などの学術的な話題であったり、ハードウェア関連の具体的な話題であったりとなってくると、関心をよせる人の数もどうしても少なくなっていく。それはどうしても仕方のない事で、 IT 関連の技術者を目指すすべての人が、それらのすべての話題を網羅して会得し関心を持ち続けるというのは、到底各人の時間的、体力的、その他あらゆる面でのリソースが追いつきっこないわけですから、それぞれがそれぞれの今与えられている仕事や直面している課題、あるいはもっと純粋な興味の末、なんでもいいのですが、そういった各人の境遇の末に抱く関心の方向が、それぞれみんなバラバラで、その結果としてそれぞれの専門に集まる耳目が少なくなるのは、まあ当然っちゃ当然ですよね、とは思うわけです。

実際の所、何らかの専門性の高い分野自体に、まだまだ踏み込めていないという人も多いと思います。まだ学習し始めたばかりという駆け出しの初心者さん、日々与えられた仕事をただなんとなくこなしているだけのサラリーマンSE、そして、憧れだけで「プログラマーになる」ことを目指してコの業界に飛び込んできちゃった方々とか…。

昨夜、寝る前になんとなーくはてブのホッテントリに、 18 till i die というプレゼン資料が上がっているのを見つけまして、ざっと内容をさらってみたのですが、正直、「ああ、またかぁ…」という感想だったんですね。

このプレゼンは Yoshiori さんという方が、Developers Summit 2014 というイベントに寄せて作られたものだそうで、そもそもこのイベント自体が、ソフトウェア技術者の自己啓発を目的としたイベントだったようです。この方自身は非常に有能な技術者さんなのだと思いますし、この資料自体もイベントの内容に則した、よく出来た発表内容だったのだと思います。

ただ、成功体験に基づいて綴られただけの自己啓発コンテンツを求め合う同業者の慣れ合いイベントを「サミット」などと呼んで盛り上がっていたり、そこで発表された資料を有難がって読んで「これはエモい」とか言って喜んでいる様を見るにつけ、彼らは一体何をしたい人たちなんだろうな、という疑問は沸き上がってくるわけです。

現在、多くの「勉強会」と呼ばれるイベントが、さまざまな専門分野において各地で行われていたりしています。それらも得てして「勉強会」と呼ぶにはあまりにイベントイベントしていて、その場で勉強をするために集まってきているというわけでは必ずしもなく、むしろ同好の士と顔を合わせ、その専門分野について話を聞き、あわよくば会話を交わし合うことで刺激を得、ますますその分野に邁進する力を得ることを目的としている節があります。そういう意味ではこういった「勉強会」イベントも、ある種の自己啓発イベントと言えなくもないのですが、そこで寄せ合う発表内容はあくまで専門技術に特化した内容であり、自分たちの関心の先に発展があることを確認しあう場であるからこそ、そういう力も強め合い、高め合うこともできているんだろうなという納得もあるのです。

言ってみれば、その専門分野に邁進する (あるいはそれによって各人の実際の興味対象や直面する課題の解決を目指す、というのでもいいのですが) という目的が大前提にあって、その目的を遂げるための力を得るために啓発しあう場として機能する、という点で、これらのイベントは役に立っているのだと思うのですね (もちろん、純粋に勉強する気でいらっしゃっている方も少なく無いと思います…)。

その一方で、割と純粋に自己啓発だけやってるイベントに喜んで参加する人たちとか、そういう場で発表された、自己啓発だけで技術的には特に内容のない資料を読んで喜んでいる人たちって、実際の所、自己啓発自体が目的になっちゃっていて、その後の各人の関心事を深めるという活動にまでは、残念ながら至っていない人も多いんじゃないかと危惧してしまいます。

取り越し苦労だといいんですけどね。

近況とか氷水とか2014年08月23日 11時42分43秒

なんとなく気が向いたので久しぶりに更新。社長ブログの方はちょくちょく更新を続けているのですが、こちらは 1年以上開けてしまいましたか…。

去年の今頃は個人事業主として某原宿で仕事していたのですが、なんか C++ と Win32 を理解できる技術顧問的な立場に据え置こうという思惑があったようで、せっかく脱サラ独立したのに一私企業の組織に組み込まれて生きていかなきゃいけないんじゃ意味無いじゃんという思いから精神的に参ってしまってさっさと逃げ出してしまったということがありまして (^_^;A、それ以降、前々から付き合いのある某所から、そんなに根詰めて時間掛けなくてもいい調査やらプロトタイピングやらのゆるい持ち帰り仕事を頂いて何とか生活を凌いでおります…。

今の仕事もいよいよ本開発にさしかかろうとしているのですが、さまざまな政治的事情があって報酬は据え置きのまま、納品後の成功報酬も口約束だけで金額もどうなるかわからないという…。体調が相変わらずいまいち振るわないのでガッツリ常駐の仕事を寄越されるよりはまだマシなのですが、もうちょっとカネになるマシな仕事を紹介していただけるんであれば、責任が発生する前にさっさとそっちに流されたい気分ですね…('A`)

そういえば家庭の事情等も色々とありまして、 5月に引っ越した際にASAHIネット解約しました(^_^;。といっても事務所の方で法人として使わせて頂いてますし、ここのブログを継続するためだけに毎月 300円払い続けてはいるのですが…。

そんなわけで、 300円がもったいないのでw、今後はこちらのブログも極力更新し続けたいと思います。主に Twitter でつぶやくと連投になっちゃいそうな類の長いつぶやき (よーするに愚痴) を吐き出す場所として使うことになりそうですが…。

せっかくなので時事ネタに触れてみることにします。アイス・バケツ・チャレンジ、ですか…。

ネット界隈では賛否分かれていらっさるようですね。個人的にもなんだか気持ち悪い運動だなあと思っていて、何でかというとこれは多分、チャレンジを振ってくれる友人も、その後にチャレンジを振る相手の友人もいる人だからこそ楽しめる遊びだからだと思うんですね。で、それをつべだの Ust だので動画うpしたりして SNS 使って周囲に見せびらかしていらっしゃるわけですから、そういう行動に疎外感を勝手に感じてしまう方々というのは一定数いらっしゃるはずで、おいらとしてはそういう精神的に孤独な人々が実際に社会的に孤立してしまうがゆえに生じるさまざまな問題に対してこそ、お金というのは投じられるべきなんじゃないかと思っていたりもしているんで、結局のところは価値観の相違なんでしょうね…。

とはいえ、無名の難病への認知度を向上させ、実際に寄付金の向上に寄与したわけですから、仕掛けとしては大成功だったのだろうと思います。おいらが好きか嫌いかなどというのは激しく些細な問題で、己が最も関心をよせる物事への助力のために手段を選ばないというその姿勢は、見習うべきものがあります。結局のところ、資金というのはもぎ取るものなんですよね…。2匹めのどじょうを追って各方面が似たような真似っ子企画を立ち上げたらそれこそ迷惑以外の何物でもないですが、まぁ好きにしたらいいんじゃないかな(´∇`)♪。

ちなみに、仮にもそんなことはありえないとは思うのですが、もしオイラがこのチャレンジに指名された場合、恐らく取る行動は指名してきた相手によって変わると思います…。

とりあえず、面識のない人、見ず知らずの人から突然振られても、間違いなく無視します。例えば Boost.勉強会で隣の席に座ってたじゃないですかーとか言われても十中八九無視します(^_^;。それから面識がありすぎる人、たとえば某 BBS の面々とか、某元同僚さんとかに振られた場合、やっぱり笑顔で無視します。「やだよw」っつって無視します。

でもね、例えば顧客として取引のある人であったりとか、過去にお世話になったとおいらが勝手に思っている人 (某 O 社の DQN 社長とかw) とかに突然振られてしまった場合、残念ながらお断りできる自信がありません。これは言ってみれば飲み会の席でだいぶ酔いが回って気持ち悪くなってきているのにビールのお尺をされそうになった場合のシチュエーションに酷似します。大抵の場合はもう無理だからと笑顔でお断りできるのですが、様々な文脈や政治的な理由によりそれがしにくい相手というのはどうしてもいます。

つまるところ、アイス・バケツ・チャレンジに否定的な人というのは、飲みニケーションが苦手な層とだいたい一致するんじゃないでしょうかね…。

DB 操作の視点からオブジェクト指向を考える2013年06月23日 22時18分58秒

シナリオ

出席簿をつけるアプリケーションを想定してみることにします。まずマスターとして、学生、講師、講義の 3つが存在するものとします。

  • 学生

    • 学籍番号 (PK)
    • 氏名
    • 性別
    • 学年
    • etc...
  • 講師

    • 教員番号 (PK)
    • 氏名
    • 性別
    • 役職
    • etc...
  • 講義

    • 講義識別番号 (PK)
    • 講義名
    • 担当講師 (教員番号)
    • 場所
    • 時間割
    • 期間
    • 単位数
    • 概説
    • etc...

それから、マスター以外のテーブルとして、受講者リストと出席記録があるものとしましょう。

  • 受講者リスト

    • 講義識別番号 (PK)
    • 受講者 (学籍番号) (PK)
    • 点数
    • 成績 (優|良|可|不可)
    • etc...
  • 出席記録

    • 講義識別番号 (PK)
    • 受講者 (学籍番号) (PK)
    • 講義回数 (N回目) (PK)
    • 遅刻 (時刻)
    • etc...

さて、ログインした講師が受け持つ講義の 1つを選択し、新たに出欠をとる画面を開いたとします (講義回数は自動でカウントされるべきでしょう)。その画面には講義に参加する全ての学生が学籍番号順にリストアップされており、点呼を受けて講師自らが学生たちの出欠状況を入力していくものとします。これをどうプログラムで表現し、実装するべきか。

ありがちな過ち

オブジェクト指向をメタファー (隠喩) の表現のために用いること自体は必ずしも間違いではありませんが、メタファー自体も手段の一つと捉えるべきです。メタファー自体が目的になってしまうと、パフォーマンスが犠牲になることが多くなります。

例えば学生と講師はどちらも人なので、 Person クラスで抽象化して StudentTeacher に派生しよう、などと考えること自体は悪くないかも知れません。

// 人を表す抽象クラス
public abstruct class Human
{
    // 人を特定する番号 (学籍番号、教員番号等)
    public long Number { get; protected set; }
    
    // 名前
    public string Name { get; protected set; }
    
    // 性別 ("M": 男性 / "F": 女性 / "O": その他)
    public string Sex { get; protected set; }
    
    // etc...
}

// 学生クラス
public class Student : Human
{
    // 学年
    public int? Year { get; private set; }
    
    // ...
}

// 講師クラス
public class Teacher : Human
{
    // 役職 (11:助教 / 16:講師 / 21:准教授 / 26:教授 / 51:名誉教授 / 56:客員講師 / 99:その他)
    public int Roll { get; private set; }
    
    // ...
}

あー、ちなみに言語は C# で書いてます。テストしてませんが。

で、ここまでは良いんですが、ありがちな誤りとして、それぞれのクラスのコンストラクタに DB からの読み込み機能を持たせちゃうという試みがあります。

using Db = MyNameSpace.DbAccessor;

public class Student : Human
{
    // ...
    
    // デフォルトコンストラクタ (マスタ登録時用)
    public Student() { }
    
    // コンストラクタ (学籍番号から情報を取得)
    public Student(long number)
    {
        DataTable table = Db.StudentTable.SelectByPk(number);
        if (table == null || table.Rows.Count == 0)
            return;
        
        DataRow row = table.Rows[0];
        Number = number;
        Name = row["STUDENT_NAME"] as string;
        Sex = row["STUDENT_SEX"] as string;
        Year = row["STUDENT_YEAR"] as int?;
        // ...
    }
    
    // ...
}

さすがに面倒くさいので Teacher の方の実装例は割愛。

何故にこれがアカンのかと言いますと、まぁ例外との兼ね合いというのもあるのですが、何よりあまりにも気兼ねなく使え過ぎちゃって、知らず知らずのうちに無駄な DB アクセスが増えてしまう要因になりうるからです。あと、実際の使用に際しては実はあまり使われることのない存在になる可能性も小さくありません。

「データ取得用」のクラスは別に設ける

シナリオを読み返しましょう。講師が出欠をとるために開いた画面では、その講義への参加を登録している全ての学生が、学籍番号順にリストアップされるとしています。そのような複数の学生を特定する処理は、DB 側での SQL に任せてしまった方が効率がよいのは当然です。そこで、特定の講義に参加する学生のリストを取得するファクトリクラスを考えます。

using Db = MyNameSpace.DbAccessor;

public class Student : Human
{
    // ...
    
    // コンストラクタ
    internal Student(DataRow row)
    {
        Number = (long)row["STUDENT_NUMBER"];
        Name = row["STUDENT_NAME"] as string;
        Sex = row["STUDENT_SEX"] as string;
        Year = row["STUDENT_YEAR"] as int?;
        // ...
    }
    
    // ...
}

// 学生情報管理クラス - とりあえずファクトリとして実装
public class StudentManager
{
    // 学籍番号を指定して学生情報を取得
    public static Student Get(long number)
    {
        DataTable table = Db.StudentTable.SelectByPk(number);
        if (table == null || table.Rows.Count == 0)
            return null;
        
        return new Student(table.Rows[0]);
    }
    
    // 講義を指定して学生情報のリストを取得
    public static Student[] ListUpByLecture(int number)
    {
        // 特定の講義番号で登録されている受講者の学籍番号を受講者リストテーブルから
        // リストアップし、その学籍番号を用いて学生テーブルから学生の情報を引っ張る、
        // までを全部 SQL でやっつけてデータを返すメソッドを想定
        DataTable table = Db.LectureMembersTable.SelectByLecture(number);
        if (table == null)
            return new Student[] {};
        
        var students = new List<Student>();
        foreach (DataRow row in table.Rows)
            students.Add(new Student(row));
        
        return students.ToArray();
    }
}

Student のコンストラクタを internal にするのがミソです。こうすることで、同一ファイル以外からのアクセスがコンパイラによって禁止されます。それによって、 StudentManager クラスのメソッドを介さなければ Student のコンストラクタは呼べない、すなわち Student クラスのインスタンスを生成できないようになるわけです。同様のことは、 Java ならクラス内クラスにして protected で、 C++ なら friend を使う等で実現可能でしょう。

デフォルトコンストラクタは省いたのではなく敢えて書いていません。多分、マスタへの変更をする目的でわざわざ Student インスタンスを生成するべきではありません。理由はいくつかあって、例えばマスタ登録のためだけにアクセサのセッターまで public にしてしまうとメンテナンス性が損なわれるのではとか、そうではなくて全部の情報を引数に渡すコンストラクタを設けるぐらいならデータ管理用のクラス (まさにここで言うところの StudentManager クラス) にて全部の情報を引数に渡すメソッドを書くんでも変わらないよねとか。ついでに INSERT はもとより UPDATE するためにわざわざ SELECT で情報を全部引っ張ってきてからそれをコード上で上書きして UPDATE を呼ぶとかするんでなしに最初っから PK だけ指定して UPDATE だけ呼んだ方が速いに決まってるよねとか。

NULL 可能なフィールドとかもあるし全部を引数に渡すメソッドは現実的じゃないだろうとか言うんであれば、内部データだけを持つデータ構造を定義して分離可能にしてしまっても良いと思う。こんな感じで。

public class HumanData
{
    public string name;
    public string sex;
    // ...
}

public class StudentData : HumanData
{
    public int year;
    // ...
}

public abstruct class Human
{
    // フィールド構造体アクセサ
    protected HumanData Fields { get; set; }
    
    public long Number { get; protected set; }
    
    public string Name
    {
        get { return Fields.name; }
        protected set { Fields.name = value; }
    }
    
    public string Sex
    {
        get { return Fields.sex; }
        protected set { Fields.sex = value; }
    }
    
    // ...
}

public class Student : Human
{
    public int Year
    {
        // こういうダウンキャストは酷くダサイですが…
        get { return (Fields as StudentData).year; }
    }
    
    // ...
    
    internal Student(DataRow row)
    {
        Number = (long)row["STUDENT_NUMBER"];
        
        var fields = new StudentData();
        fields.name = row["STUDENT_NAME"] as string;
        fields.sex = row["STUDENT_SEX"] as string;
        fields.year = (int)row["STUDENT_YEAR"];
        // ...
        Fields = fields;
    }
}

public class StudentManager
{
    // ...
    
    // 学生の情報をマスタに登録し、学籍番号を返す
    long RegistNewStudent(StudentData data)
    {
        // ...
    }
}

まぁ、この辺は好き好きで…。

マスタデータをプールする

頻繁に見には行くけどそうそう書き換わることのないデータであり、それをプールさせておく時間をそれほど長くないセッション単位に限定するのであれば、マスタデータのメモリ上でのプールはそれほど悪くないアイデアだと思います。

public class StudentManager
{
    // プール用コンテナ
    Dictionary<long, Student> pool = new Dictionary<long, Student>();
    
    // プールをクリアする
    public static void ClearPool()
    {
        pool.Clear();
    }
    
    // 学籍番号を指定して学生情報を取得
    public static Student Get(long number)
    {
        if (pool.ContainsKey(number))
            return pool[number];
        
        DataTable table = Db.StudentTable.SelectByPk(number);
        if (table == null || table.Rows.Count == 0)
            return null;
        
        return pool[number] = new Student(table.Rows[0]);
    }
    
    // 講義を指定して学生情報のリストを取得
    public static Student[] ListUpByLecture(int number)
    {
        // 特定の講義番号で登録されている受講者の学籍番号を受講者リストテーブルから
        // リストアップし、その学籍番号を用いて学生テーブルから学生の情報を引っ張る、
        // までを全部 SQL でやっつけてデータを返すメソッドを想定
        DataTable table = Db.LectureMembersTable.SelectByLecture(number);
        if (table == null)
            return new Student[] {};
        
        var students = new List<Student>();
        foreach (DataRow row in table.Rows)
            students.Add(pool[(long)row["STUDENT_NUMBER"]] = new Student(row));
        
        return students.ToArray();
    }
}

但し、どういうタイミングで StudentManager.ClearPool() を呼ぶべきかをちゃんと考えて使わないと、サーバー上で起動しっぱなしのプロセスでプールにデータがたまりっぱなし、しかもマスタメンテ画面で学生情報を修正したのに (学年とか) その変更が画面に反映されないぞー何でだーみたいなバグを誘引する原因になったりもするので、気をつけて使う必要はあると思います。特にグループ開発では。

まとめ

そんなわけで、結局のところ何が言いたいのかというと、オブジェクト指向というのは必ずしもメタファーのためだけにあるわけではないよということです。最近ではよく、「オブジェクト=物である、という説明を真に受けてはいけない」などと言われるようになりましたが、それは何でかというと、業務シナリオの中に出てくるような、実在する物だけをオブジェクトとして表現しようとすると、そのオブジェクトのクラスの中だけで何でもかんでもやり遂げなきゃならないような気になってしまうからです。学生を表現したいからと言って、必ずしも学生クラスの中だけで DB アクセスまで完結する必要はないわけです。あくまで、プログラム上での目的に応じたオブジェクト設計を心がけるべきなのです。

ASP.NET でありがちな話2013年06月20日 06時11分38秒

よーするに今の職場からでは恐らくこんなブログサイトはフィルタリングされて見られやしないだろう事を良いことに書きたい放題愚痴をまき散らしてしまえというお話です^^

単なる表示上の変化に過ぎないものまでポストバックで実現する

ポストバックというのは ASP.NET 用語で、よーするにフォーム操作で発生する POST 送信とそれに対するサーバーからの応答によって、同一ページ上でのユーザーとシステムとの対話を実現してしまおうというやり方のことです。これは問い合わせ内容に応じて結果表示を切り替える仕組みとして想定されているものですが、どうやら一般的な ASP.NET 開発者は DB への問い合わせが発生しないようなことにも平気でポストバックを使ってしまうようです…。

例えばラジオボタンの選択に応じて入力項目の表示が切り替わるような UI とか、クライアントサイドスクリプトで事足りるのにも係わらず、なぜか AutoPostback="true" とかにして、 SelectedIndexChanged イベントハンドラをわざわざ書いて、わざわざ POST が発生するような作りにしてしまう。マスターページを使ってると ID が変化しちゃうから… という声もありそうですが、 runat="server" にさえしなければ ID も変化しないわけで、だったら <div> なり <span> なりで包んで表示/非表示ぐらいは出来るだろうに (それはそれで微妙にダサイんですが…)。

何でもかんでも Page.Session に突っ込む

DB に対する問い合わせ結果を表にして表示するような UI は業務系の Web アプリでは多いですが、一般的な ASP.NET 開発者の中には DB から取得した問い合わせ結果の DataTable (配列の豪華版みたいなもん) をそのまんま Page.Session に突っ込んで、ユーザーがレコードを選択したときの値の突き合わせのために再利用しようとする人が多いみたいです。

ASP.NET では、セッションに紐付いた情報はデフォルトではプロセスのメモリに格納されるとあります (だからラウンドロビン構成にしても同一セッションでのアクセスは常に同一の Web サーバーによって処理されるわけですね)。上記のような実装を想定してセッション状態ストアプロバイダーとやらを独自に実装していたり、 Web サーバのメモリ容量を十分に確保していたりしているなら良いのですが、ちゃんとそこまで想定していらっさる開発者さんってどれくらいいらっさるんでしょうね…。

何でもかんでも View State に突っ込む

ユーザーコントロールを実装する場合、コントロールの表示状態を保持するために、関連する情報を View State と呼ばれる場所に格納しておくものなんだそうです。いや、本当に表示状態に関する情報 *だけ* をここに突っ込むんであれば良いのでしょうが、データグリッドの DataSource に突っ込むようなでかいデータをそのまま View State に放り込む人とかも結構居て、そのおかげで出力される HTML がすさまじいことになったりするケースもちらほら見かけるようです… あれは BASE64 かなんかでエンコードした文字列をそのまんま hidden に書き出しますからね…。

他にもいろいろと言いたいことはあったような気もしますが、よーするにまとめてしまうと、何でもかんでもブラックボックス化して取っつきやすさばかりを重視した開発ツールなんて、もう初学者の学習教材専用ということにしてしまって、プロの現場に持ち込むのは止めましょうよという話だったりするわけです。ぐんにゃり。

ASP.NET2013年06月03日 08時11分27秒

かつては EC サイト構築に活用されていたとか何とか言われていた ASP.NET が、今では企業向け業務用 Web アプリケーションの分野でばかり使われているような気がする現状について考えてみる。

考えるまでもないだろ、とか言われそうな気もしますが…。

とりあえずインターネットに公開する一般向けサイトの開発に向かない、というかそっち方面ではほとんど見向きもされない理由は分かるんです。個人のサイトで使う分にはちょっと仰々しすぎるというか大げさというか、準備しなきゃならないものがあまりにも多すぎてコスト高だと思うし (そも個人がサイトを開くレベルのホスティングサービスで Windows Server が使えるところ自体あんまり聞かない)、企業が作る Web サービスとかだと、仮に人気が出ちゃってアクセス集中しだしたときにスケールアップの難しさ云々以前に ASP.NET の仕組み自体が高トラフィック要求しすぎというか無駄が多すぎで話にならない。

一方で企業がイントラで使う業務用 Web アプリの分野では通信コストのスリムアップはそれほど要求されないし、むしろ要求されたらサーバー増築でさらにお金をせびる口実にもなるし、技術的には決まり切った作法に則って行われる単純作業に集約できてリスクも軽減できそうだしで良いことづくしにも見える。何より自由なソフトウェアはサポートが無くて既存のバグに由来する不具合も全て自前で責任をとる必要がある。何か問題があったラベンダー任せに出来るという安心感が、その辺の業界での採用を下支えしている感もある。

ただ、当のベンダーである Microsoft はその状況をよしとしているのかね? MVC モデルの登場は、むしろそうした状況を打破したいようにも見える。 UA へのアウトプットを概ねコントロール可能にすると言うことは、通信コストの軽減を意味するものでもあり、あるいは他の Web フレームワークと同じ土俵にたつための変更であるとも言える。ホスト OS が IIS という時点で同じ土俵には立ててない感もあるけど。

ASP.NET を利用して開発を行う企業や開発者について言えばもっと心配だ。 MVC に関して言えば、デスクトップアプリで言うところの WPF ぐらいの勢いで敬遠されている節もある。まぁいつだって業務アプリ界隈は保守的な人々の巣窟な訳だけど、 ASP 以外の普通の Web 開発現場ではむしろ MVC モデルを採用したフレームワークの利用が一般的だし、そうでなくても HTML5 や、 JQ でもいいからクライアントサイドスクリプティングが普通にこなせるようでないと潜り込んでいくのは難しい。 ASP.NET で開発やってました= Web 開発経験ありますとは到底言えないのが現状なのではないかと思うがどうか。

VSS2013年05月24日 06時48分49秒

どうも、ご無沙汰でやんす。

つなぎの、というつもりでもなかったんですが、とりあえず 1ヶ月半ぐらいやらせていただける案件があって、食いつなぐためにもやらせていただいているんですが、その現場のネット環境が非常に厳しい (外部とのメールのやりとり NG、 Web 閲覧は Google Web検索、 Google Map、Yahoo のトップページ、 MSDN Library 以外は概ね NG、その他のプロトコルも当然 NG) 為、仕事自体もやりにくかったりでいろいろとフラストレーションを抱え込んだりもしているわけですが。

仕事の内容は ASP.NET で作られている業務用 Web システムの機能追加のお手伝いで、 ASP の部分、つまりは表示と UI 制御辺りの実装を主に… まぁ仕事の内容の話はいいや。古いバージョンに拘泥している割にはガッチガチに M$ 様の支配下にいらっさるようで、ソースコードのバージョン管理も VSS を使用、当然 Trac のようなタスク管理ツールや BTS はなし。線表も顧客向けのを Excel かなんかで書いてただけみたいで (Project ぐらい使えよ)、進捗管理とかスケジュール管理とかの概念自体が微妙に希薄な印象…。

で、 VSS なんですが、実はおいらはこいつを使うのは今回が初めて。いやーこれはこれはありがたい経験をさせていただいております限りでございまして…。おかげでこいつがネット上では情報収集および発信に熱心なプログラマーたちの間で何で嫌われているのかが理解できてきましたよ。使う前までは単にマージではなくロック方式だから嫌われているだけなんだと思っていたのですが…

まず戸惑うのは言葉の違い。これはまぁ方式の違いもあるので仕方ないことではあるのですが、チェックインという言葉は使ったことがなかったので… この辺は恐らくホテルのチェックイン・アウトと同義だと思えばいいのかなと。

ソースの取得 (Subversion 辺りでいうところの update) も微妙に戸惑いますね… 何で毎回「サブプロジェクトも取得」とか「ツリーを構築する」とかチェックボックスにチェック入れなきゃあかんのでしょう… んなもん指定した場所以下は全部落とせに決まってるじゃないですか… ていう。それでディレクトリが追加されていたりすると「ディレクトリ無いけどどうする? 作るの?」みたいな確認ダイアログをわざわざ出してきてブロックする… メール確認してたりで VSS ほったらかしにしてるとそのダイアログが裏に隠れちゃってたりして気がつかないまま作業開始しちゃって、あれ、直したって言われてたビジネスロジックの動きが変わってないなぁ、何か間違えてるのかなぁ… なんてことに無駄に時間を割いたり… orz あと自分でチェックインした以外の変更があれば「xxx を置換」ってログメッセージが出るから取得が終わったんだなって分かるけど、そうじゃないと何にもログ吐かんのな。キャンセルボタンが消えてるから一応気づきはするんだけど、時間かかるんだからせめてもうちょっと「終わったよ!」ってのアピールして欲しい ('A`)。

で、作業に入るわけですが、 Visual Studio は VSS と自動で連携していて、 Visual Studio 上で書き換えようとした瞬間に、そのソースファイルのチェックアウトをしに行ってくれるようになってる。まぁロック方式ですし、手動でやらされることを考えれば便利なんでしょうけど、間違えて触っちゃってアンドゥで直してそっ閉じしたファイルがチェックアウトしっぱなしになっていてチームにご迷惑を… みたいなのは方々で多発していらっさるんでしょうなぁとか思うとちょっと胸熱…。

ロック方式とマージ方式のどっちかが絶対に優れているとかは言うつもりはないです。普通の開発体制であれば同じファイルを複数人が同時に触るということはそうそうないですし、チェックインし忘れによる不便とコンクリフト発生時の面倒を秤にかけても仕方ないですし。個人的には、テキストファイルをテキストファイルとして編集するようなもの (ソースコードとか XML とか HTML とか) はマージ方式、それ以外 (バイナリファイル全般とか、 XML でも MS-Office のドキュメントみたいにアプリ上での状態まで保存するためにちょっといじっただけでファイル全体にわたって diff が出まくるようなものとか) はロック方式で管理するのがやりやすいかなとか思っていたりはするわけですが。 Subversion なんかはファイルの種類ごととかディレクトリごととかでマージ方式かロック方式かを指定できたりするのは良いですよね。

それから VSS では変更内容のログを残しておくという文化がないっぽいのも気になります。一応、 Visual Studio 上でチェックインを行う際にはログメッセージを記入することも出来るようにはなっているのですが、現場の人には「別に特に書かなくて良いですよ」とか言われてしまい、それでもなんか嫌なので何かしら変更内容を記入するようにはしていたんですが、変更履歴のログを見る機能とかそういえば使ったこと無いですね… (一応無いことはないらしい)。 この辺はちゃんとやろうと思えばやって出来ないことではないとは思うんですが。

ログと関連して、最近は Trac や Redmine などといったタスク管理ツールと連動させる使い方が結構広まってきていると思うんですが、 VSS にはそういうソリューションってあるんですかね? コミットログにはチケット番号を、チケットにはリビジョン番号を書いて相互リンクとかやると結構便利だったりするわけですが…。

そんなわけで、結論としては VSS 不便だなぁというお話でした。それでもこうすればもうちょっと便利に使えるよ、という話はあるのかも知れませんが、 VSS と Visual Studio で完結できない話であるなら、そも今の現場はネットからファイルをダウンロードすること自体フィルタリングで物理的に不可能なので、まぁ 1ヶ月半だし我慢しましょうという感じですかね。(*sigh*)