網(wǎng)站建設服務版權(quán)歸誰2022網(wǎng)站seo
2023-05-09 設計模式(單例,工廠)
單例模式
顧名思義,就是整個系統(tǒng)對外提供的實例有且只有一個
特點:
? 1、單例類只有一個實例
? 2、必須是自己創(chuàng)建唯一實例
? 3、必須給所以對象提供這個實例
分類:一般分為餓漢式單例(直接實例化)和懶漢式單例(使用時才實例化)
餓漢式單例
public class SingletonTest {//構(gòu)造器私有化,防止外部調(diào)用private SingletonTest() {}//直接實例化private static SingletonTest sin = new SingletonTest();public static SingletonTest getInstance(){return sin;}
}
懶漢式單例
同步鎖(當然還有簡單的,去掉synchronized,只是存在安全問題)
public class SingletonTest1 {//構(gòu)造器私有化,防止外部調(diào)用private SingletonTest1() {}private static SingletonTest1 sin = null;//使用同步鎖保證一定會創(chuàng)建,并且只會創(chuàng)建一次public static synchronized SingletonTest1 getInstance(){if(sin == null){sin = new SingletonTest1();}return sin;}
}
雙重檢測鎖
public class SingletonTest2 {//構(gòu)造器私有化,防止外部調(diào)用private SingletonTest2() {}//使用volatile,在這里的作用是禁止指令重排//sin = new SingletonTest2();不是一個原子操作//第一步、申請內(nèi)存,第二步、初始化,第三步、地址引用給sin//如果第三步在第二步前面就執(zhí)行了,此時另一個現(xiàn)場通過getInstance獲取實例時進來判斷就不為null了,直接返回,而這個時候其實還并沒有實例化//synchronized只能保證代碼塊相較于外面是正常順序,代碼塊內(nèi)部還是可能由于指令優(yōu)化導致第三步在第二步前面就執(zhí)行了private static volatile SingletonTest2 sin = null;//為什么要判斷兩次呢//第一次是為了減少同步,不用每次進來都去加鎖//第二次是如果現(xiàn)在有兩個現(xiàn)場同時競爭鎖,那必然有一個是處于阻塞狀態(tài)的//當處于阻塞狀態(tài)的線程拿到鎖后,前面的線程肯定是已經(jīng)創(chuàng)建過實例了//如果這個時候不判斷一下的話就會有實例化一次public static SingletonTest2 getInstance(){if(sin == null){synchronized (SingletonTest2.class){if(sin == null){sin = new SingletonTest2();}}}return sin;}
}
內(nèi)部類
public class SingletonTest3 {//構(gòu)造器私有化,防止外部調(diào)用private SingletonTest3() {}private static SingletonTest3 sin = null;public static SingletonTest3 getInstance(){return SingletonClass.singleton;}//內(nèi)部類只有在使用的時候才會初始化,其中初始化是jvm控制的,單線程操作,保證了線程安全,也實現(xiàn)了懶漢式private static class SingletonClass{private static SingletonTest3 singleton = new SingletonTest3();}
}
工廠模式
工廠模式主要是為了屏蔽創(chuàng)建對象的過程,主要分為三類(靜態(tài)工廠,普通工廠,抽象工廠)
靜態(tài)工廠(簡單工廠)
public interface FactoryTest {void doSome();
}public class FactoryTest1 implements FactoryTest {@Overridepublic void doSome() {System.out.println("FactoryTest1");}
}public class FactoryTest2 implements FactoryTest {@Overridepublic void doSome() {System.out.println("FactoryTest2");}
}public class StaticFactory {public static FactoryTest creatTest(String name){if("FactoryTest1".equals(name)){return new FactoryTest1();}else if("FactoryTest2".equals(name)){return new FactoryTest2();}return null;}
}public class Test1 {public static void main(String[] args) {//通過StaticFactory工廠創(chuàng)建對應的實例類FactoryTest factoryTest1 = StaticFactory.creatTest("FactoryTest1");factoryTest1.doSome();FactoryTest factoryTest2 = StaticFactory.creatTest("FactoryTest2");factoryTest2.doSome();}
}
每次新增一個FactoryTest時,需要修改StaticFactory.creatTest()方法,這樣不合理,所以有了普通工廠模式
普通工廠
public interface FactoryTest {void doSome();
}public class FactoryTest1 implements FactoryTest {@Overridepublic void doSome() {System.out.println("FactoryTest1");}
}public class FactoryTest2 implements FactoryTest {@Overridepublic void doSome() {System.out.println("FactoryTest2");}
}public interface ICommonFactory {FactoryTest createTest();
}public class CommonFactory1 implements ICommonFactory {@Overridepublic FactoryTest createTest() {return new FactoryTest1();}
}public class CommonFactory2 implements ICommonFactory {@Overridepublic FactoryTest createTest() {return new FactoryTest2();}
}public class Test1 {public static void main(String[] args) {//通過CommonFactory1工廠創(chuàng)建對應的實例類new CommonFactory1().createTest().doSome();new CommonFactory2().createTest().doSome();}
}
每次新增一個FactoryTest時,只需要新增一個對應的CommonFactory工廠實現(xiàn)類就行,對于之前的工廠和對象不影響
抽象工廠
現(xiàn)在有手機和平板,可以使用上述的普通工廠來創(chuàng)建,但現(xiàn)在給手機和平板分了牌子,有華為手機和蘋果手機,華為平板和蘋果平板,這樣一個產(chǎn)品族的概念(分為手機和平板兩個產(chǎn)品族,手機產(chǎn)品族里面包含了華為手機和蘋果手機兩個產(chǎn)品),那么就可以使用抽象工廠模式。
//手機產(chǎn)品族
public interface Phone {void doSome();
}
public class PhoneHuawei implements Phone {@Overridepublic void doSome() {System.out.println("華為手機");}
}
public class PhonePinguo implements Phone {@Overridepublic void doSome() {System.out.println("蘋果手機");}
}//平板產(chǎn)品族
public interface Tablet {void doSome();
}
public class TabletHuawei implements Tablet {@Overridepublic void doSome() {System.out.println("華為平板");}
}
public class TabletPinguo implements Tablet {@Overridepublic void doSome() {System.out.println("蘋果平板");}
}//工廠
public interface AbsFactory {Phone buyPhone();Tablet buyTablet();
}
//華為工廠
public class HuaweiFatory implements AbsFactory{@Overridepublic Phone buyPhone() {return new PhoneHuawei();}@Overridepublic Tablet buyTablet() {return new TabletHuawei();}
}
//蘋果工廠
public class PinguoFatory implements AbsFactory{@Overridepublic Phone buyPhone() {return new PhonePinguo();}@Overridepublic Tablet buyTablet() {return new TabletPinguo();}
}public class Test1 {public static void main(String[] args) {HuaweiFatory huaweiFatory = new HuaweiFatory();huaweiFatory.buyPhone().doSome();huaweiFatory.buyTablet().doSome();PinguoFatory pinguoFatory = new PinguoFatory();pinguoFatory.buyPhone().doSome();pinguoFatory.buyTablet().doSome();}
}