<?xml version="1.0" encoding="UTF-8" ?> <rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>オブジェクト指向</title><link>http://blogs.wankuma.com/jitta/category/2217.aspx</link><description>オブジェクト指向</description><managingEditor>はなおか じった</managingEditor><dc:language>ja-JP</dc:language><generator>.Text Version 0.95.2004.102</generator><item><dc:creator>はなおか じった</dc:creator><title>面白いんだけど・・・</title><link>http://blogs.wankuma.com/jitta/archive/2013/03/13/319251.aspx</link><pubDate>Wed, 13 Mar 2013 22:20:00 GMT</pubDate><guid>http://blogs.wankuma.com/jitta/archive/2013/03/13/319251.aspx</guid><wfw:comment>http://blogs.wankuma.com/jitta/comments/319251.aspx</wfw:comment><comments>http://blogs.wankuma.com/jitta/archive/2013/03/13/319251.aspx#Feedback</comments><slash:comments>6</slash:comments><wfw:commentRss>http://blogs.wankuma.com/jitta/comments/commentRss/319251.aspx</wfw:commentRss><trackback:ping>http://blogs.wankuma.com/jitta/services/trackbacks/319251.aspx</trackback:ping><description>&lt;p class="p"&gt;ネタ元：「&lt;a href="http://d.hatena.ne.jp/gallu/20130301/p1" title="⇒hatena.ne.jp" class="outerLink"&gt;[プログラミング]「型」があるのは福音だよ？&lt;/a&gt;」から「&lt;a href="http://d.hatena.ne.jp/perlcodesample/20130227/1361928810" title="⇒hatena.ne.jp" class="outerLink"&gt;変数に型がないということの利点について考える&lt;/a&gt;」&lt;/p&gt;
&lt;p class="p"&gt;うん、面白い。&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;どのような型の値でも代入できる&lt;/p&gt;
&lt;p&gt;　まず基本的なこととして変数に型がなければどのような型の値でも代入できるということです。つまり、受け取るときに、どのような型の値を受け取るのかを意識する必要がありません。&lt;/p&gt;
&lt;pre&gt;my $str = 'Hello';
my $num = 1;
my $nums = [1, 2, 3];
my $person = {age =&gt; 2, name =&gt; 'taro'};
my $ua = LWP::UserAgent-&gt;new;&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;p class="p"&gt;「どのような型の値でも代入できる」ということですが、C/C++ でも、ポインターに限定すれば、&lt;code&gt;void&lt;/code&gt; とアスタリスクで宣言することで、どのような型のポインターでも代入できますよ。Java や C# なら、&lt;code&gt;Object&lt;/code&gt; で宣言すれば、何でも入れられるんじゃないかなぁ？でも、それをやる人は、まず、いない。おおよそ、構造体や関数の型を定義して、それを使う。なぜか。型を明示することにメリットがあるから。そのメリットについては、明示的には書かない。&lt;/p&gt;
&lt;p class="p"&gt;そして、これは、次と一緒と考えて良いのかな？&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;変数に型がないと変更に強い&lt;/p&gt;
&lt;p&gt;　変数に型がないとソースコードの変更に強くなります。たとえば右辺の返す型に変更があったとしても、受け取る側のソースコードを変更する必要はありません。&lt;/p&gt;
&lt;pre&gt;# clinetはClientA型でもClientB型でもよい
my $ua = $c-&gt;client;&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;p class="p"&gt;「どのような型でも代入できる」では、初期値の代入しかしていません。しかし、「変数に型がないと変更に強い」では、コーの変更のことにまで言及してあるので、例えば次のようなコードも許される、ということかな？&lt;/p&gt;
&lt;pre&gt;my $variable = 1;
my $variable = 'abc';&lt;/pre&gt;
&lt;p class="p"&gt;で、「変更に強い」というのを、この様に、「コードを変えなくてもよい」のようにはいわないと思うのですが、どうなんだろう？私がイメージする「変更に強いコード」とは、仕様に変更があったとき、「どの範囲に影響があり、どこを修正すれば良いかがわかりやすいコード」なのですが。ここで言われているのは、「どのような型でも代入可能なので、型が変わったということがわからず、変更しなければならない箇所がわかりにくい」でしかないと思うのです。ああ、「変更しなくていい」だから、変更しなければならない箇所はわからなくて良いのか。でも、変更しなければならない箇所がわかりにくいということは、変更が有効になっていることをテストするコードを書きにくい、ってことじゃないかな？そうすると、コメント欄で、「テストすればわかる」と書かれていることと矛盾します。確かに、テストコードを&amp;#8220;書いて&amp;#8221;、テストすればわかるでしょう。しかし、テストコードを&amp;#8220;書く&amp;#8221;のなら、次の所とも矛盾します。&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;記述量がとても短くなる&lt;/p&gt;
&lt;p&gt;　変数の型がないことによって記述量がとても短くなります。&lt;/p&gt;&lt;/blockquote&gt;
&lt;p class="p"&gt;え～～！！テストコードの方が、記述量が短いですって？そんなこと無いでしょう？&lt;/p&gt;
&lt;p class="p"&gt;ちょっとふざけてみました。いや、かなりまじめ。型を書くという事を「記述量が多い」といいながら、静的型付け言語では不要な「型チェックのためのテストコード」を書くことは、記述量に入らない？テストコードを書く時間は、開発時間に入らない？生産性として勘定しない？そんなバカな。。。&lt;/p&gt;
&lt;p class="p"&gt;あと、ここも気になった。&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;複数の型を受け取りたいときに、インターフェースを実装する必要がない&lt;/p&gt;
&lt;p&gt;　Javaで大きなの労力といえば、インターフェースの仕組みを覚えて、実装することでしょう。複数の型を受け取りたい変数を作成したい場合は、まずインターフェースを実装することになります。&lt;/p&gt;
&lt;br&gt;
&lt;p&gt;関数のオーバーロードが不要になる&lt;/p&gt;
&lt;p&gt;　変数の型を持つ言語は、型が異なるのだが、処理としては同一の処理を行いたい場合には、オーバーロードという機能を使う必要があります。変数の型がなければ、オーバーロードの機能は必要ではなく、ただ単にif文で分岐すればよいだけなのでとても楽です。&lt;/p&gt;&lt;/blockquote&gt;
&lt;p class="p"&gt;おそらく、「オブジェクト志向設計」を誤解しています。それはおそらく、「オブジェクト指向設計」という字を使うから。oriented は「志向」であって、「指向」ではないのです。明鏡国語辞典には、こう書かれています。&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;志向:［名・他サ変］意識や思考がある対象に向かうこと。「平和国家の建設を━する」「アウトドア［本物・上昇］━」「指向」とも書かれるが、本来的な用法ではない。「指向」は単に物理的な方向をいう。&lt;/p&gt;
&lt;p&gt;指向：［名・他サ変］ある一定の方向をめざして進むこと。また、その方向へ向かわせること。「市場を東南アジア全域に━する」「━性アンテナ」&lt;/p&gt;&lt;/blockquote&gt;
&lt;p class="p"&gt;オブジェクトに指向しかしていないから、オブジェクトを使う事を考える。オブジェクトに志向するなら、そもそも「オブジェクトとは何か」について考えます。そうすると、「処理としては同一の処理を行いたい」など、処理に志向した考え方はしなくなります。オブジェクトに志向していれば、「このオブジェクトとあのオブジェクトで、同一の処理が適用できる」の様になるでしょう。&lt;/p&gt;
&lt;p class="p"&gt;もちろん、書いてあることもおかしくて、Java, C++, C# では、次のように書くだけです。&lt;/p&gt;
&lt;pre&gt;
void sub()
{
    // 「hoge().DoSomething();」とも書ける。
    IInterface arg = hoge();
    arg.DoSomething();
}
&lt;/pre&gt;
&lt;p class="p"&gt;あ、「変数に型がないと変更に強い」に、次のように書いてありましたっけ。「&lt;q&gt;たとえば右辺の返す型に変更があったとしても、受け取る側のソースコードを変更する必要はありません。&lt;/q&gt;」と。じゃぁ、同じように書きましょう。「型に追加があっても、実行するところのコードを変更、&lt;code&gt;if - else if&lt;/code&gt; を連ねる必要は有りません。勝手に、追加された型の DoSomething メソッドが実行されます。」と。記述量も少ないし、いいよね。&lt;/p&gt;
&lt;p class="p"&gt;で、わかっていただけないのが、この &lt;code&gt;arg&lt;/code&gt; 引数の型が &lt;code&gt;IInterface&lt;/code&gt; 以外に変更になったとき、静的型付き言語ではコンパイルすることで検出できるのですが、「動的型付け言語&amp;#8230;といって良いのかな？&amp;#8230;では、実行&amp;#8220;しなければ&amp;#8221;わからない」のうち、「しなければ」が「すれば」なのか、どっちだ？！という点。同じように、「テストすればわかる」なのか、「テストしなければわからない」なのか、という問題もある。コメントをされている方々は「しなければ」なのですが、著者さんは「すれば」なんですね。&lt;/p&gt;
&lt;p class="p"&gt;で、これについては、思うのです。「経験のないものはわからない」と。&lt;/p&gt;
&lt;p class="p"&gt;もし、著者さんが、小規模の開発、小規模物件の追加改造しかされた経験がないなら、「すれば」でしょう。しかし、大規模から巨大規模の開発しか経験されていない方なら、「しなければ」でしょう。&lt;/p&gt;
&lt;p class="p"&gt;この間、必要に駆られて SQLite3 を触ったのですが、これって、型の宣言って、無視しやがるのね。INTEGER と宣言したのに、文字列も実数も格納できてしまうorz 私としては「怖い」のですが、アプリケーションの設定を簡易的に保存する手段としては、まぁ、良いかもしれませんね。でも、基幹業務に使いたいとは思わないなぁ。&lt;/p&gt;
&lt;p class="p"&gt;そういうことで、小手先の技でチョイチョイとつくって、全体を見渡せる範囲に収まっているなら、動的型付け言語って、便利だと思います。一人で全体を見渡せないなら、静的型付き言語の方が便利です。&lt;/p&gt;&lt;img src ="http://blogs.wankuma.com/jitta/aggbug/319251.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>はなおか じった</dc:creator><title>オブジェクトを指向してみる／そもそも「オブジェクト」って、何？</title><link>http://blogs.wankuma.com/jitta/archive/2010/06/19/190381.aspx</link><pubDate>Sat, 19 Jun 2010 22:29:00 GMT</pubDate><guid>http://blogs.wankuma.com/jitta/archive/2010/06/19/190381.aspx</guid><wfw:comment>http://blogs.wankuma.com/jitta/comments/190381.aspx</wfw:comment><comments>http://blogs.wankuma.com/jitta/archive/2010/06/19/190381.aspx#Feedback</comments><slash:comments>5</slash:comments><wfw:commentRss>http://blogs.wankuma.com/jitta/comments/commentRss/190381.aspx</wfw:commentRss><trackback:ping>http://blogs.wankuma.com/jitta/services/trackbacks/190381.aspx</trackback:ping><description>&lt;p class="p"&gt;「&lt;A href="http://blogs.wankuma.com/jitta/archive/2010/05/28/189520.aspx"&gt;オブジェクトを指向してみる／何故インスタンスを作るの？&lt;/a&gt;」の続き、ってことで。&lt;/p&gt;
&lt;br&gt;
&lt;p class="p"&gt;元ネタのみながわさんのコラムでは、次のように書かれています。これを考察してみましょう。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p class="quoteSource"&gt;&lt;a href="http://el.jibun.atmarkit.co.jp/minagawa/2010/04/post-ebc4.html" title="⇒atmarkit.co.jp" class="outerLink"&gt;実はオブジェクト指向ってしっくりこないんです！&lt;/a&gt;（システムエンジニア 生き残りの極意）より：&lt;/p&gt;
&lt;p&gt;オブジェクト指向は、結局のところホントにモノ（オブジェクト）に使われている記法、例えばGUI コンポーネント、データベース、ファイルなどであって、プログラムのアルゴリズムとは無関係のものである。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p class="p"&gt;ふむ。確かに、「オブジェクト」って、なんでしょう？&lt;/p&gt;
&lt;p class="p"&gt;引用したところには、「&lt;q&gt;例えば GUI コンポーネント、データベース、ファイルなどであって、プログラムのアルゴリズムとは無関係&lt;/q&gt;」と書かれています。これ、「プログラムのアルゴリズムとは無関係」に、強く、興味を持ちました。はたして、無関係なのでしょうか。&lt;/p&gt;
&lt;p class="p"&gt;とりあえず、この時点では、無関係ではないと思います。&lt;/p&gt;
&lt;p class="p"&gt;では、&amp;#8220;アルゴリズム&amp;#8221;って、なんでしょうか。ここから始めましょう。「アルゴリズム：プログラムを作るときに用いる、問題を解決するための手順・計算方法。◇アラビアの数学者アル＝フワリズミにちなむ。もと、算用数字を用いた筆算の意。（明鏡国語辞典）」だそうです。さて、オブジェクト志向は「プログラムの手順」とは関係がないのでしょうか。関係がないとすると、どの様に関係がないのでしょう。&lt;/p&gt;
&lt;p class="p"&gt;その為にはまず、「オブジェクト志向言語」において、「オブジェクト」とされる物は、いったいなんでしょうか。&lt;/p&gt;
&lt;p class="p"&gt;私は、「データと、それを扱うための手続きを組み合わせたもの」だと思います。&lt;/p&gt;
&lt;br&gt;
&lt;p class="p"&gt;我々は、現実に発生している問題を解決するために、コンピューターの中に問題を投影し、プログラミング言語等を用いて問題を解決する方法を組み立てます。つまり、「会員名簿の管理」であったり、「勤怠情報の管理」であったり、「写真に写っている人を判別する」であったり、「宇宙船の姿勢を制御する」であったりという問題を解決するためにコンピューターを使います。そこには、「処理するべき情報」が存在しています。そしてその情報には、「処理されるべき手順」が存在しています。この、「処理すべき情報」に対して「処理すべき手順」を見つけ出し、ひとまとまり（パッケージ）にして扱うことが、「オブジェクト指向処理」（勝手用語）だと考えます。&lt;/p&gt;
&lt;p class="p"&gt;「オブジェクト志向プログラミング」と、「プロセス志向プログラミング」の違いは、何に志向するか、意識や思考を向ける対象にあるのではないでしょうか。プロセス志向では、「為すべきこと」を為す手順に志向します。オブジェクト志向では、「為すべきこと」に関係するオブジェクトに志向します。従って、プロセスに志向しながら、オブジェクトを使うことはできないのではないでしょうか。ただし、オブジェクト志向では、「情報と、その操作手順」がオブジェクトですから、最終的には、プロセスにも志向しなければなりません。&lt;/p&gt;
&lt;p class="p"&gt;では、なぜ、オブジェクトに志向する、すなわち、情報と、その操作手順をパッケージするのでしょうか。&lt;/p&gt;
&lt;p class="p"&gt;私が最初にオブジェクト志向言語に触れたのは、当時在籍していた課でオブジェクト志向言語を扱う最初、または2番目の事案でした。そして課長が、こう尋ねました。「オブジェクト志向って、どんなもん？」。まだ触って間もないので、「どう？」と聞かれて困ったのですが、こう返答しました。「&lt;span style="font-size:120%;"&gt;メンテナンスがし易いようにするためのものだと思います。最初に時間をかけて設計して、後のメンテナンスが楽になるようにするものだと思います&lt;/span&gt;」。この感想は、今でも変わっていません。オブジェクト志向が、情報と情報を扱う手順をパッケージするのは、プログラム（あるいはシステム）のメンテナンスをし易くするためと考えます。&lt;/p&gt;
&lt;p class="p"&gt;プログラム（あるいはシステム）の「メンテナンス期間」とは、なんでしょうか。ここでは、「最初のリリースが終わってから、プログラム（あるいはシステム）が破棄されるまで」とします。あるいは、「最初のビルドが終わってから&amp;#8230;」でも良いかもしれません。&lt;/p&gt;
&lt;p class="p"&gt;つまり、オブジェクト志向ナントカとは、一度動くようになってから後の仕様変更に対して、如何に対応し易くするかを考えたナントカである、と考えます。&lt;/p&gt;
&lt;p class="p"&gt;では、どうして、パッケージ化すると、仕様変更に対して対応しやすくなるのでしょうか。&lt;/p&gt;
&lt;p class="p"&gt;たいていの場合、仕様変更は、扱う情報の変更を伴います。オブジェクト志向分析がなされ、オブジェクト志向設計がなされているなら、変更が起こった情報を特定しやすくなります。また、その情報を扱う方法は、他の情報からは独立しているはずですから、情報処理手順の変更による影響を、他の情報へ伝播させにくくなります。他の情報や、情報処理方法が、他の情報を変更したことによる影響を受けないのなら、修正の範囲は小さくなり、テストの範囲も小さくて済みます。これらの範囲が小さいと言うことは、工数の減少にも繋がります。&lt;/p&gt;
&lt;p class="p"&gt;実際に、このような設計を行うには、かなりの経験が必要だと思います。しかし、特に Java や .NET Framework では、用意されているフレームワークにあるクラスが、高度に抽象化されています。これによって、使う人がオブジェクトに志向しなくても、オブジェクト志向言語を使ったプログラミングができてしまいます。&lt;/p&gt;
&lt;p class="p"&gt;「オブジェクト志向言語を使ったプロセス志向プログラミング」と、「オブジェクト志向プログラミング」。この二つは、混同してはいけないと思います。&lt;/p&gt;&lt;img src ="http://blogs.wankuma.com/jitta/aggbug/190381.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>はなおか じった</dc:creator><title>オブジェクトを指向してみる／何故インスタンスを作るの？</title><link>http://blogs.wankuma.com/jitta/archive/2010/05/28/189520.aspx</link><pubDate>Fri, 28 May 2010 22:20:00 GMT</pubDate><guid>http://blogs.wankuma.com/jitta/archive/2010/05/28/189520.aspx</guid><wfw:comment>http://blogs.wankuma.com/jitta/comments/189520.aspx</wfw:comment><comments>http://blogs.wankuma.com/jitta/archive/2010/05/28/189520.aspx#Feedback</comments><slash:comments>44</slash:comments><wfw:commentRss>http://blogs.wankuma.com/jitta/comments/commentRss/189520.aspx</wfw:commentRss><trackback:ping>http://blogs.wankuma.com/jitta/services/trackbacks/189520.aspx</trackback:ping><description>&lt;BLOCKQUOTE&gt;
&lt;P class=quoteSource&gt;&lt;A class=outerLink title=⇒atmarkit.co.jp href="http://el.jibun.atmarkit.co.jp/minagawa/2010/04/post-ebc4.html"&gt;実はオブジェクト指向ってしっくりこないんです！&lt;/A&gt;（システムエンジニア 生き残りの極意）より：&lt;/P&gt;
&lt;P&gt;　「自分でクラスを作ってオブジェクト指向っぽいことをしている」なんてことはまったくない。特に「メンバー関数をstatic宣言すればインスタンス宣言をしなくてもいい」ということ知ってからは、メンバー関数を従来のファンクションのように使っている。共有変数も、pubulic static宣言していまう。したがってプロパティなんて作らない。&lt;/P&gt;
&lt;P&gt;　staticを理解していない人のコードを見ると、いちいちインスタンス宣言しているので笑ってしまう。データベースにアクセスするアプリケーションをC#で書いているのだが、Visual Studioで供給しているSQL関係のクラスを使えばできてしまうのだから。&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P class=p&gt;向こうでコメントしようかと思ったけど、もったいないのでエントリーにする。&lt;/P&gt;
&lt;P class=p&gt;さて、コメントに、コラム著者のサイト&lt;A class=outerLink title=⇒infoseek.co.jp href="http://wondsky.hp.infoseek.co.jp/index.html"&gt;SE WORLD システムエンジニアの世界 IT技術&lt;/A&gt;というサイトへのリンクがありました。そしてそこには、「ASP.NET ASP.NETのサンプルコードです。典型的なコードパターンを列挙してみました」というのがあるので、ここを見ます。&amp;#8230;だって、MVP &lt;STRONG&gt;for ASP.NET&lt;/STRONG&gt; なんだもん、一応。その中で、これを取り上げてみる。&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P class=quoteSource&gt;&lt;A class=outerLink title=⇒infoseek.co.jp href="http://wondsky.hp.infoseek.co.jp/vs2005.htm"&gt;ファイルアップロードコントロール&lt;/A&gt;（SE WORLD システムエンジニアの世界 IT技術）より：&lt;/P&gt;&lt;PRE class=code&gt;&lt;CODE&gt;
using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
public partial class _Default : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
    }
    protected void Button1_Click(object sender, EventArgs e)
    {
        if (FileUpload1.HasFile) {
            //string strSaveAs = "C:/test/" + FileUpload1.FileName;
            string strSaveAs = "//マシン名/フォルダ名/" + FileUpload1.FileName;
            FileUpload1.SaveAs(strSaveAs);
        }
    }
}&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;　リモートマシンにも保存できるが、アクセス権がeveryone 書き込みになってないと難しい。ちなみにIIS6.0のASP.NETのプログラムアカウントのデフォルト値はNetwork Serviceです。&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P class=p&gt;センタリングされていて見にくいので、見やすいように修正しました。&lt;/P&gt;
&lt;P class=p&gt;さて、この中で、&lt;CODE&gt;FileUpload1&lt;/CODE&gt; というのが、&lt;CODE&gt;FileUpload&lt;/CODE&gt; クラスのインスタンスです。そして、&lt;CODE&gt;HasFile&lt;/CODE&gt; とか、&lt;CODE&gt;SaveAs&lt;/CODE&gt; というのは、&lt;CODE&gt;FileUpload&lt;/CODE&gt; クラスのメンバーです。では、&lt;Q&gt;いちいちインスタンス宣言しているので笑ってしまう&lt;/Q&gt;ということなので、インスタンス宣言しなくてもいいように（インスタンスを作らなくてもいいように）、&lt;CODE&gt;FileUpload&lt;/CODE&gt; クラスのメンバーが全て &lt;Q&gt;pubulic static宣言&lt;/Q&gt;されていると仮定します。つまり、「&lt;Q&gt;pubulic static宣言&lt;/Q&gt;だと、こんなに使いにくいぞ」ということを示すことで、なぜインスタンスを作るのかを理解してみよう、という試みです。&lt;/P&gt;&lt;BR&gt;
&lt;P class=p&gt;&lt;CODE&gt;FileUpload&lt;/CODE&gt; クラスのメンバーが全て静的なので、1ページからは1度に1つのファイルしか、アップロードできなくなります。複数のファイルをアップロードしようとすると、&lt;CODE&gt;FileUpload&lt;/CODE&gt; クラスから導出して、&lt;CODE&gt;FileUpload1&lt;/CODE&gt; クラス、&lt;CODE&gt;FileUpload2&lt;/CODE&gt; クラス、&lt;CODE&gt;FileUpload3&lt;/CODE&gt;...と、インスタンスの代わりにクラスを複数作らなければなりません。これは、「コードを書く手間」を考えると、とても不便ではないでしょうか。また、それぞれでクラスが違うのですから、最初に配列を宣言して、インスタンスを作るというわけにもいきません。これも、不便ではないでしょうか。&lt;/P&gt;&lt;PRE class=code&gt;&lt;CODE&gt;
// 配列を宣言して、インスタンスを生成する
FileUpload[] fileUp = new FileUpload[10];
foreach (FileUpload f in fileUp) {
    f = new FileUpload();
}
// メンバーを静的にすると、上記のように出来ず、
// クラスを10個作らなければならない
class FileUpload01 : FileUpload {};
class FileUpload02 : FileUpload {};
class FileUpload03 : FileUpload {};
...
// その後、配列に登録する。
FileUpload[] fileUp = new FileUpload[10];
fileUp[0] = FileUpload01; &lt;SPAN style="COLOR: red"&gt;おおっと、クラスは登録できないや！！&lt;/SPAN&gt;
&lt;/CODE&gt;&lt;/PRE&gt;&lt;BR&gt;
&lt;P class=p&gt;これで、「static にせずにインスタンスを作るのはなぜ？」の答（のひとつ）になるかな？&lt;/P&gt;&lt;BR&gt;
&lt;P class=p&gt;それでは、反論も考えてみましょう。&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P class=quoteSource&gt;2010年4月28日 (水) 08:53&lt;/P&gt;
&lt;P&gt;むしろC言語の構造体はいやになるほど書いたから、逆にビジネスロジックのクラスの優位性についてピンとこないのです。&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P class=p&gt;なるほど。&lt;/P&gt;
&lt;P class=p&gt;&lt;CODE&gt;FileUpload&lt;/CODE&gt; は、データだけを持つ構造体であるとすると、どうなるでしょうか。例えば、こんな定義がどこかにあって、それを使って保存することになります。&lt;/P&gt;&lt;PRE class=code&gt;&lt;CODE&gt;
public class StaticFunctions {
    private StaticFunctions() {};
    public static void SaveAs(const FileUpload fu, const string saveFileName) {
        // 処理は省略
    }
    public static void SaveAs(const FileStream fs, const string saveFileName) {
        // 処理は省略
    }
    public static void SaveAs(const MyStructure ms, const string saveFileName) {
        // 処理は・・・&lt;SPAN style="COLOR: red"&gt;おおっと、オーバーロードさせてよかった？&lt;/SPAN&gt;
    }
}
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P class=p&gt;私は、似て非なる構造体を多数書いたので、クラスの方がいい、と思いましたね。&lt;/P&gt;&lt;BR&gt;
&lt;P class=p&gt;様々なコメントが付いていますが、このコメントがもっとも秀逸だと思います。&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P class=quoteSource&gt;2010年4月27日 (火) 16:14&lt;/P&gt;
&lt;P&gt;OOPは理解できないから使わない、と主張されるのは結構だと思います。&lt;/P&gt;
&lt;P&gt;しかし、自分が理解できないからといって「知ったかぶってOOPするヤツら笑っちゃう」というような論調で話を進められるのは宜しくないですね。&lt;/P&gt;
&lt;P&gt;変数が隠蔽できるか否かはOOPの本質ではないんです。そもそも言語仕様としてクラスやプロパティがあるかどうかも本質ではないのです。言語仕様はよりOOPしやすくするための道具にすぎません。&lt;/P&gt;
&lt;P&gt;極意を示すコラムなのですから、OOPを理解したうえで「俺はOOPしない！」と主張する生え抜きのロートルエンジニア（＜良い意味で言っています）が、その経験と技術でもってOOP全盛時代を生き残る方法論を論じる、くらいのレベルの高さがあって欲しいですね。&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P class=p&gt;こんな風に、簡単にまとめられる技量が欲しいです。。。&lt;/P&gt;&lt;img src ="http://blogs.wankuma.com/jitta/aggbug/189520.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>はなおか じった</dc:creator><title>「オブジェクト指向」ってなんじゃらほい？（その3）</title><link>http://blogs.wankuma.com/jitta/archive/2009/01/20/166558.aspx</link><pubDate>Tue, 20 Jan 2009 23:30:00 GMT</pubDate><guid>http://blogs.wankuma.com/jitta/archive/2009/01/20/166558.aspx</guid><wfw:comment>http://blogs.wankuma.com/jitta/comments/166558.aspx</wfw:comment><comments>http://blogs.wankuma.com/jitta/archive/2009/01/20/166558.aspx#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://blogs.wankuma.com/jitta/comments/commentRss/166558.aspx</wfw:commentRss><trackback:ping>http://blogs.wankuma.com/jitta/services/trackbacks/166558.aspx</trackback:ping><description>&lt;p class="p"&gt;前回は、オブジェクト志向プログラミングだと変更がしやすいと、書きました。本当でしょうか？検証してみましょう。&lt;/p&gt;
&lt;p class="p"&gt;では、元のお題「ローカル ディスク上の任意の場所にあるファイルを、ローカル ディスク上の任意の場所に移動する。」を変更します。&lt;br&gt;
「ローカル ディスク上の任意の場所にあるファイルを、ローカル ディスク上の任意の場所、または FTP サーバー上の任意の場所に移動する。」&lt;/p&gt;
&lt;br&gt;
&lt;p class="p"&gt;移動先に、FTP サーバーを追加しました。さて、プロセス志向ナントカ、オブジェクト志向ナントカは、それぞれどのように変わるでしょうか。&lt;/p&gt;
&lt;p class="p"&gt;プロセス志向設計では、処理の途中で「移動先が FTP サーバーなら、&amp;#8230;」と、分岐が必要です。しかし、オブジェクト志向設計は、「ファイルの属性「場所」を、新しい場所に設定する。」のまま変わりません。その「新しい場所」がローカル ディスクなのか、FTP サーバーなのかは、この設計では揺らがないのです。&lt;/p&gt;
&lt;p class="p"&gt;ただし、プログラミングのレベルにまで落とせば、どこかで「ファイルを移動させる」という処理をしなければなりません。プロセス志向プログラミングでは、プロセス（手続き）の中に「移動させる」を書きました。オブジェクト志向プログラミングでは、いくつかの方法があります。&lt;/p&gt;
&lt;br&gt;
&lt;p class="p"&gt;ひとつは、ファイル オブジェクトのメソッドの中に、プロセス志向プログラミングと同じように書き込む方法です。「オブジェクト志向」といっても、どこかでプロセスにも目を向けなければなりません。そこに実装するのがひとつ。&lt;/p&gt;
&lt;p class="p"&gt;しかし、そんなことをしていては、本当に「変更が容易」とは言い難いです。新しい「移動先」を追加するごとに、ファイル クラスを修正しなければなりません。それではプロセス志向プログラミングとかわりありません。&lt;/p&gt;
&lt;br&gt;
&lt;p class="p"&gt;そこで、やはりオブジェクトに志向することにします。&lt;/p&gt;
&lt;p class="p"&gt;「ファイルを移動する」ということは、「どこかにあるファイルを、どこかへ持って行く」ということです。「持って行く」です。誰が？はい、ここに「オブジェクト」が潜んでいました。「ファイルの移動を行うオブジェクト」です。&lt;/p&gt;
&lt;p class="p"&gt;この、「ファイルの移動を行うオブジェクト」が、「ローカル ディスクからローカル ディスクへ移動させる」ことや、「ローカル ディスクから FTP サーバー上のディレクトリへ移動させる」ことが出来ればいいのです。つまり、「移動」というメソッドに、「ファイル」オブジェクトと「新しい場所」をパラメータとして引き渡せるようにします。&lt;/p&gt;
&lt;p class="p"&gt;とはいえ、これでもやはり、新しい場所について新しい概念が追加されると、「ファイルの移動を行うオブジェクト」の中を変更しなければなりません。先ほどと変わりがないだけでなく、クラスが増えた分、管理が面倒になるだけです。&lt;/p&gt;
&lt;p class="p"&gt;ここで、オブジェクト志向ナントカにあって、プロセス志向ナントカにはないものを使います。汎化と特化です。&lt;/p&gt;
&lt;p class="p"&gt;今、「ファイルの移動を行うオブジェクト」に対して、「ローカル ディスクからローカル ディスクへ移動させる」「ローカル ディスクから FTP サーバー上のディレクトリへ移動させる」を考えました。「ファイルを移動させる」という動作について、移動先を「ローカル ディスク」「FTP サーバー上のディレクトリ」という場合に分けました。これが特化です。「移動させる」という汎用的な機能を、移動先を特定し、絞り込んだわけです。反対に、「ローカル ディスク上の」という特定された機能から、「いや、FTP とか、HTTP サーバーとかもあるかもしれない」と考え、場所を特定しない、汎用的な「移動する」へと考えを広げることが汎化です。もっとも、ここでは「機能」ですが、オブジェクトに志向するのですから、機能だけでなく、情報も対象になります。&lt;/p&gt;
&lt;br&gt;
&lt;p class="p"&gt;もうひとつ、オブジェクトに指向した例です。先ほどは、「オブジェクトを移動させるもの」を作りました。しかし、ファイルというオブジェクトが「移動してくる場所」も、オブジェクトです。ですから、「場所オブジェクト」に「指定されたファイルを作る」メソッドと、「指定されたファイルを消す」メソッドを用意することもできます。この方法でも、「場所」は汎化、特化で表されます。&lt;/p&gt;
&lt;br&gt;
&lt;p class="p"&gt;では、この汎化と特化によって、何がどうなるのでしょう？こんなふうになります。&lt;/p&gt;
&lt;ol&gt;
 &lt;li&gt;&lt;p&gt;ファイルのインスタンスを作成する。&lt;/p&gt;&lt;/li&gt;
 &lt;li&gt;&lt;p&gt;「ファイルを移動させる」オブジェクト（「場所」オブジェクト）を作成する。&lt;/p&gt;&lt;/li&gt;
 &lt;li&gt;&lt;p&gt;「ファイルを移動させる」オブジェクト（「場所」オブジェクト）によって、ファイルを移動させる。&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p class="p"&gt;これによって、ファイルの場所に関する新しい概念が出来たとき、その概念に特化した「ファイルを移動させるクラス」を作成することになります。クラスが分かれているので、「移動させる」部分については、ファイルの場所が増えることによる変更の影響を受けません。新しい「ファイルを移動させる」オブジェクトが作成できていることを確認すれば、すでにあったクラスについて、変更の影響を受けていないことを確認する必要はありません。&lt;/p&gt;
