ディレクトリ
例1.シングルモード
1.1飢えモード
1.2レイジー・モード
1.3その他のシングルトン
2.プロトタイプモデル
2.1浅いクローン
2.2深いクローニング
3.ファクトリパターン
3.1単純なファクトリパターン
3.2ファクトリメソッド
4. Abstract Factoryパターン
5.ビルダーモード
Singletonパターン(シングルトン)
クラスのインスタンスを1つだけ確認し、グローバルなアクセスポイントのインスタンスへのアクセスを提供します。
利点:形成単なる一例による、システムのパフォーマンス・オーバーヘッドを低減します。あなたは、システム内のグローバルアクセスポイントを設定した環境で共有リソースへのアクセスを向上させることができます。このように単一の実施形態を提供することができるクラスは、すべてのデータマッピングテーブルを処理する責任があります。
一般的なSingletonパターン:
飢えモード(スレッドセーフな、高効率の呼び出しではなく、遅延ロード)(メイン)
レイジーモード(メイン)を(スレッドセーフは、ロードを遅らせることができ、効率が高くない呼び出し)
(基礎となるJVM内部モデルによる、時折問題、推奨されません)デュアル検出ロック
静的内部クラスタイプ(スレッドセーフな、高呼効率、遅延ロード)
列挙シングルトン(スレッドセーフな、高効率の呼び出しではなく、遅延ロード)
シングルトンUMLダイアグラム:
(1)モード飢え
質問:あなたはこのクラスをロードした場合は、このクラスのgetInstance()メソッドを呼び出していない、またはこのクラスを呼び出すことは決してしないでください。それは資源の無駄になります。
class eh{ //(1)直接创建私有实例对象 private static final eh texteh = new eh(); //(2)私有无参的构造函数 private eh() {} //(3)唯一一个公用的调用实例的方法 public static eh getInstance() { return texteh; } }
(2) 懒汉模式
问题:资源利用效率高了。但是,每次调用getInstance()方法都要同步,并发效率较低。
class lh{ //(1)使用volatile保证所有线程安全 private static volatile lh textlh = null; //(2)私有无参构造 private lh() {} //(3)添加同步synchronized public static synchronized lh getInstance() { //如果是第一次调用的,就创建。否则,使用原来创建的 if(textlh == null) { textlh = new lh(); } return textlh; } }
(3)其他单例模式
双重检测锁:提高了利用效率,不必每一次都需要进行同步。只是同步第一次。其他的都不用同步。
class scjc{ private static scjc jc = null; private scjc() {} private static scjc getInstance() { if(jc == null) { scjc jcs; synchronized (scjc.class) { jcs = jc; if(jcs == null) { synchronized (scjc.class) { if(jcs == null) { jcs = new scjc(); } } } } } return jc; } }
静态内部类:静态内部类不会立即加载,只要调用了getInstance()方法才会加载。tt的加载只会创建一次,只能被赋值一次,保证了线程的安全。兼备了高并发调用和延迟加载的优势。
class text{ private static class text2{ //静态内部类 private static final text tt = new text(); } //私有无参构造 private text() {} public static text getInstance(){ return text2.tt; } }
枚举实现类式:枚举本身就是一个单例模式,有JVM的保障,避免了通过反射和反序列化的漏洞。
public enum text { tt; //直接调用,就可以获取单例对象 //添加自己的方法 public void getOther() {} }
二、原型模式(Prototype)
将一个对象作为原型,克隆复制出多个和原型类似的新实例。克隆类似于new,但是不同于new。new创建新的对象属性采用的是默认值。克隆出来的对象属性和原型的完全一样,并且改变新克隆出来的对象不会影响原型对象。克隆的实现需要实现Cloneable接口和重写clone方法。克隆出来的是一个新的对象,不是单例。
克隆分为深克隆、浅克隆。
1、浅克隆:
浅克隆克隆的不是全部的原型,如果原型在克隆的过程中被修改了。那么克隆的是修改后的东西
public class text implements Cloneable{ private String name; public text(String name) { super(); this.name = name; } //补全get、set方法 @Override protected Object clone() throws CloneNotSupportedException { return (text)super.clone();//浅克隆 } public static void main(String[] args){ text tt = new text("huang"); text clone = (text) tt.clone();//克隆 tt.setName("ling"); //克隆的时候被修改了属性 System.out.println(tt.getName()); System.out.println(clone.getName()); } }
2、深克隆
深克隆的是对整个对象进行克隆。就算在克隆途中改变了属性,也不会影响克隆体。
public class text implements Cloneable{ private String name; private Date date; public text(String name,Date date) { super(); this.name = name; this.date = date; } //补全get、set方法 @Override protected Object clone() throws CloneNotSupportedException { Object obj = super.clone(); text tt = (text)obj; tt.name = (String)this.name; //如果是一般数据类型。 tt.date = (Date)this.date.clone();//其他类型 return obj;//浅克隆 } public static void main(String[] args) throws CloneNotSupportedException { text tt = new text("huang",new Date(2020,1,3)); text clone = (text) tt.clone();//克隆 tt.setName("ling"); //属性被修改 tt.setDate(new Date(2020,1,2)); System.out.println(tt.getName()+","+tt.getDate()); System.out.println(clone.getName()+","+clone.getDate()); } }
三、工厂模式(Factory Method)
定义一个创建产品对象的工厂接口,将产品对象的实际创建交给具体的子类去完成。
工厂模式分为:简单工厂模式、工厂方法模式。
简单工厂方法:
如果只要一个工厂类就可以完成的。不属于GOF的模式。
public class textFactory { public static void main(String[] args) { // TODO Auto-generated method stub //实现工厂 Factory factory = new Factory(); factory.createMD().show(); //生产美的空调 factory.createGL().show(); //生产格力空调 } } interface Product{ //定义接口 public void show(); } class md implements Product{ //实现接口的产物 @Override public void show() { System.out.println("我是美的空调!"); } } class gl implements Product{ //实现接口的产物 @Override public void show() { System.out.println("我是格力空调!"); } } class Factory{ //定义工厂类 只有一个简单的工厂 public Product createMD() {//生产美的 return new md(); }; public Product createGL() { //生成格力 return new gl(); } }
工厂方法:
就是专门创建一个工厂类的接口,来进行工厂类的管理。
public class textFactory { public static void main(String[] args) { // TODO Auto-generated method stub //创建美的工厂 AbstractFactory md = new ConcreateFactory1(); md.newProduct().show(); //生产美的空调 //创建格力工厂 AbstractFactory gl = new ConcreateFactory2(); gl.newProduct().show(); //生产格力空调 } } interface Product{ //定义接口 public void show(); } class md implements Product{ //实现接口的产物 @Override public void show() { System.out.println("我是美的空调!"); } } class gl implements Product{ //实现接口的产物 @Override public void show() { System.out.println("我是格力空调!"); } } interface AbstractFactory{ //工厂接口类 public Product newProduct(); } //创建美的空调的工厂 class ConcreateFactory1 implements AbstractFactory{ @Override public Product newProduct() { return new md(); } } //创建格力空调工厂 class ConcreateFactory2 implements AbstractFactory{ @Override public Product newProduct() { return new gl(); } }
四、抽象工厂方法(Abstract Factory)
提供一个创建一组相关或相互依赖对象的接口,且访问类无需指定所要产品的具体类就能得到同族的不同等级的产品的模式结构。
产品族:同一个具有工厂所生产的位于不同等级的一组产品。
public class textFactory { public static void main(String[] args) { // TODO Auto-generated method stub //这里使用了用抽象工厂来创建不同品质等级的汽车零件。 //1、生产高质量汽车零件 AbstractFactory gzl = new gcar();//高质量汽车工厂 gzl.newProduct1().showWK(); gzl.newProduct2().showFDJ(); //2、生产低质量汽车零件 AbstractFactory dzl = new dcar();//低质量汽车工厂 dzl.newProduct1().showWK(); dzl.newProduct2().showFDJ(); } } interface Product1{ //产品一 (生产汽车外壳) public void showWK(); } interface Product2{//产品二 (生产汽车发动机) public void showFDJ(); } //不同品质的成品 class gcs implements Product1{ //高品质外壳 @Override public void showWK() { System.out.println("高质量外壳"); } } class dcs implements Product1{ //低品质外壳 @Override public void showWK() { System.out.println("低质量外壳"); } } class gfdj implements Product2{ //高品质发动机 @Override public void showFDJ() { System.out.println("高质量发动机"); } } class dfdj implements Product2{ //低品质发动机 @Override public void showFDJ() { System.out.println("低质量发动机"); } } //抽象工厂 interface AbstractFactory{//需要产出的不同的品质的产品。(产品族) public Product1 newProduct1(); //生产不同品质的外壳 public Product2 newProduct2(); //生产不同品质的发动机 } class gcar implements AbstractFactory{//高质量汽车 @Override public Product1 newProduct1() { return new gcs(); //高质量外壳 } @Override public Product2 newProduct2() { return new gfdj(); //高质量发动机 } } class dcar implements AbstractFactory{//低质量汽车 @Override public Product1 newProduct1() { return new dcs();//低质量外壳 } @Override public Product2 newProduct2() { return new dfdj(); //低质量发动机 } }
五、建造者(Builder)
指将一个复杂对象的构造与它的表示分离,使同样的构建过程可以创建不同的表示。就是将对象的构建和装配进行解耦。
public class textBuilder { public static void main(String[] args) { // TODO Auto-generated method stub //先产出材料 (炫彩材料) Builder xc = new xc(); //或者换回 普通材料 //指挥者进行指挥 Director director = new Director(xc); //显示墙 director.construct().show(); } } //实体产物 class Product{ private String zt;//砖头 private String sn;//水泥 public void setZt(String zt) { this.zt = zt; } public void setSn(String sn) { this.sn = sn; } //建造出来的墙 public void show() { System.out.println("建造出来的墙:使用砖头:"+zt+";水泥:"+sn); } } //抽象建造者 abstract class Builder{ //使用protected,为了可以给子类使用 protected Product p = new Product(); abstract void getzt();//给子类工厂进行修饰 abstract void getsn();//给子类工厂进行修饰 public Product getResult() { return p; } } //第一个修饰工厂 class xc extends Builder{//炫彩材料 @Override void getzt() { p.setZt("七彩砖"); } @Override void getsn() { p.setSn("混合凝土"); } } class pt extends Builder{//普通材料 @Override void getzt() { p.setZt("沙砖"); } @Override void getsn() { p.setSn("单一凝土"); } } //指挥者 class Director{ private Builder builder; public Director(Builder builder) { super(); this.builder = builder; } public void setBuilder(Builder builder) { this.builder = builder; } //指挥者进行指挥装配 public Product construct() { builder.getzt(); builder.getsn(); return builder.getResult(); } }