- PR -

別クラスのメソッドを使用する場合についての質問

投稿者投稿内容
かずくん
ぬし
会議室デビュー日: 2003/01/08
投稿数: 759
お住まい・勤務地: 太陽系第三惑星
投稿日時: 2003-11-20 11:54
> ほむらさん
引用:

かずくん氏のコードはsingletonを応用したもののようなのですが
僕ではコンパイルが通せません。。。
後学のためにコンパイルの通る形のものを教えていただければなとおもいます^^;;;;;


インスタンス数を制限していればSingletonですが、インスタンスを無制限に生成してるので、ただのFactory Methodです(正確にはClass-side Factoryって言うんだっけ?)。
かずくん
ぬし
会議室デビュー日: 2003/01/08
投稿数: 759
お住まい・勤務地: 太陽系第三惑星
投稿日時: 2003-11-20 12:12
> ほむらさん
引用:

スパゲッティプログラムの始まりじゃないでしょうか?



まず、Class_Bの責任範囲やコンテキストを考える必要があるとおもいます。

  • Class_Bが外部仕様に含まれるのであれば、public class。
  • Clss_Bは外部仕様ではないが、同一package内からのみ使用されるのであればpackage private class。
  • CLass_Bが包含するクラスのみ、または包含するクラスの継承階層でのみ使用されるのであれば、inner class。

もし、3番目に該当するのであれば、架空兎さんのコードは何ら問題がないと思います。

この当たりの判断は、どうしても分析者としての目が必要になると思います。
分析者が実装者の目を持つことが必要なのと同様に、実装者も分析者の目を持つことが必要なのかもしれません。