&lt;p class="p"&gt;しかし、大きな欠点というか、面倒な点があります。前回は「移動させる」ことをファイル クラスにさせていましたが、今回で移動させるクラスに切り出しました。最初に行った分析が十分ではなかったということです。このように、オブジェクト志向開発による変更が容易であるためには、「最初の分析・設計が十分に行えていれば」という条件がつくのです。この条件こそ、オブジェクト志向開発を難しいものにしているのではないかと思います。&lt;/p&gt;&lt;img src ="http://blogs.wankuma.com/jitta/aggbug/166558.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>はなおか じった</dc:creator><title>「オブジェクト指向」ってなんじゃらほい？（その2）</title><link>http://blogs.wankuma.com/jitta/archive/2008/12/28/165210.aspx</link><pubDate>Sun, 28 Dec 2008 21:14:00 GMT</pubDate><guid>http://blogs.wankuma.com/jitta/archive/2008/12/28/165210.aspx</guid><wfw:comment>http://blogs.wankuma.com/jitta/comments/165210.aspx</wfw:comment><comments>http://blogs.wankuma.com/jitta/archive/2008/12/28/165210.aspx#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://blogs.wankuma.com/jitta/comments/commentRss/165210.aspx</wfw:commentRss><trackback:ping>http://blogs.wankuma.com/jitta/services/trackbacks/165210.aspx</trackback:ping><description>&lt;P class=p&gt;「プロセス志向」と「オブジェクト志向」の比較を続けます。&lt;/P&gt;
&lt;P class=p&gt;要望を分析する段階で、プロセス志向ではいきなり実装に近いことを考えることが出来ました。それに対してオブジェクト志向では、オブジェクトを抽出するところから始まりました。つまり、設計にはいるまでに時間がかかりそうです。&lt;/P&gt;
&lt;P class=p&gt;ところで、アプリケーション プログラムのライフサイクルを思い浮かべてください。まず、「計画」を行います。そして、「設計」を行います。設計に基づいて「実装」を行います。実装ができると、「テスト」を行います。設計、実装、テストは、小さく繰り返すことがあります。そしてリリースされ、「メンテナンス」に入ります。メンテナンスをしながら気がついて点などを次のリリースのために「計画」に組み入れます。・・・。&lt;/P&gt;
&lt;P class=p&gt;このように、「計画」→「設計」→「実装」→「テスト」→「メンテナンス」を繰り返すわけですが、一番最初の「計画」「設計」以外は、「最初のリリースのメンテナンスである」と、言えないでしょうか。そう言っても良いなら、アプリケーション プログラムは、設計や実装の期間と比べると、比較にならないほど長いメンテナンス期間を持っていると言えるでしょう。&lt;/P&gt;
&lt;P class=p&gt;私が「オブジェクト志向プログラミングっていいなぁ」と思うのは、この「メンテナンス」期間においてです。&lt;/P&gt;
&lt;P class=p&gt;前回、プロセス志向のところで「「ファイルの移動をどうやって実現するか」ということが、よくわかると思います。」と書きました。しかし、オブジェクト志向については、該当するものを書いていません。では、オブジェクト志向設計では、何がわかりやすいのでしょうか。&lt;/P&gt;
&lt;P class=p&gt;前回のお題は、こうでした。&lt;BR&gt;「ローカル ディスク上の任意の場所にあるファイルを、ローカル ディスク上の任意の場所に移動する。」&lt;BR&gt;そして、オブジェクト志向プログラミングに対する設計は、こうです。&lt;BR&gt;「ファイルの属性「場所」を、新しい場所に設定する。」&lt;/P&gt;
&lt;P class=p&gt;どうでしょう？お題がほぼそのまま設計になっています。いくつかの制約、前提条件がありますが、それらが整っていれば、要望から仕様を作ること、仕様から実装を行うことが、とても容易に行えます。その制約、前提条件とはなんでしょう。オブジェクトが、オブジェクトとしてできあがっていることです。このため、最初の設計では苦労すると思います。しかし、長いメンテナンス期間において、仕様書の何を変更すれば実装のどこを変更しなければならないか、明確になっているのではないでしょうか。&lt;/P&gt;&lt;BR&gt;&lt;BR&gt;
&lt;P class=p&gt;ということで、次回は実際に変更を行ってみようと思います。&lt;/P&gt;
&lt;P class=comment&gt;まじ、続けられるのか？&lt;/P&gt;&lt;img src ="http://blogs.wankuma.com/jitta/aggbug/165210.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>はなおか じった</dc:creator><title>「オブジェクト指向」ってなんじゃらほい？</title><link>http://blogs.wankuma.com/jitta/archive/2008/12/26/165061.aspx</link><pubDate>Fri, 26 Dec 2008 22:33:00 GMT</pubDate><guid>http://blogs.wankuma.com/jitta/archive/2008/12/26/165061.aspx</guid><wfw:comment>http://blogs.wankuma.com/jitta/comments/165061.aspx</wfw:comment><comments>http://blogs.wankuma.com/jitta/archive/2008/12/26/165061.aspx#Feedback</comments><slash:comments>435</slash:comments><wfw:commentRss>http://blogs.wankuma.com/jitta/comments/commentRss/165061.aspx</wfw:commentRss><trackback:ping>http://blogs.wankuma.com/jitta/services/trackbacks/165061.aspx</trackback:ping><description>&lt;p class="p"&gt;タイトルのままだと某氏に怒られるのでww、「オブジェクト志向プログラミングってなんじゃらほい？」ってことで。なお、タイトルは「指向」を使いましたが、前回のエントリで「志向」の方が正しいような気がしたので、このエントリでは、以後「志向」を使います。&lt;/p&gt;
&lt;br&gt;
&lt;p class="p"&gt;「オブジェクト志向プログラミング」は、1970年代の終わり頃から、新しいプログラミング手法として広まり始めました。ここで注目したいのは、「新しい」というところです。&lt;/p&gt;
&lt;p class="p"&gt;「新しい」というのは、2種類、あるいはそれ以上の考え方があります。1つは、「今現在」において、発展中であるということ。もうひとつは、ある時点において、何かの代わりとして登場したということです。ここで「新しいプログラミング手法」というのは、それまであったプログラミング手法に変わる手法として登場した、ということです。&lt;/p&gt;
&lt;p class="p"&gt;「代わり」なのですから、「それまであった」があるわけです。この2つを比較することで、「オブジェクト志向プログラミング」というものがどういうものか、見えてくるのではないでしょうか。&lt;/p&gt;
&lt;br&gt;
&lt;p class="p"&gt;では、「それまであった」ものとは、どんなものでしょうか？私はこれを、「プロセス志向プログラミング」と呼んでいます。この2つを比較します。&lt;/p&gt;
&lt;p class="p"&gt;その前に、「プログラミング」とは、どのような作業でしょうか。コードを書く。コンピュータにわかるコードを書く。コードを書いてコンパイラに通す。など、返ってきそうです。ところで、「書く」のでしょうか？私も「書く」という言葉を使いますが、気持ち的には「コードを組み立てる」つもりでいます。&lt;/p&gt;
&lt;p class="p"&gt;私は、「プログラミング」を、「ブロック遊び」にたとえることがあります。レゴとか、積み木でもいいでしょう。ブロックは、すでに形を持っています。その形を組み合わせて、何かを作ります。プログラミングも同じではないでしょうか。我々が使用するコードの大部分は、すでに誰かによって作られたコードの断片です。その断片の組み合わせ方によって、様々な動作を行うアプリケーション プログラムができあがります。&lt;/p&gt;
&lt;p class="p"&gt;さて、この、「断片を組み合わせる」という作業。この作業の進め方について、「プロセス志向」と「オブジェクト志向」を比較します。しかし、具体的に比較するものがあった方が比較しやすいですから、具体的な例題を考えます。&lt;/p&gt;
&lt;p class="p"&gt;「ローカル ディスク上の任意の場所にあるファイルを、ローカル ディスク上の任意の場所に移動する」を考えます。「rename や mv で一発じゃない」とは、いわないでください。その中身を考えます。&lt;/p&gt;
&lt;p class="p"&gt;まず、プロセス志向です。プロセス志向ナントカでは、処理を行う手順を中心に考えます。すると、こんなふうになるかと思います。&lt;/p&gt;
&lt;ol&gt;
	&lt;li&gt;&lt;p&gt;移動させるファイルを開く。&lt;/p&gt;&lt;/li&gt;
	&lt;li&gt;&lt;p&gt;移動先にファイルを作る。&lt;/p&gt;&lt;/li&gt;
	&lt;li&gt;&lt;p&gt;移動元から、用意したバッファがいっぱいになるまで読み取る。&lt;/p&gt;&lt;/li&gt;
	&lt;li&gt;&lt;p&gt;移動先に書き込む。&lt;/p&gt;&lt;/li&gt;
	&lt;li&gt;&lt;p&gt;移動元のファイル ポインタが、最後を指すまで繰り返す。&lt;/p&gt;&lt;/li&gt;
	&lt;li&gt;&lt;p&gt;移動元のファイルを閉じる。&lt;/p&gt;&lt;/li&gt;
	&lt;li&gt;&lt;p&gt;移動先のファイルを閉じる。&lt;/p&gt;&lt;/li&gt;
	&lt;li&gt;&lt;p&gt;移動元のファイルを削除する。&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p class="p"&gt;これによって、「ファイルの移動をどうやって実現するか」ということが、よくわかると思います。&lt;/p&gt;
