1

このための意味のある質問のタイトルを考え出すのは難しいです。私がやろうとしていることを正確に説明します。

Path潜在的に大きなオブジェクトのリストを作成するAndroidグラフィックライブラリを作成しました。それぞれに追加のデータを添付する必要がありますPath。これを行うために、追加の拡張データフィールドを提供するために単純にサブクラス化Path(と呼びます)しました。一般的なユースケースでは、これらのオブジェクトのうち、実際に追加のデータセットが設定されているPathSubclassのはごくわずかです。Pathたとえば、ArrayList数千Pathのデータが存在する可能性がありますが、追加のデータがあるのはほんの一握りです。ライブラリを開発するときに、それぞれに添付したい追加データの量が発生する可能性がありますPathかなり成長します。これは時期尚早の最適化である可能性がありますが、追加データが非常にまれにしか入力されず、そのオブジェクトのかなり大きなコレクションが使用される場合、オブジェクトをサブクラス化して追加データを含めるのは効率的ではないことを懸念しています。

私がやろうと思ったのは、おそらく私のサブクラスExtendedPathDataとは別のクラスを持つことでした。Pathしたがって、各サブクラスは、追加データを必要とするごく少数のオブジェクトを除いて、多くの場合Path、メンバーの必要性によって少しだけ肥大化します。これは、メソッドを使用して、通常、追加のデータをに添付する方法と似ていると思います。mExtendedDatanullPathViewsetTag()

私が考慮すべき他のアプローチはありますか、それは何らかの理由でより良いですか?

4

2 に答える 2

4

継承の代わりに構成を使用できます。

アイデア1

PathDataクラスには、aPathおよびExtendedPathData:への参照が含まれる場合があります。

// encapsulate properly in your code, this is
// just a short sample
class PathData {
  public Path path;
  public ExtendedPathData data;
}

これにより、dataメンバーをに設定できますnull。各PathDataインスタンスには、常に2つの参照のサイズがあります。のメンバーの数が増えると、実際のメモリ消費量は、null以外のインスタンスに対してExtendedPathDataのみ増加します。PathDatadata

アイデア2

次の2つの実装を持つインターフェイスを使用して、もう1つの参照を削除できます。

interface PathData {
  Path path();
  ExtendedPathData data();
}

final class NullPathData implements PathData {
  Path path;
  public Path path() { return path; }
  public ExtendedPathData data() { return null; }
}

final class ExtendedPathData implements PathData {
  Path path;
  ExtendedPathData data;
  public Path path() { return path; }
  public ExtendedPathData data() { return data; }
}

使用する実装を決定するにはここでファクトリメソッドが必要なので、2つの実装を持つことが本当にコードの価値があるかどうかを判断するのはあなた次第です。インスタンスごとに1つの4バイト参照です...

その他のもの

ExtendedPathData不変で、多くの等しいインスタンスが存在する可能性がある場合は、パブリックコンストラクタの代わりにインスタンスプールを使用する静的ファクトリメソッドを公開することで、それらをプールすることもできます

JoshuaBlochによるEffectiveJavaをお持ちの場合は、ヒントを詳細に説明する参考資料を以下に示します(より一般的なコンテキストで)。

  • 項目1コンストラクターではなく静的ファクトリメソッドを検討する
  • 項目16継承よりも構成を優先する
于 2013-01-07T09:58:10.667 に答える
2

のサブクラスをPath以下のコンテナに格納できるのは、継承の全体的なポイントではありませんか?

ArrayList<Path> pathList;

pathList.add(new Path());
pathList.add(new PathPlusPlus());

それとも私は問題を理解していませんか?

isinstanceof@assyliasが示唆するように、醜い呼び出しをなくすために、拡張データを返すゲッターをベースクラスに追加できます。基本クラス自体では、を返しnull、サブクラスでは、関連するデータを返します。

于 2013-01-07T10:00:50.063 に答える