对扩展开发,对修改关闭
继承必须确保超类所拥有的子类的性质在子类中仍然成立
面向接口编程,不要面向实现编程,降低程序之间的耦合性
控制类的粒度大小,将对象解耦,提高其内聚性
要为各个类创建他们专用的接口
只于你的直接朋友交谈,不跟陌生人交谈
尽量先使用组合或者聚合等关联来实现,其次才考虑使用集成关系来实现
public class Hunger{
private Hunger(){}
private final static Hunger HUNGER_SINGLTON = new Hunger();
public static Hunger getInstrente(){
return HUNGER_SINGLTON;
}
}
public class LayzeMan{
private static LayzMan LAYZE_MAN;
private LayzeMan(){
System.out.println(Thread.currentThread().getName()+"ok");
}
public static LayzeMan getInstrence(){
if(LAYZE_MAN == null){
LATZE_MAN = new LayzeMan();
}
return LAYZE_MAN;
}
}
/**
该单例模式在使用普通创建对象时,可以实现对象的单例
还存在两个问题
public class Layze{
private volatile static Layze lay;
private Layze(){
}
/**
三重检测锁 DCL模式
**/
public static Layze getInstance(){
if(lay == null){
synchorized(Layze.class){
if(lzy == null){
lay = new Layze();
}
}
}
}
}
此时使用多线程破坏单例模式的问题已经可以解决
public calss LayzeMan{
private static volatile LayzeMan layze;
private LayzeMan(){
synchorized(LayzeMan.class){
if(layze !=null){
throw new RuntimeException("不要试图使用反射去破坏我的单例模式");
}
}
}
public static LayzeMan getInstrence(){
if(layze == null){
synchorized(LayzeMan.class){
if(layze == null){
layze = new LayzeMan();
}
}
}
return layze;
}
}
class test{
public static void main(String[] args){
LayzeMan layzeMan = LayzeMan.getInstrence();
Constructor<LazyPJie> declaredConstructor = LazyPJie.class.getDeclaredConstructor(null);
declaredConstructor.setAccessible(true);
LazyPJie lazyPJie1 = declaredConstructor.newInstance();
System.out.println(lazyPJie);
System.out.println(lazyPJie1);
}
}
此时会报错
Exception in thread "main" java.lang.reflect.InvocationTargetException
at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:499)
at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:480)
at com.itcast.designMode.single.Test01.main(LazyPJie.java:41)
Caused by: java.lang.RuntimeException: 不要试图使用反射破坏单例模式
此时还会有一个问题:就是在类中判断对象是否为空时,判断了有没有第一个对象用普通方式去创建对象的时候,这个时候使用反射的时候就会报出异常,但是,此时如果两个对象都使用反射去创建就会出问题,单例模式就会又被破坏
public static void main(String[] args) throws Exception {
/* LazyPJie lazyPJie = LazyPJie.getInstance();*/
Constructor<LazyPJie> declaredConstructor = LazyPJie.class.getDeclaredConstructor(null);
declaredConstructor.setAccessible(true);
LazyPJie lazyPJie1 = declaredConstructor.newInstance();
LazyPJie lazyPJie = declaredConstructor.newInstance();
System.out.println(lazyPJie);
System.out.println(lazyPJie1);
}
public calss LayzeMan{
private static volatile LayzeMan layze;
private static boolean flag = flase;
private LayzeMan(){
synchorized(LayzeMan.class){
if(!flag){
flag = ture;
}else{
throw new RuntimeException("不要试图使用反射去破坏我的单例模式");
}
}
}
public static LayzeMan getInstrence(){
if(layze == null){
synchorized(LayzeMan.class){
if(layze == null){
layze = new LayzeMan();
}
}
}
return layze;
}
}
class test{
public static void main(String[] args) throws Exception {
/* LazyPJie lazyPJie = LazyPJie.getInstance();*/
Constructor<LazyPJie> declaredConstructor = LazyPJie.class.getDeclaredConstructor(null);
declaredConstructor.setAccessible(true);
LazyPJie lazyPJie1 = declaredConstructor.newInstance();
LazyPJie lazyPJie = declaredConstructor.newInstance();
System.out.println(lazyPJie);
System.out.println(lazyPJie1);
}
}
package com.itcast.designMode.single;
/**
* author:hlc
* date:2023/9/18
*/
public enum EnumClass {
ENUM_CLASS;
public EnumClass getEnumClass(){
return ENUM_CLASS;
}
}
class Test03{
public static void main(String[] args) {
EnumClass enumClass = EnumClass.ENUM_CLASS;
}
}
package com.itcast.designMode.single;
/**
* author:hlc
* date:2023/9/18
*/
public class Holder {
/**
* 静态内部类实现单例模式
*/
private Holder(){}
public static Holder getInstance(){
return InnerClass.HOLDER;
}
public static class InnerClass{
private static final Holder HOLDER = new Holder();
}
}
实例化对象不使用new,而是使用方法
package com.itcast.designMode.factory;
public interface Car {
void name();
}
package com.itcast.designMode.factory;
/**
* author:hlc
* date:2023/9/18
*/
public class Tesila implements Car{
@Override
public void name() {
System.out.println("特斯拉");
}
}
package com.itcast.designMode.factory;
/**
* author:hlc
* date:2023/9/18
*/
public class WuLing implements Car{
@Override
public void name() {
System.out.println("五菱");
}
}
package com.itcast.designMode.factory;
/**
* author:hlc
* date:2023/9/18
*/
public class CarFactory {
public static Car getCar(String name){
if (name.equals("五菱")){
return new WuLing();
}else if (name.equals("特斯拉")){
return new Tesila();
}else {
return null;
}
}
}
public static void main(String[] args) {
Car car = CarFactory.getCar("五菱");
Car car1 = CarFactory.getCar("特斯拉");
car1.name();
car.name();
}