&lt;p class="p"&gt;次に、オブジェクト志向です。オブジェクト志向ナントカでは、処理の手順ではなく、処理を行う何かに注目します。それを「オブジェクト」と呼び、クラスで表します。では、この例題の「何か」とは、なんでしょうか？それを探すところからスタートです。&lt;/p&gt;
&lt;p class="p"&gt;「オブジェクト志向ナントカ」の本を見ると、たいてい「名詞を探せ」とあります。では、名詞を探してみましょう。次のものが名詞です。&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;ローカル ディスク&lt;/li&gt;
	&lt;li&gt;ファイル&lt;/li&gt;
	&lt;li&gt;場所&lt;/li&gt;
&lt;/ul&gt;
&lt;p class="p"&gt;これら全てがクラスになるかというと、違います。これらは「クラス候補」であって、ここからクラスにする必要があるか、選別します。&lt;/p&gt;
&lt;p class="p"&gt;「ローカル ディスク」は、「ローカル」が「ディスク」を制限するために修飾しているので、「ディスク」だけで良さそうです。しかし、例題には「ローカル ディスク上の任意の場所」と書かれていました。ディスクもまた、「場所」を制限するために修飾しています。よって、「ローカル ディスク」はクラスとはなりません。&lt;/p&gt;
&lt;p class="p"&gt;「ファイル」は、クラスになるでしょうか。これは、例題で操作される対象です。ですから、クラスとなります。&lt;/p&gt;
&lt;p class="p"&gt;「場所」は、どうでしょうか。場所は、ファイルがあるところを示すものですから、ファイルの属性と言えるでしょう。しかし、「ローカル ディスク上の」と、制約があります。この制約が守られているかどうかのチェックが必要です。このために、クラスとすることにします。&lt;/p&gt;
&lt;br&gt;
&lt;p class="p"&gt;では、オブジェクト志向プログラミングにおける、「ローカル ディスク上の任意の場所にあるファイルを、ローカル ディスク上の任意の場所に移動する」は、どう表現されるでしょうか。&lt;/p&gt;
&lt;ol&gt;
	&lt;li&gt;&lt;p&gt;ファイルのインスタンスを作成する。&lt;/p&gt;&lt;/li&gt;
	&lt;li&gt;&lt;p&gt;ファイルの属性「場所」を、新しい場所に設定する。&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p class="p"&gt;これだけです。ただし、ファイル クラスは、属性「場所」が変更されたらどう振る舞わなければならないか、定義されていなければなりません。その定義の中身は、上のプロセス志向ナントカの時と同じです。&lt;/p&gt;
