面向对象的七大原则(OOP)
1,开闭原则:
对扩展开发,对修改关闭
2.里氏替换原则:
继承必须确保超类所拥有的子类的性质在子类中仍然成立
3.依赖倒置原则:
面向接口编程,不要面向实现编程,降低程序之间的耦合性
4.单一职责原则:
控制类的粒度大小,将对象解耦,提高其内聚性
5.接口隔离原则:
要为各个类创建他们专用的接口
6.迪米特法则:
只于你的直接朋友交谈,不跟陌生人交谈
7.合成复用法则:
尽量先使用组合或者聚合等关联来实现,其次才考虑使用集成关系来实现
单例模式
饿汉模式
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.InvocationTargetExceptionat 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{@Overridepublic void name() {System.out.println("特斯拉");}
}package com.itcast.designMode.factory;/*** author:hlc* date:2023/9/18*/
public class WuLing implements Car{@Overridepublic 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();}