この辺の話は、2003年12月号のInterface誌の特集記事が参考になるかもしれません。
ほむら
ぬし
会議室デビュー日: 2003/02/28
投稿数: 583
お住まい・勤務地: 東京都
投稿日時: 2003-11-20 15:34
ども、ほむらです。
いゃぁ、もう冬ですね。最近メラさむいっす
ごめんなさいレス遅れてしまいました^^;;;;(理由になってませんが(笑 )
----------------------------
ぽん氏へ
引用:

Class_AとClass_Bをtestクラスの外に出せばコンパイルが通ると思います。
インナークラスのインスタンスを作成するにはアウタークラスのインスタンスが必要ですね。

[追記]
Class_AとClass_Bにstaticをつける手も有ります。


Class_A と Class_B を 外に持っていくと無事コンパイルできました。
なるほど〜、同じスコープ内(?)にある
別のクラスのインスタンスは作成できなかったのですね。
ありがとうございました。

かずくん氏へ
引用:

インスタンス数を制限していればSingletonですが、インスタンスを無制限に生成してるので、ただのFactory Methodです(正確にはClass-side Factoryって言うんだっけ?)。


数を制限するのがSignletonパターンだったのですね。。。
インスタンスの生成を管理することことだとばかり思っていました。
んで、Class-side Factoryというのが良くわからなかったので
ちょっと引いてみたのですがこちらも、オブジェクトの生成に関するものなのですねー。
また一つ勉強になりました^^

かずくん氏・架空兎氏へ
スパゲティプログラムにならないかなと思ったのはClass_BがClass_Aの拡張機能を
もたせているのかと思ったからです。(なのでDecoratorの話を出してしまいました^^;;;)
でも、架空兎氏コードを落ち着いて読んでみると確かに
かずくん氏の言うとおり問題はなさそうですね。
でも、Class_Bが内部クラスのわりに独立しすぎてるような。。。
ってこの考えが間違えの元なんですよね(汗)

とりあえず、まずは
Class_Bの責任範囲(Class_Bのもつ想定した機能という解釈でよいのですよね?)を
考えないことにはClass_Bの位置も落ち着きそうにないですね。。。
Class_Bがどんな機能を持つのかによってClass_Aの初期化にClass_Bを必要としているのか
とかもでてくるでしょうし。。
(責任範囲を考えるとはこういう事で間違えてませんよね?微妙に不安だったり)


最後におふとぴで
生成と同時に色々な初期化を行う場合。僕は生成用の関数を作っていました。
Javaでやってみようかと思ったのですがうまくいかず(笑
変に中途半端ですが一応。。。
(C++だとfriendでcreateClass_A()を作って終わりでした(笑 )

(ほんとはClassBuilderをClass_Aの内部クラスまでは持っていきたかったのですが)
コード:
public class test01
{
  public static void main(String arg[]){
    ClassBuilder bld = ClassBuilder.getInstance();
    Class_A clsA = bld.createClass_A();
  }

  static class ClassBuilder {
    static ClassBuilder instance = null;
    private ClassBuilder(){
    }
    public static ClassBuilder getInstance(){
      if( instance == null ) instance = new ClassBuilder();
      return instance;
    }
    public Class_A createClass_A(){
      Class_A clsA = new Class_A();
      Class_B clsB = new Class_B( clsA );
      clsB = null;
      return clsA;
    }
  }
}

class Class_A { 
  public void A_Method(){ 
  } 
} 

class Class_B { 
  Class_A clsA; 
  public Class_B(Class_A cls) { 
    clsA = cls; 
    clsA.A_Method(); 
  } 
}


長いですけどおまけに。。。
もしもDecoratorパターンを使用するとこんな感じ?
コード:
public class test02
{
  public static void main(String arg[]){
    Class_A clsA = new Class_A();
    Class_B clsB = new Class_B(clsA);
    clsB.A_Method();
  }

}
interface ClassMethod {
  abstract public void A_Method();
}

class Class_A implements ClassMethod { 
  public void A_Method(){ 
  } 
} 

class Class_B implements ClassMethod { 
  Class_A clsA; 
  public Class_B(Class_A cls) { 
    clsA = cls; 
  } 
  public void A_Method(){ 
    clsA.A_Method();
    // なんらかの拡張処理
  } 
}


かずくん
ぬし
会議室デビュー日: 2003/01/08
投稿数: 759
お住まい・勤務地: 太陽系第三惑星
投稿日時: 2003-11-20 16:14
引用:

数を制限するのがSignletonパターンだったのですね。。。
インスタンスの生成を管理することことだとばかり思っていました。


通常は、インスタンス数をアプリケーション内で1つに制限したものを良く使用しますね。
本来の意味はこちらであり、数を制限するというのは拡大解釈に当たると思います。
ただ、この解釈の方が応用がきくかな?って思っています。

# ちょこっと追加
生成数を管理しているので、ほむらさんの認識で問題ないと思います。
ついでに、インスタンス数を制限するのがSingletonであり、インスタンス数を無制限に生成するのがClass-side Factoryとすると、両者はいとこみたいな関係にあるといえるのかな(どちらも生成系のパターンだってば)。

引用:

んで、Class-side Factoryというのが良くわからなかったので
ちょっと引いてみたのですがこちらも、オブジェクトの生成に関するものなのですねー。


Factory Methodのメリットはnew演算子で直接Productオブジェクトを生成を防ぎ変更に強くするというものと理解していますが、Factory自体はnew演算子で生成しているので、あまり意味ないんじゃん、というのがGoFのFactory Methodに対する、率直な感想です。

Class-side Factoryの場合、Productをnew 演算子で生成するのを抑制した上で、Factoryはnew演算子で生成しないという所が気に入っています。

引用:

もしもDecoratorパターンを使用するとこんな感じ?


私はしばしば、Decorator+Template Methodの組み合わせを用います。
コード:

interface Decorator {
public void method_A();
}

abstract class AbstractDecorator implements Decorator {
private Decorator decorated;

protected AbstractDecorator(Decorator deco) {
decorated = deco;
}

public void method_A() {
if (null != decorated) {
decorated.method_A();
}

method_A_Self();
}

abstract protected void method_A_Self();
}

class ConcDecorator_A extends AbstractDecorator {
public ConcDecorator_A(Decorator deco) {
super (deco);
}

protected void method_A_Self() {
// 何かする。
}
}

class ConcDecorator_B extends AbstractDecorator {
public ConcDecorator_A(Decorator deco) {
super (deco);
}

protected void method_A_Self() {
// 秘密のことする。
}
}

public class Test {
public static void main(String[] arg) {
Decorator deco = new ConcDecorator_A(new ConcDecorator_B(null));
deco.method_A();
}
}



[ メッセージ編集済み 編集者: かずくん 編集日時 2003-11-20 16:38 ]
かずくん
ぬし
会議室デビュー日: 2003/01/08
投稿数: 759
お住まい・勤務地: 太陽系第三惑星
投稿日時: 2003-11-20 16:34
コード:
public class Class_A {
    private Class_A.Class_B clsB = new Class_A.Class_B();
    private boolean blnA = false;

    private void A_Method() {
        this.blnA = true;
    }

    public class Class_B {
        public void B_Method() {
            Class_A.this.A_Method();
        }
    }
}


引用:

でも、Class_Bが内部クラスのわりに独立しすぎてるような。。。
ってこの考えが間違えの元なんですよね(汗)


確かに、Class_BはAPI(外部仕様)にしたいのか、実装の詳細にしたいのか、いったいどっちやねんって言いたくはなりますね。まあ、サンプルっということでいいんじゃないですかね。

スキルアップ/キャリアアップ(JOB@IT)