&lt;br&gt;
&lt;p class="p"&gt;あるいは、こういう考え方も出来ます。&lt;/p&gt;
&lt;p class="p"&gt;このふたつを比べると、「オブジェクト志向プログラミング」の所以がわかるのではないでしょうか。先のものが「どうするか」だけを考えていることに対し、後のものは「何が、どうするか」を考えています。この「何が」が「オブジェクト」であり、「どうするか」よりも「何が」に志向する（意識を向ける）から「オブジェクト志向」なわけです。&lt;/p&gt;
&lt;br&gt;
&lt;p class="p"&gt;こうして、「従来の方法」と、「新しい方法」の違いを比較すると、不便な点も便利な点も、いろいろ見えてくるのではないでしょうか。&lt;/p&gt;
&lt;br&gt;
&lt;br&gt;
&lt;p class="p"&gt;と、従来の方法との違いを見る方法を提示したところで、今回はここまで。&lt;/p&gt;
&lt;p class="comment"&gt;続けられるのか？&lt;/p&gt;
&lt;img src ="http://blogs.wankuma.com/jitta/aggbug/165061.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>はなおか じった</dc:creator><title>オブジェクトの切り分け</title><link>http://blogs.wankuma.com/jitta/archive/2008/12/20/164480.aspx</link><pubDate>Sat, 20 Dec 2008 00:26:00 GMT</pubDate><guid>http://blogs.wankuma.com/jitta/archive/2008/12/20/164480.aspx</guid><wfw:comment>http://blogs.wankuma.com/jitta/comments/164480.aspx</wfw:comment><comments>http://blogs.wankuma.com/jitta/archive/2008/12/20/164480.aspx#Feedback</comments><slash:comments>11</slash:comments><wfw:commentRss>http://blogs.wankuma.com/jitta/comments/commentRss/164480.aspx</wfw:commentRss><trackback:ping>http://blogs.wankuma.com/jitta/services/trackbacks/164480.aspx</trackback:ping><description>&lt;BLOCKQUOTE&gt;
&lt;P class=quoteSource&gt;&lt;A href="http://blogs.wankuma.com/jitta/archive/2008/12/18/164339.aspx#164399"&gt;re: オブジェクトを思考する&lt;/A&gt;より：&lt;/P&gt;
&lt;P&gt;オブジェクト指向をたいして(全く？)理解してないですが、&lt;BR&gt;「私」クラスと「犬」クラスの２つがあって、&lt;BR&gt;実行ファイルでは私クラスの「犬に吠えろと言う」メソッドを呼び出し、&lt;BR&gt;その中から犬クラスの「吠えろ」メソッド(Shared←Newしないと言う意味で)を呼ぶのかと思ってました。&lt;/P&gt;
&lt;P&gt;&amp;#8230;根本的に違うのかな？それだと実行ファイルにあたるものがないか。&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P class=p&gt;ぱるとさん、コメントありがとうございます。コードを書こうと思ったので、エントリで返事させていただきます。&lt;/P&gt;&lt;BR&gt;
&lt;P class=p&gt;「オブジェクト指向プログラミング」において、「何をクラスとするか」ということについて、私はいつも迷っています。先のエントリでは「処理するデータの塊」としました。その「処理の単位」を、どう切り分けるか。それが迷うポイントです。&lt;/P&gt;
&lt;P class=p&gt;まず、犬クラスは、こんなふうに作れます。&lt;/P&gt;
&lt;pre class=code&gt;&lt;code&gt;// 犬クラス
public class 犬
{
    private List&amp;lt;Object&amp;gt; 飼い主;
    public 犬() {
        System.Diagnostics.Debug.WriteLine("犬が生まれた。");
    }
    public void Add飼い主(Object 誰か) {
        飼い主.Add(誰か);
    }
    public Object 命令を受ける(Object 誰に, string 何をする) {
        if (飼い主か？(誰に) == true) {
            パフォーマンス p = 言葉を解釈する(何をする);
            return p.Do(誰に);
        }
        return null;
    }
    private bool 飼い主か？(Object 誰) {
        foreach (Object obj in 飼い主) {
            if (対象.Compare(obj) == 0) {
                return true;
            }
        }
        return false;
    }
    private string 吠える(Object 対象) {
        if (飼い主か？(対象) == true) {
            return "ワン";
        } else {
            return "ウゥゥゥ";
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p clas="p"&gt;ん～。。。現実をプログラムに落とすのは、こういうときに無理があるね。「飼い主」は、ペットが認めるもので、外部から与えるものじゃない。そういう無理には、目をつむっていただこう。以下同じ。コンパイル出来ないけど、細かいことにこだわらないで。&lt;/p&gt;
&lt;p class="p"&gt;で、「私が犬に鳴けといったら、犬がワンと鳴いた。」です。「私」が実行ファイルの中にあるクラスであれば、こんなふうになります。あ、「ブー」は、昔飼っていた犬の名前です。&lt;/p&gt;
&lt;pre class="code"&gt;&lt;code&gt;
public class 人
{
    private List&amp;lt;Object&amp;gt; ペット;
    public 人() {
        System.Diagnostics.Debug.WriteLine("人が生まれた。");
    }
    public void 飼育する(Object 生き物) {
        ペット.Add(生き物);
        生き物.Add飼い主(this);
    }
    public void 命じる(Object 対象, string 命令) {
        対象.命令を受ける(this, 命令);
    }
}
void main() {
    Object 私 = new 人();
    犬 ブー = new 犬();
    私.飼育する(ブー);
    私.命じる(ブー, "吠える");
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p class="p"&gt;「私」が所有しない（知らない）ものに対してメッセージを送ることは出来ません。ですから、「私」は「飼育する」ことで「犬」のインスタンスを手に入れます。そして、そのインスタンスに対してアクションを起こします。起こすアクションは、「「吠えろ」と命じる」です。ここで、命令はたくさんあるし、それが出来るかどうかはわからないので、リフレクションとかマップとかで、言葉と実際の動作（メソッド）を決定することとします。ペットは、当然、誰が命じたかによって行動を変えるでしょう。というわけで、こんなコードになりました。&lt;/p&gt;
&lt;br&gt;
&lt;p class="p"&gt;で、「私＝実行ファイル」だと、こうなります。あるふさんのイメージは、こんな感じだと思います。&lt;/p&gt;
&lt;pre class="code"&gt;&lt;code&gt;
void main() {
    犬 ブー = new 犬();
    ブー.いたずらされる(null);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p class="p"&gt;しかし、「犬」が「実行ファイル」の「外」にある場合。こんな感じ。&lt;/p&gt;
&lt;pre class="code"&gt;&lt;code&gt;
void main(string[] args) {
    if (args.Length == 1) { return; }
    Object obj = 文字列を元にプロセスを探す(args[1]);
    obj.いたずらされる(null);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p class="p"&gt;適当ですんません。&lt;/p&gt;
&lt;p class="p"&gt;他、リフレクションを使ってインスタンスを作るとか、RPC 使うとか、.NET はリモーティングか。&lt;/p&gt;
&lt;p class="p"&gt;そして、これらの中で、「私」というものの定義が重要なんじゃないかと思うのです。先のエントリでは「私の立ち位置」としました。「私」って、何？&lt;/p&gt;
&lt;p class="p"&gt;私は、プログラムを行っています。ですから、自己定義言語なんてのもありますが、そんなことを話しているのではないので削除します。私は、プログラムを作成しています。ですから、私はプログラムではありません。しかし、私は、あのクラスやこのクラスに、「あれしろ、これしろ」と命じます。つまり、コードを書きます。そして、実行時には、それは実行ファイルが実際に行います。&lt;/p&gt;
&lt;p class="p"&gt;はたして、本当にそうなのでしょうか？実行ファイルが命じているのでしょうか？&lt;/p&gt;
&lt;p class="p"&gt;そういうとらえ方も出来るのかもしれません。私は、そうではなく、例えば演劇でいうところの監督？脚本家？そんなものだと思っています。クラスは、俳優が演じる役割です。俳優を役に割り当てることで、インスタンス化されます。じゃぁ、実行ファイルとは何か。動くように命じるのは監督です。監督は私です。実行ファイルは、俳優が演じている場所、舞台です。&lt;/p&gt;
&lt;p class="p"&gt;オブジェクト志向プログラミングは、現実のオブジェクト間にある関係を、プログラミングの世界に投影しようとするところから生まれました。そのため、オブジェクト志向プログラミングを説明したものの多くに、鯛焼きだの車だの生物だの、現実に沿ったものを使って説明しようとしています。&lt;/p&gt;
&lt;p class="p"&gt;しかし、そのことによって、オブジェクト志向プログラミングの理解を遠ざけているのではないか、と思っています。なぜか。現実のプログラミングにおいて、鯛焼きや車や生物をプログラミングすることはないからです。現実と説明とのギャップが広すぎて、理解を難しくしているのではないでしょうか。&lt;/p&gt;
&lt;br&gt;
&lt;br&gt;
&lt;p class="p"&gt;あ、あれ？ぱるとさんに答えてない？ごめんなさい！！&lt;/p&gt;&lt;img src ="http://blogs.wankuma.com/jitta/aggbug/164480.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>はなおか じった</dc:creator><title>オブジェクトを思考する</title><link>http://blogs.wankuma.com/jitta/archive/2008/12/18/164339.aspx</link><pubDate>Thu, 18 Dec 2008 22:06:00 GMT</pubDate><guid>http://blogs.wankuma.com/jitta/archive/2008/12/18/164339.aspx</guid><wfw:comment>http://blogs.wankuma.com/jitta/comments/164339.aspx</wfw:comment><comments>http://blogs.wankuma.com/jitta/archive/2008/12/18/164339.aspx#Feedback</comments><slash:comments>6</slash:comments><wfw:commentRss>http://blogs.wankuma.com/jitta/comments/commentRss/164339.aspx</wfw:commentRss><trackback:ping>http://blogs.wankuma.com/jitta/services/trackbacks/164339.aspx</trackback:ping><description>&lt;P class=p&gt;忙しいのに、なんでこう、興味をそそられるエントリを上げるんだ！！（苦笑）&lt;/P&gt;
&lt;P class=p&gt;ネタもと→&lt;A href="http://blogs.wankuma.com/alf/archive/2008/12/13/163590.aspx"&gt;オブジェクト指向 01 定義&lt;/A&gt;&lt;/P&gt;&lt;BR&gt;
&lt;P class=p&gt;まず、「私」の立ち位置をはっきりさせないと。私が「実行ファイル」になっちゃったら、私こそ考えられるべきオブジェクトになっちゃうよ。&lt;/P&gt;
&lt;P class=p&gt;私はプログラム(n)の外にいて、全体を俯瞰しながらプログラム(v)しないと。その「プログラムする」という行為において、どのように考えるか。つまり、オブジェクトというものを重視した（oriented）プログラム(v)を行うのが「オブジェクト指向プログラミング」です。&lt;/P&gt;
&lt;P class=p&gt;&lt;A href="http://blogs.wankuma.com/alf/archive/2008/12/16/163928.aspx#164147"&gt;No2のコメント&lt;/A&gt;でbiacさんが言われている &lt;A class=outerLink title=⇒cocolog-nifty.com href="http://bluewatersoft.cocolog-nifty.com/blog/wankuma-documents01.html"&gt;LT 資料&lt;/A&gt;には、「oriented を「指向」と訳したのは誰だ」と書かれています。「oriented」は、上の段落では「～を重視する」と訳しました。その他、「（知的・情緒的に）方向づけられた，&amp;#8230;志向の，&amp;#8230;本位の，&amp;#8230;を重視する；〔&amp;#8230;に〕関心［興味］がある」という意味があります。この、「方向付けられた」が、「指向（ある一定の方向をめざして進むこと。また、その方向へ向かわせること。）」という訳に繋がったのですかね。おっと、「志向」の説明にはこうあります。「「指向」とも書かれるが、本来的な用法ではない。「指向」は単に物理的な方向をいう。」。うむ。「オブジェクト志向（意識や思考がある対象に向かうこと。）」が、本来の意味として正しいようです。&lt;SPAN class=comment&gt;（ジーニアス英和辞典 第3版 (C) Taishukan 2001-2006）&lt;/SPAN&gt;&lt;SPAN class=comment&gt;（明鏡国語辞典 (C) Taishukan 2002-2006）&lt;/SPAN&gt;&lt;/P&gt;&lt;BR&gt;
&lt;P class=p&gt;はてさて。それじゃ、「オブジェクト」って、なに？&lt;/P&gt;
&lt;P class=p&gt;.NET Framework の &lt;ACRONYM title="Base Class Library"&gt;BCL&lt;/ACRONYM&gt; には、Object クラスがあります。この Object クラスは、全てのクラスの派生元となっています。むっはー！object には、名詞の他に、動詞の意味もありますね。語源は、「～に向かって（ob）投げられた（ject）もの」「注意を喚起させるもの」なんだそうです。そして、「オブジェクト」（ジェにアクセント）という発音は、どちらかというと動詞。名詞の時は「アブジクト」（アにアクセント）のようです。動詞には「反対する。抗議する。異議を唱える。」という意味があります。名詞の場合は「もの。物体。目的。（コンピュータ上で処理の対象となる）ひとかたまりのデータ。」といった意味があります。&lt;SPAN class=comment&gt;（ジーニアス英和辞典 第3版 (C) Taishukan 2001-2006）&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=p&gt;ちうもく～。「処理の対象となるひとかたまりのデータ」です。データの塊であれば、なんだって「オブジェクト」なのです。つまり、「オブジェクトとは何か？」ではなく、「何かをオブジェクトにする」のです。ということは、「1」という数値もオブジェクトですし、「文字」という文字列もオブジェクトです。そして、実行ファイル自身もオブジェクトであり、実行ファイルが動いているコンピュータもオブジェクトです。&lt;/P&gt;&lt;BR&gt;
&lt;P class=p&gt;さて、オブジェクトが定義できました。もう一度、「私の立ち位置」を検証します。「オブジェクト志向プログラミング」において、「私」は「実行ファイル」すなわち「プロセス」なのでしょうか？&lt;/P&gt;
&lt;P class=p&gt;私はこれに、「NO!」と答えます。&lt;/P&gt;
&lt;P class=p&gt;「オブジェクト志向プログラミング」です。「プログラミング」なのです。「program」は、それだけで名詞でありながら、「ing」がついています。ここでの「programing」は、「program」という動詞に接尾子「ing」が付けられて名詞になっているのです。つまり、動作を表しています。できあがったコードがオブジェクトを志向しているのではなく、プログラムを作るという行為がオブジェクトを志向するのです。&lt;/P&gt;
&lt;P class=p&gt;そうすると、オブジェクトを志向するのはプログラム、つまり実行ファイルではなく、プログラムを行っている開発者である、ということになります。&lt;/P&gt;
&lt;P class=p&gt;「私」が、オブジェクトを志向しながらプログラムを作るので、全てのものが「オブジェクト」となります。全てのものを「オブジェクト」として、プログラムの中に投影できます。したがって、「実行ファイル」もまた、「オブジェクト」です。&lt;/P&gt;
&lt;P class=p&gt;そうすると、お題「私が犬に鳴けといったら、犬がワンと鳴いた。」はどうなるか。私は、プログラムにおいて表現される（あるいは、アプリケーションに要求される）「犬」というオブジェクトを、クラスとして設計します。設計した犬を、コードに落とします。「犬のインスタンスを作る」ように、コードを書きます。出来た犬インスタンスに「鳴け」と命じることを、コード化します。結果、実行時に犬がワンと鳴きます。&lt;/P&gt;
&lt;P class=p&gt;「犬がワンと鳴く」のはオブジェクト志向プログラミングの結果であり、「犬にワンと鳴かせる」方法を、オブジェクトを念頭に置きながらプログラミングします。&lt;/P&gt;
&lt;TABLE&gt;
&lt;TBODY&gt;
&lt;TR&gt;
&lt;TD&gt;クラス&lt;/TD&gt;
&lt;TD&gt;犬&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;クラスのインスタンス&lt;/TD&gt;
&lt;TD&gt;クラスを実体化させたものの一つ&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;オブジェクト&lt;/TD&gt;
&lt;TD&gt;犬、犬クラスの実体&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;開発者&lt;/TD&gt;
&lt;TD&gt;私&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;プログラム&lt;BR&gt;（実行ファイル）&lt;/TD&gt;
&lt;TD&gt;オブジェクトが存在するコンピュータ上の世界&lt;BR&gt;私（あるいは顧客）の頭の中にある要求を実現したもの&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;設計図書&lt;/TD&gt;
&lt;TD&gt;私（あるいは顧客）の頭の中にある要求を、プログラム化できるように体系化したもの&lt;/TD&gt;&lt;/TR&gt;&lt;/TBODY&gt;&lt;/TABLE&gt;&lt;img src ="http://blogs.wankuma.com/jitta/aggbug/164339.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>はなおか じった</dc:creator><title>サービスを再起動する（オブジェクト指向的修正編）</title><link>http://blogs.wankuma.com/jitta/archive/2008/09/30/157863.aspx</link><pubDate>Tue, 30 Sep 2008 22:04:00 GMT</pubDate><guid>http://blogs.wankuma.com/jitta/archive/2008/09/30/157863.aspx</guid><wfw:comment>http://blogs.wankuma.com/jitta/comments/157863.aspx</wfw:comment><comments>http://blogs.wankuma.com/jitta/archive/2008/09/30/157863.aspx#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://blogs.wankuma.com/jitta/comments/commentRss/157863.aspx</wfw:commentRss><trackback:ping>http://blogs.wankuma.com/jitta/services/trackbacks/157863.aspx</trackback:ping><description>&lt;p class="p"&gt;&lt;A href="http://blogs.wankuma.com/jitta/archive/2008/09/17/156837.aspx"&gt;前回&lt;/a&gt;、サービス（を表すクラス）が何をするか、というコードを示しました。ここで、サービス クラス（の定義）をもう一度見てみます。&lt;/p&gt;
&lt;pre class="code"&gt;&lt;code&gt;
class LocalService
{
private:
    SC_HANDLE handle;
    static unsigned int FixTimeout(unsigned int timeout);
    DWORD WaitForState(DWORD status, unsigned int timeout);

public:
    LocalService(void);
    virtual ~LocalService(void);
    DWORD Open(SC_HANDLE manager, LPCTSTR serviceName, DWORD desiredAccess);
    void Close(void);
    DWORD Start(unsigned int timeout = 30);
    DWORD Stop(unsigned int timeout = 30);
};
&lt;/code&gt;&lt;/pre&gt;
&lt;p class="p"&gt;&lt;code&gt;Open&lt;/code&gt; メソッドによって、サービスとリンクします。これは、コンストラクタに持って行っても良かったのですが、Open という操作に失敗したときにインスタンスがどのような状態として存在するべきか？というのを考えて、Open に分けることにしました。&lt;/p&gt;
&lt;p class="p"&gt;&lt;code&gt;Close&lt;/code&gt; メソッドによって、Open で接続したサービスから切り離します。これは、.NET Framework だと IDisposable インターフェイスを実装し、Dispose メソッドを明示実装で隠蔽する様にして実装することになります。&lt;/p&gt;
&lt;p class="p"&gt;&lt;code&gt;Start&lt;/code&gt; メソッドは、接続しているサービスを起動します。同様に、&lt;code&gt;Stop&lt;/code&gt; メソッドで停止させます。&lt;/p&gt;
&lt;p class="p"&gt;これを、&lt;A href="http://blogs.wankuma.com/jitta/archive/2008/08/29/154687.aspx"&gt;初回&lt;/a&gt;のように、順序を付けてみます。&lt;/p&gt;
&lt;ol&gt;
	&lt;li&gt;&lt;p&gt;サービス マネージャにアクセスする。&lt;/p&gt;&lt;/li&gt;
	&lt;li&gt;&lt;p&gt;指定のサービスにアクセスする。&lt;/p&gt;&lt;/li&gt;
	&lt;li&gt;&lt;p&gt;停止させる。&lt;/p&gt;&lt;/li&gt;
	&lt;li&gt;&lt;p&gt;起動させる。&lt;/p&gt;&lt;/li&gt;
	&lt;li&gt;&lt;p&gt;サービスのインスタンスを破棄する。&lt;/p&gt;&lt;/li&gt;
	&lt;li&gt;&lt;p&gt;サービス マネージャのインスタンスを破棄する。&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p class="p"&gt;このようになります。そして、問題に対応するのも、ここは変わりません。なぜなら、ここに書いたのは「サービスに対して指示をするオブジェクト」がすることだからです。「依存しているサービスを列挙する」とか、「それらを止める」などは、サービス オブジェクトが責任を持ってすることで、サービスに対して指示をするオブジェクトには関係がないのです。&lt;/p&gt;
&lt;p class="p"&gt;これがどういうことかというと、設計の段階で、誰（オブジェクト）がすることに対して責任を持つのか、明確にするということです。&lt;/p&gt;
&lt;p class="p"&gt;たまに、「ログ フラグが true なら、ログを出力する関数を呼ぶ」というコードを見かけます。次のような感じです。&lt;/p&gt;
&lt;pre class="code"&gt;&lt;code&gt;// 例1
    if (doOutputLog) {
        LogWrite(logString);
    }
// 例2
    if (doOutputLog &amp;&amp; logSize &lt; 1024) {
        logWrite(logString);
    }
&lt;/code&gt;&lt;/pre&gt;
&lt;p class="p"&gt;これは、違います。ログを出力するように命令するオブジェクトは、出力フラグのオン／オフにかかわらず、「ログ出力をする」と、命令すればいいのです。ログ出力オブジェクトが、命令を受け取った後、「ログの出力をするか？」検討すればいいのです。もし、ログ フラグが「デバッグ構築の時は常に ture」という条件に変わっても、変更する箇所は「ログ出力を行う」一カ所です。出力指示の箇所で判別していれば、全ての判別箇所を変更しなければならないし、漏れがないかチェックすることは困難です。&lt;/p&gt;
&lt;p class="p"&gt;次に、サービスの「停止させる」を見ます。&lt;/p&gt;
&lt;ol&gt;
	&lt;li&gt;&lt;p&gt;停止信号を送る。&lt;/p&gt;&lt;/li&gt;
	&lt;li&gt;&lt;p&gt;停止状態になるまで待つ。&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p class="p"&gt;ここに、修正を加えます。すると、こうなります。&lt;/p&gt;
&lt;ol&gt;
	&lt;li style="background-color:#ccffff;"&gt;&lt;p&gt;依存していて、動作しているサービスを列挙する。&lt;/p&gt;&lt;/li&gt;
	&lt;li style="background-color:#ccffff;"&gt;&lt;p&gt;上記サービスについて、停止させる。&lt;/p&gt;&lt;/li&gt;
	&lt;li&gt;&lt;p&gt;停止信号を送る。&lt;/p&gt;&lt;/li&gt;
	&lt;li&gt;&lt;p&gt;停止状態になるまで待つ。&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p class="p"&gt;また、サービス クラスにプロパティを一つ追加します。&lt;/p&gt;
&lt;pre class="code"&gt;&lt;code&gt;
class LocalService
{
private:
    SC_HANDLE handle;
    static unsigned int FixTimeout(unsigned int timeout);
    DWORD WaitForState(DWORD status, unsigned int timeout);
    &lt;span style="background-color:#ccffff;"&gt;std::list&lt;LocalService&gt; dependentServices;&lt;/span&gt;

public:
    LocalService(void);
    virtual ~LocalService(void);
    DWORD Open(SC_HANDLE manager, LPCTSTR serviceName, DWORD desiredAccess);
    void Close(void);
    DWORD Start(unsigned int timeout = 30);
    DWORD Stop(unsigned int timeout = 30);
};
&lt;/code&gt;&lt;/pre&gt;
&lt;p class="p"&gt;このように、設計の中心にオブジェクトを据え、オブジェクトの責任を明確にしていれば、手を加えるべきところが他から独立します。変更が他から独立するということは、変更による影響が、他のところに及ばないということです。&lt;/p&gt;
&lt;p class="p"&gt;今回は「再起動」であるため、「止める」と「動かす」の2つに変更が及びます。また、「止めたものを動かす」ために、「止めた」という情報を覚えておかなければなりません。そのために、インスタンス変数として、depententServices を追加しました。しかし、この追加は&amp;#8220;インスタンス変数&amp;#8221;であるため、インスタンス間では独立しており、互いに影響を与えません。また、追加した変数のアクセス指定子は private です。このため、クラス外からは追加したということがわかりません。このため、変更は LocalService クラス内で閉じていると言えます。&lt;/p&gt;
&lt;p class="p"&gt;変更の影響が外部に及ばないとのメリットは、わかりますか？&lt;/p&gt;
&lt;p class="p"&gt;先ほど、ログを出力する箇所の例を出しました。今度は、オブジェクト指向で同じコードを例示します。&lt;/p&gt;
&lt;pre class="code"&gt;&lt;code&gt;// Log クラス
private BOOL Log::DoOutput(void) {
    return (doOutputLog == LOGGING_ALL ||
        (doOutputLog == LOGGING_LIMIT &amp;&amp; logSize &lt; maxSize));
}

public void Log::Write(LPCTSTR message) {
    if (DoOutput()) {
        cout &lt;&lt; message;
        logSize += _tcslen(message);
    }
}

// 呼び出し
    Log log;
    log.Write(message);
&lt;/code&gt;&lt;/pre&gt;
&lt;p class="comment"&gt;コードの細かいところについては突っ込まないでね。&lt;/p&gt;
&lt;p class="p"&gt;このように、「どのようなときに書き出すか」という判断を、ログというオブジェクトが行えば、ログというものがどのようなものになっても、変更するところは Write メソッドの中だけで済みます。この場合、doOutputLog を設定しているところも変更しますが、全てのコードから doOutputLog を&amp;#8220;使用しているところ&amp;#8221;を探す必要はありません。&lt;/p&gt;
&lt;p class="p"&gt;もっとも、この程度は「構造化プログラミング」の範疇ですが。&lt;/p&gt;
&lt;p class="p"&gt;構造化プログラミングでは、変更の可能性がある箇所を切り出したり、同じ処理をしているところをまとまることで、変更による影響が広がらないようにしました。オブジェクト指向は、切り出す箇所を「誰がするべきか」という視点で行い、「誰」によってまとめていると言ってもよいでしょう。その目的は、変更に強いプログラムにすることです。変更に強いとは、変更による影響が及ぶ範囲を小さくし、変更する箇所を物理的に少なくすることです。&lt;/p&gt;
&lt;img src ="http://blogs.wankuma.com/jitta/aggbug/157863.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>はなおか じった</dc:creator><title>サービスを再起動する（設計編）</title><link>http://blogs.wankuma.com/jitta/archive/2008/09/17/156837.aspx</link><pubDate>Wed, 17 Sep 2008 22:43:00 GMT</pubDate><guid>http://blogs.wankuma.com/jitta/archive/2008/09/17/156837.aspx</guid><wfw:comment>http://blogs.wankuma.com/jitta/comments/156837.aspx</wfw:comment><comments>http://blogs.wankuma.com/jitta/archive/2008/09/17/156837.aspx#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://blogs.wankuma.com/jitta/comments/commentRss/156837.aspx</wfw:commentRss><trackback:ping>http://blogs.wankuma.com/jitta/services/trackbacks/156837.aspx</trackback:ping><description>&lt;p class="p"&gt;&lt;a href=""&gt;前回&lt;/a&gt;発生した問題に対して、オブジェクト指向で設計、実装されていたら、どうだったかを検証します。ここで考えるのは、&lt;A href="http://blogs.wankuma.com/jitta/archive/2008/08/29/154687.aspx"&gt;前々回&lt;/a&gt;の段階です。&lt;/p&gt;
&lt;p class="p"&gt;その前に、「オブジェクト指向」って、難しいのでしょうか？ということを考えます。「難しいのでしょうか？」というのは、正しくありません。「何が、難しいのでしょうか？」を考えます。&lt;/p&gt;
&lt;p class="p"&gt;普通、人は、何かしなければならないとき、「どうする」か、考えます。あるいは、達成した状態になるために、どのようなことが必要か考えます。このとき考えることは、「行為」のみではないでしょうか。&lt;/p&gt;
&lt;p class="p"&gt;とっても簡単な例では、「彼に、醤油をとってもらいたい」とします。私は、「醤油をとって」と頼みます。このように、「彼に頼む」という行為をすればよい、と考えるわけです。&lt;/p&gt;
&lt;p class="p"&gt;ところが、オブジェクト指向では、「誰にさせるか」ということが重要になります。「私」にも「彼」にも、「ものを運ぶ」という行為はできます。したがって、「私」が「ものを運ぶ」のか、「彼」が「ものを運ぶ」のか、考えなければなりません。そして、「彼」に仕事をするために、「私」ができることは何か？と、考えます。そうすると、「彼に頼む」とだけ考えればよかった手続き指向に対して、オブジェクト指向では「誰が、彼に頼むのか」を考えなければならない、、、と、言えなくもありません。確かに面倒ではありそうです。つまり、手続き指向では「私が」という暗黙の了解があったわけです。ところが、オブジェクト指向では「私」はプログラムから切り離され、独立してしまうのです。そして「私」は、プログラム内の様々な「誰か」に対して、「他の人に頼む」という行為をさせることになります。そして、頼むためには、その「誰か」が、対象のことを「できる」かどうか、確認しておかなければならない、ということでもあります。&lt;/p&gt;
&lt;p class="p"&gt;.NET Framework には、System.Windows.Forms.Form というクラスがあります。この「クラス」が「誰か」です。Form クラスには、Show というメソッドがあります。つまり、Form クラスは現れる（Show）ことができます。しかし、System.String クラスには Show メソッドがありません。したがって、String クラスは現れることができません。&lt;/p&gt;
&lt;p class="p"&gt;余談：この原則を壊すのが、拡張メソッドですね。後付のような感じで「～することができる」を増やすことができます。&lt;/p&gt;
&lt;p class="p"&gt;閑話休題。このように、オブジェクト指向では、「誰」ということ、その誰かが「何ができるか」について、注意を払わなければなりません。また、「誰か」つまりクラスを設計する場合は、そのクラスに「何をさせるべきか」について、注意を払わなければなりません。&lt;/p&gt;
&lt;p class="p"&gt;オブジェクト指向が難しいのは、この、いわば「キャスティング」ではないでしょうか。ひとつのアプリケーションという演劇に、どのような俳優すなわちクラスを起用するのか。俳優によって得意とすることが異なります。同じように、クラスによってできること、得意なことが異なります。場合によっては、というかほとんどの場合、新しい俳優を捜さなければならないでしょう。すなわち、クラスの設計です。&lt;/p&gt;
&lt;p class="p"&gt;では、キャスティング...というか、すでに潜んでいる俳優たちを見つけ出します。&lt;/p&gt;
&lt;p class="p"&gt;まず、「停止させられ」たり、「起動させられ」たりする、「サービス」です。他者から「～させられる」ということは、自立して「～できる」ということです。&lt;span class="comment"&gt;注：国語的な意味ではなくて。プログラムの世界では、他からメッセージによって指示を与える、っていうのは、常識でしょ？&lt;/span&gt;&lt;/p&gt;
&lt;p class="p"&gt;それから、サービス マネージャも、キャストとして&lt;span class="comment"&gt;（こう書くと、投げる、型変換する、みたいだけど違うよ）&lt;/span&gt;あげておきましょう。&lt;/p&gt;
&lt;p class="p"&gt;こんなモンですかね。では、彼らは、どんなことができるのか、考えます。&lt;/p&gt;
&lt;p class="p"&gt;サービス マネージャは、「アクセスする（される）」ことと、「アクセスを切り離す（切り離される）」ことができます。.NET Framework ではこれは「アンマネージド リソース」として扱うのですが、今回は Unmanaged C++ を考えているので、とりあえず、無視。他に、「ハンドル」というプロパティが必要ですね。これは、アクセスすることで得られるものなので、「読み取り専用」とします。&lt;/p&gt;
&lt;p class="p"&gt;サービスは、「停止する（停止させられる）」ことと「起動する（起動させられる）」ことができます。サービスにもハンドルが必要ですが、これは、今回の用途には必要がないので、private にしておきます（アクセッサーを用意しない）。ハンドルがあるということは、「アクセスする」と「切り離す」もありますね。そして、起動や停止が完了するのを、「どれくらい待つか」というのを、指定できるようにしておきましょう。ただし、デフォルトを30秒として、また、30秒未満には設定できないようにします。&lt;/p&gt;
&lt;pre class="code"&gt;&lt;code&gt;// サービス マネージャ ヘッダ
#pragma once

class ServiceManager
{
private:
    SC_HANDLE handle;

public:
    ServiceManager(void);
    virtual ~ServiceManager(void);
    DWORD Open(DWORD desiredAccess);
    void Close(void);
    const SC_HANDLE get_Handle(void);
};
&lt;/code&gt;&lt;/pre&gt;
&lt;pre class="code"&gt;&lt;code&gt;// サービス マネージャ
#include "ServiceManager.h"

ServiceManager::ServiceManager(void)
{
    handle = NULL;
}

ServiceManager::~ServiceManager(void)
{
    if (handle != NULL) {
        Close();
    }
}

DWORD ServiceManager::Open(DWORD desiredAccess)
{
    if (handle == NULL) {
        handle = OpenSCManager(NULL, NULL, desiredAccess);
        if (handle == NULL) {
            DWORD ret = GetLastError();
            SetLastError(ret);
            return ret;
        }
    }
    SetLastError(ERROR_SUCCESS);
    return ERROR_SUCCESS;
}

void ServiceManager::Close(void)
{
    CloseServiceHandle(handle);
    handle = NULL;
}

const SC_HANDLE ServiceManager::get_Handle(void)
{
    return handle;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre class="code"&gt;&lt;code&gt;// サービス ヘッダ
#pragma once

class LocalService
{
private:
    SC_HANDLE handle;
    static unsigned int FixTimeout(unsigned int timeout) {
        // ３０以上６０未満に整形
        return (timeout &lt; 30 ? 30 : (timeout &gt; 60 ? 60 : timeout));
    };
    DWORD WaitForState(DWORD status, unsigned int timeout);

public:
    LocalService(void);
    virtual ~LocalService(void);
    DWORD Open(SC_HANDLE manager, LPCTSTR serviceName, DWORD desiredAccess);
    void Close(void);
    DWORD Start(unsigned int timeout = 30);
    DWORD Stop(unsigned int timeout = 30);
};
&lt;/code&gt;&lt;/pre&gt;
&lt;pre class="code"&gt;&lt;code&gt;// サービス
#include "LocalService.h"

LocalService::LocalService(void)
{
    handle = NULL;
}

LocalService::~LocalService(void)
{
    if (handle != NULL) {
        Close();
    }
}

DWORD LocalService::Open(SC_HANDLE manager, LPCTSTR serviceName, DWORD desiredAccess)
{
    if (serviceName == NULL || manager == NULL || serviceName[0] == 0) {
        SetLastError(ERROR_BAD_ARGUMENTS);
        return ERROR_BAD_ARGUMENTS;
    }
    if (handle != NULL) {
        Close();
    }

    handle = OpenService(manager, serviceName, desiredAccess);
    if (handle == NULL) {
        DWORD result = GetLastError();
        SetLastError(result);
        return result;
    }
    SetLastError(ERROR_SUCCESS);
    return ERROR_SUCCESS;
}

void LocalService::Close(void)
{
    (void) CloseServiceHandle(handle);
    handle = NULL;
}

DWORD LocalService::Start(unsigned int timeout)
{
    if (handle == NULL) {
        return ERROR_NOT_READY;
    }
    timeout = FixTimeout(timeout);

    BOOL ret = StartService(handle, 0, NULL);
    DWORD result = GetLastError();
    if (ret == TRUE || result == ERROR_SERVICE_ALREADY_RUNNING) {
        result = WaitForState(SERVICE_RUNNING, timeout);
    }
    SetLastError(result);
    return result;
}

DWORD LocalService::Stop(unsigned int timeout)
{
    if (handle == NULL) {
        return ERROR_NOT_READY;
    }
    timeout = FixTimeout(timeout);

    SERVICE_STATUS status;
    BOOL ret = ControlService(handle, SERVICE_CONTROL_STOP, &amp;status);
    DWORD result = GetLastError();
    if (ret == TRUE || result == ERROR_SERVICE_NOT_ACTIVE) {
        result = WaitForState(SERVICE_STOPPED, timeout);
    }
    SetLastError(result);
    return result;
}

DWORD LocalService::WaitForState(DWORD waitFor, unsigned int timeout)
{
    DWORD result;
    SERVICE_STATUS status;
    int count = 0;
    while (TRUE) {
        if (QueryServiceStatus(handle, &amp;status)) {
            if (status.dwCurrentState == waitFor) {
                result = ERROR_SUCCESS;
                break;
            }
            if (++count &gt; timeout) {
                result = ERROR_SERVICE_REQUEST_TIMEOUT;
                break;
            }
        } else {
            result = GetLastError();
            break;
        }
        Sleep(1000);
    }
    return result;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;img src ="http://blogs.wankuma.com/jitta/aggbug/156837.aspx" width = "1" height = "1" /&gt;</description></item></channel></rss>