参考記事:
- 全体的にします。https://www.cnblogs.com/adamjwh/p/9033545.html
- シングルトンます。https://www.cnblogs.com/ygj0930/p/10845530.html
以下に分割スキーマを作成します。
シングルトン(シングルトン)モード:同時オブジェクトおよびメソッドへのアクセスを確保するために、マルチスレッド操作の唯一のインスタンス
のプロトタイプ(原型)モード:その複製によってプロトタイプとしてオブジェクト、および同様のプロトタイプの複数のクローニング新しいインスタンス。
ファクトリメソッド(FactoryMethod)モード:製品を作成するために使用されるファクトリインタフェースの定義、生成サブクラスA製品。
抽象ファクトリー(AbstractFactory)モード:各サブクラスが生成することができ、インターフェースの製品ファミリを作成します一連の関連商品。
ビルダー(ビルダー)モード:複雑なオブジェクト比較的単純なの複数の部分にそして、それぞれの異なるニーズに応じてそれらを作成し、最終的には複雑なオブジェクトを構築します。
A、シングルトン
-
定義:クラスの唯一のインスタンスシングルトンパターン確保し、システム全体を提供するために、インスタンスをインスタンス化します。コンピュータシステム、スレッドプール、キャッシュ、ログオブジェクト、ダイアログボックス、プリンタでは、グラフィックスドライバオブジェクトは、多くの場合、一の実施形態で設計されています
-
特長:
1):1つのだけのインスタンス
2):あなたは、独自の一意のインスタンスを作成しなければならない
3):この例は、他のすべてのオブジェクトに提供する必要があります
)4:施工方法に加えて、他のは静的です
1. 怠惰な人間(自分のインスタンス化の最初の呼び出し時)
public class Singleton{
//将构造函数设置为私有,避免类在外部实例化
private Singleton(){}
//设置为静态,这样就可以每一次调用都是同一个对象
private static Singleton single=null;
public static Singleton getInstance(){
//只有在没有实例的情况下才创建实例,保证只有一个实例
if(single==null){
single=new Singleton();
}
return single;
}
}
クラスのコンストラクタによって定義シングルトンが同じ範囲内に、外部から仮想マシンを回避をインスタンス化され、唯一のインスタンスのみアクセスすることができるシングルトンのgetInstance()メソッドがプライベートです。
(実際には、Javaリフレクション機構を介してクラスのコンストラクタをインスタンス化することができますプライベートで、それが実質的にすべて失敗し、Javaの単一の実施形態の原因となる。この問題は、暫定的に反射のないことを信じて欺く、ここで議論されていません。)
しかし、セキュリティ上の問題を考慮していない、それはスレッドセーフを、同時インスタンスシングルトン環境は、より可能性が高いスレッドセーフを達成することですされていない、3つの方法があります怠惰なシングルスレッドの上記の例を達成するために、このメソッドのgetInstanceの転換です、あなたの最初の接触シングルトン場合は、スレッドの安全性は非常に理解していない怠惰な人間のシングルトンスレッドセーフことを保証するために、あなたは、次の3つのストリップをスキップすることができ、そのような背後を見ているように飢えた男、単一の例を参照してくださいスレッドの安全性の問題を検討するために戻って行きます。
- 同期方法は、のgetInstanceに適用されます
public static synchronized Singleton getInstance(){
if(single == null){
single=new Singleton();
}
return single;
}
- ダブルチェックロッキング
A.の2つの判決のヌルはの偉大な感覚であることに注意してください
- 最初はヌルオブジェクトにそれがロックされている場合にのみ、彼が作成したすべての時間を作ることです
- 第二は、2つのスレッドがメソッドにアクセスしたときに最初のスレッドがインスタンスを作成した後にロックを解除する最初の空の判定方法、項目、閉塞、に、判定ヌルを防止することで、また第二の入力ロックは、また、状況のインスタンスを作成しました。
II。volatileキーワードを追加する必要がある以上、オブジェクトのインスタンスで
- エラーが発生することがない場合はここで揮発性、すなわち、コードの読み取りは、ライン11上の文と判定された場合、インスタンスがnullではありませんが、参照されるオブジェクトのインスタンスは、初期化が終了しない場合があります、スレッドは、オブジェクトへのアクセスが初期化されていない必要があります。コードの最初の14行は、オブジェクトを作成するためであり、このコードは、擬似コードの三行に分解することができる理由、すなわちメモリ・オブジェクトを割り当て、オブジェクトを初期化し、メモリアドレスだけ割り当てられたポイントインスタンスは、1,2と呼ばれ初期化は、最終ステップになった後2と3の間に3は、並べ替え並べ替えてもよいです。したがって、イントラスレッドセマンティクススレッドAは、(Javaプログラムを実行するとき、すべてのスレッドがイントラスレッドセマンティクスに準拠する必要があり、それはシングルスレッドで結果を並べ替えることを確認するプログラムを変更しない)変更が、A2及びA3の並べ替えていませんスレッドBは、インスタンスが空でないと判断された原因と、次のスレッドが場合、参照されるオブジェクトのインスタンスBにアクセスするには、スレッドBは、オブジェクトへのアクセスに初期化されていないがあります。遅延は、揮発性の初期化スレッドセーフを使用して達成することができ、性質は遅延初期化スレッドの安全性を確保するために、2と3の間で並べ替えによって禁止されている場合。
public class Singleton {
private volatile static Singleton instance;
private static Object syncRoot = new Object();
private Singleton() {
}
public static Singleton getInstance() {
//双重锁定
if(instance == null) {
synchronized (syncRoot) {
if(instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
- 静的内部クラス(両方のスレッドセーフを実現するだけでなく、同期による性能への影響を避けるため)。
クラスローディングの使用は、インスタンスを作成するインスタンスを1つだけ確実にするために
短所:クラスがロードされたとき、初期化時間が長くなると作成されたオブジェクトを作成するために遅らせることはありませんが発生します
public class Singleton {
//静态内部类
private static class SingletonHolder {
public static Singleton instance = new Singleton();
}
private Singleton() {
}
public static Singleton getInstance() {
return SingletonHolder.instance;
}
}
例2は、単一の飢え(初期クラスで自分でインスタンス化されます)
同時に空腹中国風のクラスがすでにシステムで使用される静的オブジェクトを作成して作成もはや変更されますので、本質的にスレッドセーフ。
public class Singleton{
private Singleton(){}
//定义为final和static,无法修改
private static final Singleton single = new Singleton().;
public static Singleton getInstance(){
return single;
}
}
上記4つの方法の欠点は、単一の実施形態を実現します
実施形態は、単一の直列化復元を破壊します。1.
それはgetXX()メソッドデシリアライズされたときには、このようにバイパスlogicsheetsの実施形態では、新たなオブジェクトの直接生成、単一の実施形態の破壊を確実に、呼び出されません。
ソリューション:
- メソッドオーバーライドデシリアライズクラスメソッドではなく、新しいオブジェクトを作成するよりも、デシリアライズ単一の実施形態を返します。
public class Singleton implements Serializable{
//当前实例
public static Singleton INSTANCE = new Singleton();
//双重锁定部分代码
。。。
//重写反序列化,使其直接返回当前实例
private Object readResolve() {
return INSTANCE;
}
}
- プライベートコンストラクタを書き換え
//维护一个volatile的标志变量在第一次创建实例时置为false;重写构造函数,根据标志变量决定是否允许创建。
private static volatile boolean flag = true;
private Singleton(){
if(flag){
flag = false; //第一次创建时,改变标志
}else{
throw new RuntimeException("The instance already exists !");
}
使用する最善の方法 - シングルモードの列挙の例を使用して
public enum singletonEnum{
INSTANCE;
private String name;
public String getName(){
return name;
}
public void setName(String name){
this.name=name;
}
}
理由
- 使用SingletonEnum.INSTANCEアクセス、メソッドを定義し、メソッドのgetInstanceを呼び出すために不要になりました
- JVM固有の列挙インスタンスが、単一の実施形態の破壊が発生し、上述した反射およびデシリアライゼーションを回避する、列挙型の各々は、列挙を定義した後、JVMは一意です。
(列挙型列挙オブジェクトのname属性が出力された場合にのみ配列の結果、逆シリアル化時間であるjava.lang.Enumの名前ルックアップvalueOfメソッドによって列挙オブジェクトによれば)- 注:コンパイラは禁止列挙型のwriteObject、readObjectメソッド、readObjectNoData、にwriteReplaceはreadResolveおよびその他のメソッドをオーバーライドする必要があります。)
プロトタイプモード
- 該当するシーン:
- 同一または類似のオブジェクト間、唯一のいくつかの異なる個々のプロパティとき
- 面倒なオブジェクトが、コンビニのコピーを作成します。
- オブジェクトは元のオブジェクト、同じプロパティ値が、異なるアドレスオブジェクトの外ではありません、あなたが同様の多数のオブジェクトを作成することができますコピーします。
- コードの実装(Cloneableインタフェースは、Javaのラインを使用して実装)
//具体原型类
class A implements Cloneable{
//写一个自定的构造方法,方便理解
A(){
System.out.println("具体原型创建成功");
}
public Object clone throws CloneNotSupportedException{
System.out.println(“具体原型复制成功”);
return (A)super.clone();
}
}
//原型模式的测试类
public class B{
public static void main(String[] args)throws CloneNotSupportedException
{
A obj1=new A();
A obj2=(A)obj1.clone();
System.out.println("obj1==obj2?"+(obj1==obj2));
}
}
- 結果は以下のとおりであります
具体的なプロトタイピングの成功!
具体的なプロトタイプ複製成功!
obj1とobj2が==?偽
ファクトリパターン
- 該当するシーン:
- 反対側には、明確なの製品名のみ生産工場を、特定の製品名がわかりません
- 特定の植物上のオブジェクトによって生成された製品を作成し、抽象的な工場は、オブジェクトのインタフェースを作成するための唯一の責任があります
- お客様が唯一の製品は細部を気にしない、ブランドを気に
- 一般的な構造
- 抽象ファクトリー:オブジェクトを作成するためのインタフェースメソッドを提供します
- コンクリート工場:インプリメンテーションのオブジェクトを作成し、別の工場が異なる製品のオブジェクトを作成するには
- 要約製品:定義製品仕様、製品の主な特徴についての説明
- 具体的な製品:特定の工場、およびプラント固有の対応によって作成された、抽象製品を実装します。
- 実現モード
/**
*产品类
**/
//抽象产品
interface product{
public void show();
}
//具体产品1
class proA implements product{
@Override
public void show() {
System.out.println("A");
}
}
//具体产品2
class proB implements product{
@Override
public void show(){
System.out.println("B");
}
}
/**
*工厂类
**/
//抽象工厂
interface factory {
product getPro();
}
//具体工厂1
class facA implements factory{
@Override
public product getPro(){
return new proA();
}
}
//具体工厂2
class facB implements factory {
@Override
public product getPro() {
return new proB();
}
}
Abstract Factoryパターン
- 特長:特定の工場だけでなく、特定の製品を製造する場合
- 実装(変更ファクトリクラス)
···
インターフェースAbstractFactory
{
公共newProduct1製品1)が(ある
公共newProduct2 Product2です();
}
AbstractFactory ConcreteFactory1実装クラス
{
公共製品1はnewProduct1()は
{
のSystem.out.println( "詳細発生プラント1 - > ...特定製品11");
戻り新しい新しいConcreteProduct11();
}
公共Product2はnewProduct2()である
{
System.out.printlnは( "詳細発電プラント1 - > ...特定製品21が");
戻り新しい新しいConcreteProduct21();
}
}
···
ビルダーモード
- 該当シーン
- オブジェクトがあり、より複雑な作成しました複数の成分複合体の各メンバーは、メンバーの間で安定した順序の構造を変化させるであろう。
- ビルドプロセスと最終製品は、独立した際に表し
-
個人的な理解:製品実現とセグメント化された建設プロセスと建設のさまざまなコンポーネントは、順序を達成すること、製品変更の構築プロセス場合、ビルダーは、変更する必要があり、製品の相対的な変化の成分が存在する場合、別々に各成分の具体的な実現を変更し、及びビルダーと司令を分離し、場合建設プロセスが変更されたときに、プロセスの変更の構成の詳細は、唯一の特定の建設方法を変更する必要がビルダーことができますが、唯一の私たちは、司令官を変更する必要があります
-
一般的な構造
- 製品の役割は:さまざまなコンポーネントを達成するために、あること、複雑なオブジェクトの複数のコンポーネントが含まれています
- 要約ビルダーは:製品の下位区分を作成するための抽象メソッドが含まれています
- 具体的なビルダー:抽象実装インタフェースビルダ
- 司令官:メソッド呼び出しビルダーは、複雑なオブジェクトの建設を完了します
それは、個々のスケジュールによって、建物の完全な別の部分に請負業者、建設請負業者を指示している労働者、によって建てられた建物の建設のプロセスに似ている、建物の建設を完了
- 実装コード
public class Abc {
public static void main(String[] args) {
//创建一个建造者
ture_builder ture_builder=new ture_builder();
//创建一个指挥者,并且给他建造者
boss boss=new boss(ture_builder);
product product=boss.build();
System.out.println();
}
}
//产品角色
class product{
//部分1
String pat1;
String pat2;
public void show(){
System.out.println("aaa");
};
}
//抽象建造者
abstract class builder{
abstract void getpat1();
abstract void getpat2();
abstract product getres();
}
//具体建造者
class ture_builder extends builder{
product pro1=new product();
@Override
void getpat1() {
pro1.pat1="1";
System.out.println("建造pat1部分");
}
@Override
void getpat2() {
pro1.pat2="2";
System.out.println("建造pat2部分");
}
@Override
product getres() {
return pro1;
}
}
//指挥者
class boss{
private ture_builder ture_builder;
boss(ture_builder ture_builder){
this.ture_builder=ture_builder;
}
product build(){
ture_builder.getpat1();
ture_builder.getpat2();
return ture_builder.getres();
}
}