Javaデザインパターンのフライ級モデル①①
人生には苦労が必要です。苦労した場合にのみ、失敗した後の明確な良心が得られます。人生は一方通行であり、苦労したときにのみ明るい未来を得ることができます。人生には多くの競争相手がいるため、多くの競争相手がいます。競争相手、だから私たちはもっと戦わなければなりません!
デザインパターンの学習、近い将来23のデザインパターンについてブログを書きますので、お楽しみに〜
—2021 / 1/12
定義
フライウェイトモデルとも呼ばれ、共有テクノロジーを使用して、多数のきめの細かいオブジェクトを効果的にサポートします。
使用するシーン
アプリケーションが多数のオブジェクトを使用し、これらのオブジェクトによって多くのストレージオーバーヘッドが発生する場合は、フライウェイトモデルを使用できるかどうかを検討できます。
たとえば、オブジェクトのきめ細かいインスタンスが多数生成され、これらのインスタンスがいくつかのパラメータを除いて基本的に同じである場合、それらの共有パラメータをクラスの外に移動して、メソッドが呼び出されると、多数の単一インスタンスを共有することができます。
問題分析
正方形、長方形、円、三角形を作成したいとします。
通常の考え方は次のとおりです。ファクトリモデルを使用します。これらは非常に類似しており、一連の「製品」に属していますが、複数のインスタンスが作成され、メモリの浪費が発生します。
解決策:
それらを統合し、関連するコードとデータを共有します。これは、シングルトンモデルにいくらか似ています。ここでは、Flyweightモデルの列を使用します。
フライ級モードとシングルトンモードの違い
- シングルトンモードは、システム全体が1つのインスタンスを共有することです
- フライウェイトモードでは、システム全体が同じタイプの複数のオブジェクトを共有し、フライウェイトモードの共有オブジェクトは必要に応じて割り当てられ、存在しない場合は自動的に作成されます。
- シングルトンモードでは、2番目のインスタンスは作成されません
- Flyweightモデルの共有オブジェクトは、スレッドに対してプライベートである必要があります。たとえば、共有自転車。共有されていても、あなたのものですが、借りて返済し、ある程度共有します。
外部状態と内部状態
- 内部状態は共有でき、Flyweightに保存でき、環境の変化によって変化することはありません。
- 外部状態は共有できず、環境の変化に伴って変化するため、外部状態はクライアントによって維持されます(環境の変化はクライアントによって引き起こされるため)。
ここで理解していなくても構いません。コードを読めば理解できます!
UML类图(2.1)
:
役割分析
-
Abstract Flyweight:特定のFlyweightに実装する必要のあるメソッドを指定し、外部状態はこのメソッドを介してパラメーターの形式で渡されます。Javaでは、抽象クラスとインターフェースを使用できます。
-
ConcreteFlyweight:抽象的な役割を実装するためのメソッド。内部状態がある場合は、内部状態のストレージスペースを提供する責任があります。
-
FlyweightFactoryロール(FlyweightFactory):FlyweightFactoryロールの作成と管理を担当します。共有の目的を達成するためには、この役割の実現が鍵となります!
-
クライアントロール(クライアント):すべてのフライウェイトオブジェクトへの参照を維持し、対応する外部状態を保存する必要もあります
ここで理解していなくても構いません。コードを読めば理解できます!
内部ステータスコードの実装
IShape(抽象的なフライ級の役割):
public interface IShape {
public void showShape();
}
ShapeImpl(特定のフライ級の役割):
public class ShapeImpl implements IShape{
//内部享元部分 (形状)
private String type = "";
public ShapeImpl(String type) {
this.type = type;
}
@Override//外部享元角色
public void showShape() {
Log.i("享元模式","绘制 "+type+" 成功 ");
}
}
ここでのタイプは共有可能な内部状態であり、環境の変化によって変化することはありません。
ShapeFactory(フライ級ファクトリーの役割)
public class ShapeFactory {
HashMap<String,ShapeImpl> hashMap = new HashMap<>();
//设置type
public IShape getShape(String type){
if (!hashMap.containsKey(type)) {
hashMap.put(type,new ShapeImpl(type));
}
return hashMap.get(type);
}
//获取hashMap数量
public int getShapeSize(){
return hashMap.size();
}
}
ここでHashMapを使用する理由
HashMapの機能:
- HashMapの最下層は、主に配列とリンクリストに基づいています。
- クエリ速度が比較的速い理由は、主にハッシュコードを計算して保存場所を決定するためです。
- HashMapはシリアル化できます。スレッドセーフではありません。
- HashMapは、キーが一意であることを保証できます
HashMapはキーが一意であることを保証できるため、キーが渡されると、対応するオブジェクトが存在する場合は返されます。オブジェクトが作成されていない場合は、「シングルトン」の効果が得られます。
HashMapスレッドは安全ではないため、フライウェイトモードをマルチスレッドの状況で使用することはお勧めしません。
試験方法:
ShapeFactory shapeFactory = new ShapeFactory();
IShape shape1 = shapeFactory.getShape("正方形");
IShape shape2 = shapeFactory.getShape("正方形");
IShape shape3 = shapeFactory.getShape("三角形");
IShape shape4 = shapeFactory.getShape("正方形");
shape1.showShape();
shape2.showShape();
shape3.showShape();
shape4.showShape();
Log.i("享元模式","总个数为: "+shapeFactory.getShapeSize()+"");
Log图(1.1)
:
3つの正方形が格納されていますが、内部に2つのタイプ(正方形と三角形)しかないため、印刷されたものの総数は2つであることがわかります。
しかし、コードは内部状態にのみ使用され、外部状態はなく、外部状態を追加していることがわかります。
外部ステータスコードの実装
IShape(抽象的なフライ級の役割):
public interface IShape {
//由客户端输入外部状态
public void showShape(Color color);
}
ここでの色は外部状態であり、外部状態は共有できず、外部状態はお客様が入力し、環境の変化に応じて変化します。
色(外部状態):
public class Color {
private String color = "";
public Color(String color) {
this.color = color;
}
public String getColor() {
return color;
}
}
ShapeImpl(特定のフライ級の役割):
public class ShapeImpl implements IShape{
//共享部分 (形状)
private String type = "";
public ShapeImpl(String type) {
this.type = type;
}
@Override//外部享元角色
public void showShape(Color color) {
Log.i("享元模式","绘制 "+type+" 成功 颜色为:"+color.getColor());
}
}
ここでのタイプは共有可能な内部状態であり、環境の変化によって変化することはありません。
ShapeFactory(フライ級ファクトリーの役割)
public class ShapeFactory {
HashMap<String,ShapeImpl> hashMap = new HashMap<>();
public IShape getShape(String type){
if (!hashMap.containsKey(type)) {
hashMap.put(type,new ShapeImpl(type));
}
return hashMap.get(type);
}
public int getShapeSize(){
return hashMap.size();
}
}
試験方法:
ShapeFactory shapeFactory = new ShapeFactory();
IShape shape1 = shapeFactory.getShape("正方形");
IShape shape2 = shapeFactory.getShape("正方形");
IShape shape3 = shapeFactory.getShape("三角形");
IShape shape4 = shapeFactory.getShape("正方形");
shape1.showShape(new Color("红色"));
shape2.showShape(new Color("红色"));
shape3.showShape(new Color("黄色"));
shape4.showShape(new Color("黑色"));
Log.i("享元模式","总个数为: "+shapeFactory.getShapeSize()+"");
Log图(1.2)
:
外部状態は、ユーザーが定義した外部に公開されているため、
共有できません。内部状態は共有されます。同じ値の場合、再作成されず、共有状態が使用されます。
オリジナリティは簡単ではありません、あなたの好きなものは私にとってあなたの最大のサポートです、あなたの好きなものを残してください〜