パスワードを忘れた? アカウント作成
この議論は賞味期限が切れたので、アーカイブ化されています。 新たにコメントを付けることはできません。

非オブジェクト指向な「Javaプログラミング能力認定試験」」記事へのコメント

  • 私感だけど、
    オブジェクト指向というのは、再利用するライブラリを作成する場合は威力を発揮するのはよく分かる。
    しかし、再利用しない場合は不要だし、多人数で開発する場合は他人とのインタフェース部分だけオブジェクト指向的にすれば十分だと思う。
    他人に見せない内部まで生真面目にオブジェクト指向で作ったら、むしろコードサイズが大きくなり。処理が分散することで、かえって可読性が落ちる。

    • by Anonymous Coward on 2011年01月11日 2時20分 (#1886035)

      オブジェクト指向というのは、再利用するライブラリを作成する場合は威力を発揮するのはよく分かる。

      発揮しません。再利用性で重要なのは、汎用性のある仕様です。オブジェクト指向で作ろうが、使えないものは使いたくありません。

      他人に見せない内部まで生真面目にオブジェクト指向で作ったら、むしろコードサイズが大きくなり。処理が分散することで、かえって可読性が落ちる。

      オブジェクト指向というか、カプセル化はきっちりした方がいいですよ。一人で書く場合も重要。書いているうちに共通部分が次第に見出せてくるので、そういうものをクラスに分離。そうして分離したクラスをコード内で再利用。本質的なカプセル化がされていると、データと処理の組合せを分離するのが非常に楽で、コードもコンパクトになります。分離の際には、オブジェクト指向の「継承」の概念が使えます。

      もし、肥大化するのであれば、それは不要なメソッドを作っているからです。特にいらないのがアクセサ。アクセサなんか作ったら、データと処理を分離して書くことが可能になってしまうため、カプセル化の意味がありません。

      でも、C++なんかだと、多態性や動的束縛は爆弾を仕込むことになることもあるので、よく考えて使ったほうが吉。

      親コメント
      • >発揮しません。
        レイヤが違います。たとえ、仕様がちゃんとしていても、クラス変数の操作がアクセサで防御されていなければ、ダメでしょう。オブジェクト指向ってライブラリの使用者に不正な操作をさせないための工夫が随所に盛り込まれています。

        >書いているうちに共通部分が次第に見出せてくるので、そういうものをクラスに分離。
        単に、共通部分を private メソッドに切り出すだけではダメですか?
        また、細かい話ですが、このようなサブルーチン化はカプセル化とは違うものです。

        >特にいらないのがアクセサ。
        オブジェクト指向的には、格別な理由が無い限り、アクセサを使用すべきです。たとえ、もらった値をクラス変数に設定するだけのアクセサであってもです。さらに...

        >多態性や動的束縛は爆弾を仕込むことになることもあるので、よく考えて使ったほうが吉。
        だなんて、私と同じく、あなたもオブジェクト指向の濫用には反対だったりしませんか?

        親コメント
        • by Anonymous Coward

          クラス変数の操作がアクセサで防御されていなければ、ダメでしょう。

          何故に「クラス変数」の場合に限るのでしょうか。何か特定の言語のお話?

          オブジェクト指向ってライブラリの使用者に不正な操作をさせないための工夫が随所に盛り込まれています。

          最初の発言では「再利用」と言っておきながら、いつのまにか「利用」の話にすりかわってますね。

        • by Anonymous Coward

          とりあえず、私(#1886035)はオブジェクト指向プログラミングの信奉者ではありません。また、カプセル化については推進派ですが、アクセサに関しては不要派です。

          再利用性ついて、オブジェクト指向である必要性はありません。Cにもライブラリはありますよね。カプセル化については、Cのモジュールでも実現できます。それだと、再利用が難しいですか?再利用性に、オブジェクト指向は不可欠ではありませんし、プログラミング言語という道具だけの問題ではないのです。

          単に、共通部分を private メソッドに切り出すだけではダメですか?
          また、細かい話ですが、このようなサブルーチン化はカ

          • >カプセル化については、Cのモジュールでも実現できます。

            それは、C言語上でオブジェクト指向的な設計を実践しただけのことです。いわゆるオブジェクト指向言語でなくてもオブジェクト指向な設計は実践可能です。それで私は、再利用しない、他人に見せない部分では、構造化設計のレベルで十分(オブジェクト指向設計はやり過ぎ)ではないかと考えております。

            >処理だけなら、privateメソッドにしていいですよ。でも、「クラス」と書いたのはデータと処理のどちらかではなく、組合せを念頭においているからです。

            結局は程度論になるのでしょうけど、ひとりで把握できている範囲ならばデータと処理が分離しても良いと考えてます。データと処理の関連性を意識したいならば、変数名関数名で関連性を持たせれば十分ではないかと思います。

            >でも、アクセサは処理からデータを切り離す手段なので、データに誤った処理を書く確率が高まります。

            アクセサは誤った処理ができないようにするためのものだと思いますが。アクセサ内で入力をチェックして、不正な値ならば拒絶すれば良いですね。

            >また、カプセル化がきっちり出来たクラスのオブジェクトは、アクセサで取り出そうが、メンバ変数で取り出そうが、本質的には同じことです。

            どうも誤解されているようですが、アクセサとはカプセル化を行うための手段なので、このコメントは矛盾しているように思います。外部に対してリードオンリーな属性(変数)を実現するにはアクセサを使わざるを得ないと思いますが。

            親コメント
      • by Anonymous Coward
        > 特にいらないのがアクセサ。アクセサなんか作ったら、データと処理を分離して書くことが可能になってしまうため、カプセル化の意味がありません。
        カプセル化という意味では、クラスが持っているデータを直接触らせないというのは非常に重要です。
        例えばgetHoge()というアクセサを用意した場合、hogeがどうやって得られるかをオブジェクトのユーザに意識させずに済むわけです。インスタンス変数かもしれないし、定数かもしれないし、別モジュールへ問い合わせた結果かもしれないし、何らかの計算結果かもしれないけど、とりあえずgetHoge()すればhogeが得られる。
        さらに重要なのは、何らかの理由でクラスの仕様を変える必要が発生して、例えばいままでクラス変数として保持していたのを別のモジュールへの問い合わせに変更したとしても、getHoge()の仕様さえ変わらなければオブジェクトのユーザのコードは変える必要がないということですね。

        アクセサ介さずにデータまでpublicとして見せるのはオブジェクトのユーザが、オブジェクトの具体的なデータ構造まで意識したい場合くらいですね。
        • by Anonymous Coward

          アクセサ介さずにデータまでpublicとして見せるのはオブジェクトのユーザが、オブジェクトの具体的なデータ構造まで意識したい場合くらいですね。

          逆だよ。アクセサを使うときは、オブジェクトの具体的なデータ構造まで意識したい場合。

          例えば、符号無しの多倍長整数を扱うクラスを作るとしよう。メンバ変数は、何らかの形で表現されたunsigned intの配列と、必要ならその配列の長さを保持するint型の変数としよう。そのとき、アクセサは必要?

          表示のためには、文字列を返すメソッドを作ればいい。四則演算はそのためのメソッドを作ればいい。それ以外の演算に

          • 符号無しの多倍長整数を扱うクラスを作るとしよう。メンバ変数は、何らかの形で表現されたunsigned intの配列と、必要ならその配列の長さを保持するint型の変数としよう。そのとき、アクセサは必要?

            そういう「アクセサが不要」なクラス設計で「アクセサが不要」と言われても、「一般論としてアクセサは不要」とは言えないでしょう。

            たとえば、アクセサと隠蔽の例によく挙げられるものとして複素数クラスがありますが、
            複素数クラスで、その実部と虚部にアクセスするアクセサは不要なものですか?

            こういうクラスでデータをpublicで見せるのは、デカルト座標形式な内部表現限定な「具体的なデータ構造まで意識したいデータ構造」だし、
            これをpublicとして見せずにアクセサとして用意しておけば、たとえば「内部表現が極形式の複素数クラス」でも複素数クラスとしては気にせずに同じように使うことができます。

            そういう「直接データを持っているとは限らないし、持ってないとも限らない」ような「オブジェクトの状態」情報へのアクセス手段の提供こそがアクセサの出番でしょう。

            親コメント
            • by Anonymous Coward

              複素数クラスで、その実部と虚部にアクセスするアクセサは不要なものですか?

              はい。不要です。「アクセサ」の定義次第ではありますが。

              例えば、一般的なクラスにおいて、isZero()やisEmpty()がアクセサであるというのであれば、アクセサが不要などと言うことは言いません。そういうものは積極的に書くべきです。そういうものがないと、C++では、"obj == 0"と言うコードがあった時に泣けます。

              複素数クラスで、メンバ変数が不可変ではないのに、setReal()がなくて、getReal()だけでもアクセサと言うのであれば、アクセサが不要などと言うことは言いません。

              でも

          • by Anonymous Coward

            逆だよ。アクセサを使うときは、オブジェクトの具体的なデータ構造まで意識したい場合。

            この段落以降や#1886499 [srad.jp]あたりをよむと、アクセサの公開ではオブジェクトの具体的なデータ構造は(メンバ変数の公開ほどは)意識させない。メンバ変数の公開はオブジェクトの具体的なデータ構造まで意識してでも効率的に動かしたい場合に使う、という使い分けしてるように読めるんだが。

      • by Anonymous Coward

        class Function {
        public: virtual int apply(int argument) = 0;
        };

        class FunctionAdd : public Function {
        private:
                int value;

        public:
                FunctionAdd(int value) { this->value = value; }
                int apply(int argument) { return argument + value; }
        };
        class FunctionDiv : public Function {
        private:
                int value;

        public:
                FunctionDiv(int value) { this->value = value; }
             

        • by Anonymous Coward
          あれ? preタグで囲んだ、getSumから一部のメソッドがおかしくなった。
          htmlという事を忘れて<をエスケープしてなかったのが原因か?

          int getSum() {
            int sum = 0;
            for (int i = 0; i < size(); i++) sum += get(i);
            return sum;
          }

          Abstract1DMatrix* assign(Function *f) {
            for (int i = 0; i < size(); i++) set(i, f->apply(get(i)));
            return this;
          }

※ただしPHPを除く -- あるAdmin

処理中...