可変クラス(immutable class)
5534 ワード
可変クラス、その名の通りクラスのインスタンスは変更できません.インスタンスの情報は、作成時に提供され、ライフサイクル全体で変更できません.
JavaのStringクラスがimmutableであることはよく知られています.実はprimaryの包装類はimmutableです.では、immutableのclassをデザインさせたらどうしますか?
immutableとは、変わらないという意味です.変えられない.どのようにしてクラスのオブジェクトを変更しますか?
第一に、このクラスは継承できないと思います.そこでclassの前にfinalを追加します.これは最も直接的な方法であり、最も簡単な方法でもありますが、将来それを拡張したいときはできません.彼の基礎の上でサブクラスを定義したいのもimmutableかもしれません.この場合、classの前にfinalを追加するのではなく、すべての方法にfinalを追加することができ、サブクラスがその方法を書き換えることを防止することができます.実は継承することなくこのクラスを拡張することができ、compositeメソッドを通じて.したがってimmutableクラスの継承は推奨されません.さらに、immutableクラスを継承できない方法もあります.それは、メソッドをプライベートまたはprotected、すなわち保証プライベートにし、次に静的ファクトリメソッドを提供してインスタンスを生産することです.これは、パッケージ内の拡張が可能であり、顧客クラスにとって継承できないため、最も推奨される方法です.同時に静的工場法には構造法よりも良いところがたくさんある.
第二に、属性が変えられないことを考えるかもしれません.fieldの前にもfinalを追加しなければなりません.属性を私有化し、直接アクセスされて修正されないようにしなければなりません.これで十分ですか.他のクラスのオブジェクトの参照プロパティがある場合は?どうやって変わらないと保証しますか?
まずあなたができることは、自分の方法の中でその値を変えないことを保証することです.どうやって他のクラスが直接変えないことを保証しますか?この引用は他の相手があなたに伝えたものですか?どうやって保証しますか?同様に、メソッドでこのプロパティを返すとしたら?考えてみろ.
それがimmutableの自然であれば安心です.でもそうじゃなかったら?
新しい相手をcloneしなければならないようです.cloneについては、liuwang 126の記事[url]を参照してください.http://liuwang126.iteye.com/blog/272595[/url]
次は完全なSampleです.
これは一般的な開発ではあまり使われないかもしれません.デザインゲームと見なすことができます.しかし、私たちが自分でAPIを設計して他の人に呼び出す場合は、ルールの厳格さとあなたの意図が正確に表現され、制限されることを考慮しなければなりません.
次にfinalを分析します.
final:designとefficiencyを使う理由は2つあります.メソッドのパラメータにfinalを加えて、入力されたパラメータが変更されないことを保証することができます.この設計は私たちがよく推奨しています.
methodの前にfinalを加える理由も2つあります.1つ目は,クラスのサブクラスがこの方法を書き直さないことを保証し,この方法の挙動は変更されない.これが設計上の理由です.もう1つは、低バージョンjdkでこれを利用することでperformanceを向上させることができます.しかし、メモリ消費に悪影響を及ぼすこともあります.jdk 5以降、jvmはperformanceを自動的に改善することができ、これを利用して性能を最適化することを奨励しません.jvmに任せるべきだ.
classの前にfinalを付けると、このクラスが将来継承されることを許可しない準備もできないことを示します.これは、安全なためか、それ自体にサブクラスがないためかもしれません.これはdesign側の原因です.final classのメソッドは継承されないのでfinalされますが、属性はfinalされていません.
友达と交流して、また少し新しい見方がありました.immutableの本意は、クラスのオブジェクトを作成した後、変更されないようにすることです.定数に似ています.他のプログラムを読み取り専用にしたいだけです.つまり、書く方法や修正方法は提供されません.コンストラクション関数を提供するだけで、一度に生成され、変更されません.この角度から見ると、デザインも簡略化されています.このようなオブジェクトに対して、安心して使用することができます.彼があなたが生成したときのオブジェクトであることを知っているので、一度も変えられません.
[b]なぜJDKはこんなに多くのimmutableのクラスを設計するのか.[/b]
immutableクラスはmutableクラスよりも設計、実現、使用しやすいからです.また、エラーが発生しにくく、より安全です.
[b]簡単:[/b]オブジェクトが生成されると値が固定されるので、変わらない.オブジェクトのステータスから見ると、ステータスの変化や移行はありません.逆に、オブジェクトを変えることができる場合、彼の状態の変化は多くなります.彼の可能な変化を説明するには、状態遷移図が必要です.つまり、彼の状態空間が大きい可能性があります.
[b]スレッドセキュリティ:[/b]メソッドが変更されていないため、同期の問題を考慮する必要はなく、同時環境でも安心して同時readを実行できます.
[b]メモリの節約:[/b]オブジェクトが変わらない以上、自由に共有できます.ユーザーは、重複しないで既存のインスタンスをできるだけ使用することができます.定数を定義するように、これらのクラスの静的finalインスタンスプロパティを定義できます.
もちろん、Immutableクラスに静的ファクトリを提供し、ファクトリによって重複するオブジェクトインスタンスが作成されないことを保証することもできます.
これにより、メモリ消費やゴミ回収の負担が節約されます.このようなオブジェクトがあれば、システムの中で大量に、頻繁に、同時に読まれます.このパターンを考慮しない.実はStringは良い例です.
[b]良い構築基盤:[/b]SetとMap、特にmapのkey値をよく使うべきですが、これらの値が何気なく変わったかどうかをよく考える必要がありますか?これにより、setまたはmapの設定の本意に影響します.Immutableの相手を使えば心配しなくてもいいのでは?なぜStringでkey値を作るのが好きなのか.もちろんequalsとhashCodeの書き換えをできるだけ避けたいかもしれません.
[b]このパターンを悪用しないでください[/b]
すべては必ず利益と弊害がある.immutableのオブジェクトは値によって新しいオブジェクトを生成することを知っていますので、オブジェクトと使用方法を慎重に設計してください.たとえばStringでは、ループに文字列を接続する場合、Stringの+番号ではなくBufferString、StringBufferクラスで内容が可変な文字列を表す方法を提案し、下位文字列を変更する方法を提供します.文字の結合を行う場合は、StringクラスではなくStringBufferクラスを使用します.前者は後者より100倍速いからです.これは私たちが自分のデザインをバランスよく知っているかもしれません.immutableクラスのパートナークラスを設計することもできるかもしれません.
私から見れば、構造的な定数を設計したいときは、immutableのクラスを設計することを考えることができます.
JavaのStringクラスがimmutableであることはよく知られています.実はprimaryの包装類はimmutableです.では、immutableのclassをデザインさせたらどうしますか?
immutableとは、変わらないという意味です.変えられない.どのようにしてクラスのオブジェクトを変更しますか?
第一に、このクラスは継承できないと思います.そこでclassの前にfinalを追加します.これは最も直接的な方法であり、最も簡単な方法でもありますが、将来それを拡張したいときはできません.彼の基礎の上でサブクラスを定義したいのもimmutableかもしれません.この場合、classの前にfinalを追加するのではなく、すべての方法にfinalを追加することができ、サブクラスがその方法を書き換えることを防止することができます.実は継承することなくこのクラスを拡張することができ、compositeメソッドを通じて.したがってimmutableクラスの継承は推奨されません.さらに、immutableクラスを継承できない方法もあります.それは、メソッドをプライベートまたはprotected、すなわち保証プライベートにし、次に静的ファクトリメソッドを提供してインスタンスを生産することです.これは、パッケージ内の拡張が可能であり、顧客クラスにとって継承できないため、最も推奨される方法です.同時に静的工場法には構造法よりも良いところがたくさんある.
第二に、属性が変えられないことを考えるかもしれません.fieldの前にもfinalを追加しなければなりません.属性を私有化し、直接アクセスされて修正されないようにしなければなりません.これで十分ですか.他のクラスのオブジェクトの参照プロパティがある場合は?どうやって変わらないと保証しますか?
まずあなたができることは、自分の方法の中でその値を変えないことを保証することです.どうやって他のクラスが直接変えないことを保証しますか?この引用は他の相手があなたに伝えたものですか?どうやって保証しますか?同様に、メソッドでこのプロパティを返すとしたら?考えてみろ.
それがimmutableの自然であれば安心です.でもそうじゃなかったら?
新しい相手をcloneしなければならないようです.cloneについては、liuwang 126の記事[url]を参照してください.http://liuwang126.iteye.com/blog/272595[/url]
次は完全なSampleです.
package immutable;
public class Immutable {
private final int a;
private static final String b;
private final ClassA oa;
static{
b="";
}
public static Immutable getImmutable(int a, ClassA oa){
return new Immutable(a, oa);
}
protected Immutable(int a, ClassA oa){
this.a=a;
this.oa=oa.clone();
}
public ClassA getOA(){
return oa.clone();
}
public int getA() {
return a;
}
public static String getB() {
return b;
}
public static void main(String[] s){
ClassA a = new ClassA(2);
Immutable immutable=new Immutable(1, a);
ClassA a2 = immutable.getOA();
if(a==a2){
System.out.print("a==a2");
}else{
System.out.print("a2.a="+a2.getA());
}
}
}
package immutable;
public class ClassA implements Cloneable{
private int a;
public ClassA(int i){
a=i;
}
public int getA() {
return a;
}
public void setA(int a) {
this.a = a;
}
public ClassA clone(){
ClassA o = null;
try{
o = (ClassA)super.clone();
}catch(CloneNotSupportedException e){
e.printStackTrace();
}
return o;
}
}
package immutable;
final class ChildImmutable extends Immutable{
private final int c;
public ChildImmutable(int a, ClassA oa, int c) {
super(a, oa);
this.c=c;
}
public int getC() {
return c;
}
}
これは一般的な開発ではあまり使われないかもしれません.デザインゲームと見なすことができます.しかし、私たちが自分でAPIを設計して他の人に呼び出す場合は、ルールの厳格さとあなたの意図が正確に表現され、制限されることを考慮しなければなりません.
次にfinalを分析します.
final:designとefficiencyを使う理由は2つあります.メソッドのパラメータにfinalを加えて、入力されたパラメータが変更されないことを保証することができます.この設計は私たちがよく推奨しています.
methodの前にfinalを加える理由も2つあります.1つ目は,クラスのサブクラスがこの方法を書き直さないことを保証し,この方法の挙動は変更されない.これが設計上の理由です.もう1つは、低バージョンjdkでこれを利用することでperformanceを向上させることができます.しかし、メモリ消費に悪影響を及ぼすこともあります.jdk 5以降、jvmはperformanceを自動的に改善することができ、これを利用して性能を最適化することを奨励しません.jvmに任せるべきだ.
classの前にfinalを付けると、このクラスが将来継承されることを許可しない準備もできないことを示します.これは、安全なためか、それ自体にサブクラスがないためかもしれません.これはdesign側の原因です.final classのメソッドは継承されないのでfinalされますが、属性はfinalされていません.
友达と交流して、また少し新しい見方がありました.immutableの本意は、クラスのオブジェクトを作成した後、変更されないようにすることです.定数に似ています.他のプログラムを読み取り専用にしたいだけです.つまり、書く方法や修正方法は提供されません.コンストラクション関数を提供するだけで、一度に生成され、変更されません.この角度から見ると、デザインも簡略化されています.このようなオブジェクトに対して、安心して使用することができます.彼があなたが生成したときのオブジェクトであることを知っているので、一度も変えられません.
[b]なぜJDKはこんなに多くのimmutableのクラスを設計するのか.[/b]
immutableクラスはmutableクラスよりも設計、実現、使用しやすいからです.また、エラーが発生しにくく、より安全です.
[b]簡単:[/b]オブジェクトが生成されると値が固定されるので、変わらない.オブジェクトのステータスから見ると、ステータスの変化や移行はありません.逆に、オブジェクトを変えることができる場合、彼の状態の変化は多くなります.彼の可能な変化を説明するには、状態遷移図が必要です.つまり、彼の状態空間が大きい可能性があります.
[b]スレッドセキュリティ:[/b]メソッドが変更されていないため、同期の問題を考慮する必要はなく、同時環境でも安心して同時readを実行できます.
[b]メモリの節約:[/b]オブジェクトが変わらない以上、自由に共有できます.ユーザーは、重複しないで既存のインスタンスをできるだけ使用することができます.定数を定義するように、これらのクラスの静的finalインスタンスプロパティを定義できます.
package client;
import immutable.ClassA;
import immutable.Immutable;
class Client{
public static final Immutable A = Immutable.getImmutable(1, new ClassA(1));
public static final Immutable B = Immutable.getImmutable(2, new ClassA(2));
}
もちろん、Immutableクラスに静的ファクトリを提供し、ファクトリによって重複するオブジェクトインスタンスが作成されないことを保証することもできます.
これにより、メモリ消費やゴミ回収の負担が節約されます.このようなオブジェクトがあれば、システムの中で大量に、頻繁に、同時に読まれます.このパターンを考慮しない.実はStringは良い例です.
[b]良い構築基盤:[/b]SetとMap、特にmapのkey値をよく使うべきですが、これらの値が何気なく変わったかどうかをよく考える必要がありますか?これにより、setまたはmapの設定の本意に影響します.Immutableの相手を使えば心配しなくてもいいのでは?なぜStringでkey値を作るのが好きなのか.もちろんequalsとhashCodeの書き換えをできるだけ避けたいかもしれません.
[b]このパターンを悪用しないでください[/b]
すべては必ず利益と弊害がある.immutableのオブジェクトは値によって新しいオブジェクトを生成することを知っていますので、オブジェクトと使用方法を慎重に設計してください.たとえばStringでは、ループに文字列を接続する場合、Stringの+番号ではなくBufferString、StringBufferクラスで内容が可変な文字列を表す方法を提案し、下位文字列を変更する方法を提供します.文字の結合を行う場合は、StringクラスではなくStringBufferクラスを使用します.前者は後者より100倍速いからです.これは私たちが自分のデザインをバランスよく知っているかもしれません.immutableクラスのパートナークラスを設計することもできるかもしれません.
私から見れば、構造的な定数を設計したいときは、immutableのクラスを設計することを考えることができます.