设计模式

This commit is contained in:
罗祥
2019-12-02 17:58:59 +08:00
parent 6cd2987838
commit 6858a78396
17 changed files with 694 additions and 17 deletions

Binary file not shown.

Binary file not shown.

View File

@ -14,15 +14,10 @@ public class PhoneFactory {
public Phone getPhone(Class<? extends Phone> phoneClass) {
try {
return (Phone) Class.forName(phoneClass.getName()).newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
} catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) {
e.printStackTrace();
}
return null;
}
}

View File

@ -0,0 +1,23 @@
package com.heibaiying.creational.singleton;
/**
* 使用双重检查锁来保证线程安全
*/
public class DoubleCheckLazySingletonSafe {
private static volatile DoubleCheckLazySingletonSafe instance = null;
private DoubleCheckLazySingletonSafe() {
}
public static DoubleCheckLazySingletonSafe getInstance() {
if (instance == null) {
synchronized (DoubleCheckLazySingletonSafe.class) {
if (instance == null) {
instance = new DoubleCheckLazySingletonSafe();
}
}
}
return instance;
}
}

View File

@ -0,0 +1,23 @@
package com.heibaiying.creational.singleton;
/**
* 利用枚举实现单例
*/
public enum EnumInstance {
INSTANCE;
private String field;
public String getField() {
return field;
}
public void setField(String field) {
this.field = field;
}
public static EnumInstance getInstance() {
return INSTANCE;
}
}

View File

@ -0,0 +1,21 @@
package com.heibaiying.creational.singleton;
import java.io.*;
import java.lang.reflect.Constructor;
public class EnumInstanceTest {
public static void main(String[] args) throws Exception {
// 序列化攻击
EnumInstance instance = EnumInstance.getInstance();
ObjectOutputStream outputStream = new ObjectOutputStream(new FileOutputStream("EnumSingletonFile"));
outputStream.writeObject(instance);
ObjectInputStream inputStream = new ObjectInputStream(new FileInputStream(new File("EnumSingletonFile")));
EnumInstance newInstance = (EnumInstance) inputStream.readObject();
System.out.println(instance == newInstance);
// 反射攻击Enum类中只有一个两个参数的构造器Enum(String name, int ordinal)
Constructor<EnumInstance> constructor = EnumInstance.class.getDeclaredConstructor(String.class, int.class);
constructor.setAccessible(true);
EnumInstance enumInstance = constructor.newInstance("name", 0);
System.out.println(instance == enumInstance);
}
}

View File

@ -0,0 +1,29 @@
package com.heibaiying.creational.singleton;
import java.io.Serializable;
/**
* 利用静态代码块来实现饿汉式单例
*/
public class HungrySingleton implements Serializable {
private static final HungrySingleton instance;
static {
instance = new HungrySingleton();
}
private HungrySingleton() {
if (instance != null) {
throw new RuntimeException("单例模式禁止反射调用");
}
}
public static HungrySingleton getInstance() {
return instance;
}
private Object readResolve() {
return instance;
}
}

View File

@ -0,0 +1,19 @@
package com.heibaiying.creational.singleton;
/**
* 线程不安全的懒汉式单例模式
*/
public class LazySingletonUnsafe {
private static LazySingletonUnsafe instance = null;
private LazySingletonUnsafe() {
}
public static LazySingletonUnsafe getInstance() {
if (instance == null) {
instance = new LazySingletonUnsafe();
}
return instance;
}
}

View File

@ -0,0 +1,15 @@
package com.heibaiying.creational.singleton;
import java.lang.reflect.Constructor;
/**
* 利用反射破坏单例
*/
public class ReflectionDamage {
public static void main(String[] args) throws Exception {
Constructor<HungrySingleton> constructor = HungrySingleton.class.getDeclaredConstructor();
constructor.setAccessible(true);
HungrySingleton hungrySingleton = constructor.newInstance();
System.out.println(hungrySingleton);
}
}

View File

@ -0,0 +1,17 @@
package com.heibaiying.creational.singleton;
import java.io.*;
/**
* 利用序列化破坏单例
*/
public class SerializationDamage {
public static void main(String[] args) throws IOException, ClassNotFoundException {
HungrySingleton instance = HungrySingleton.getInstance();
ObjectOutputStream outputStream = new ObjectOutputStream(new FileOutputStream("SingletonFile"));
outputStream.writeObject(instance);
ObjectInputStream inputStream = new ObjectInputStream(new FileInputStream(new File("SingletonFile")));
HungrySingleton newInstance = (HungrySingleton) inputStream.readObject();
System.out.println(instance == newInstance);
}
}

View File

@ -0,0 +1,21 @@
package com.heibaiying.creational.singleton;
/**
* 利用静态内部类来实现饿汉式单例
*/
public class StaticInnerClassHungrySingleton {
private static class InnerClass {
private static StaticInnerClassHungrySingleton instance = new StaticInnerClassHungrySingleton();
}
public static StaticInnerClassHungrySingleton getInstance() {
return InnerClass.instance;
}
private StaticInnerClassHungrySingleton() {
if (InnerClass.instance != null) {
throw new RuntimeException("单例模式禁止反射调用");
}
}
}

View File

@ -0,0 +1,10 @@
package com.heibaiying.creational.singleton;
public class ZTest {
public static void main(String[] args) {
HungrySingleton hungrySingleton = HungrySingleton.getInstance();
StaticInnerClassHungrySingleton staticInnerClassHungrySingleton = StaticInnerClassHungrySingleton.getInstance();
DoubleCheckLazySingletonSafe doubleCheckLazySingletonSafe = DoubleCheckLazySingletonSafe.getInstance();
EnumInstance instance = EnumInstance.getInstance();
}
}