设计原则
在此向各位说声抱歉,此文章还在编辑完善中,此文主要展示demo
单一职责原则
一个类中应当只有一个引起它变化的原因,即一个类应当只有一个职责
优点
降低类的复杂性
提高类的可读性
提高代码的可维护性和复用性
降低因变更引起的风险
里氏替换原则
在面向对象的语言中,继承是必不可少的
尽可能的不要覆盖重写父类方法
优点
- 代码共享,减少创建类的工作,每个类都有父类的方法和属性
- 提高代码的可重用性
- 提高代码的可扩展行
- 提高产品或项目的开发性
缺点
- 继承是入侵式的,只要继承,就必须拥有父类的属性和方法
- 降低代码的灵活性,子类必须拥有父类的方法和属性,是子类受限
- 增强了耦合性,当父类属性和方法发生变化是,必须考虑子类的修改,可能发生大片代码的重构
依赖倒置原则
面向接口编程
接口隔离原则
接口尽量的设计为细粒度
迪米特法则
降低耦合,不要在局部变量中引入新的类
开闭原则
对扩展开放,对修改关闭
创建型模式
创建型模式是用来创建对象的模式,抽象了实例化的过程,所有的创建型模式都有两个主要功能
- 将系统使用的具体类的信息封装起来
- 隐藏类的实例是如何被创建和组织
单例模式
/**
* 通过添加readResolve方法,覆盖反序列化出来的对象,防止通过反序列化的方式破坏单例
* 通过反序列化,还是会创建两次,但是因为此方法覆盖上一个创建的对象,实现单例不被破坏,相对安全
* 之前反序列化创建的对象会被GC回收
* @return
*/
private Object readResolve(){
return hungryStaticSingleton;
}
懒汉模式
-
简单懒汉模式
public class LazySimpleSingleton { private LazySimpleSingleton(){} private static LazySimpleSingleton lazySimpleSingleton = null; public synchronized static LazySimpleSingleton getInstance(){ if(lazySimpleSingleton == null){ lazySimpleSingleton = new LazySimpleSingleton(); } return lazySimpleSingleton; } }
-
静态内部类模式
public class LazyInnerClassSingleton { private LazyInnerClassSingleton(){ if(LazyHolder.LAZY != null){ throw new RuntimeException("不允许构建多个实例"); } } public static final LazyInnerClassSingleton getInstance(){ return LazyHolder.LAZY; } private static class LazyHolder{ private static final LazyInnerClassSingleton LAZY = new LazyInnerClassSingleton(); } }
-
双重锁模式
public class LazyDoubleCheckSingleton { private LazyDoubleCheckSingleton(){} private volatile static LazyDoubleCheckSingleton lazyDoubleCheckSingleton; public static LazyDoubleCheckSingleton getInstance(){ if(lazyDoubleCheckSingleton == null){ synchronized (LazyDoubleCheckSingleton.class){ if(lazyDoubleCheckSingleton == null){ lazyDoubleCheckSingleton = new LazyDoubleCheckSingleton(); } } } return lazyDoubleCheckSingleton; } }
饿汉模式
-
饿汉模式
-
/** * 饿汉式单例 */ public class HungrySingleton { private static final HungrySingleton hungrySingleton = new HungrySingleton(); private HungrySingleton(){} public HungrySingleton getInstance() { return hungrySingleton; } }
-
静态代码块
public class HungryStaticSingleton { private HungryStaticSingleton(){} private static final HungryStaticSingleton hungryStaticSingleton; static { hungryStaticSingleton = new HungryStaticSingleton(); } public static HungryStaticSingleton getInstance(){ return hungryStaticSingleton; } }
容器式单例
public class ContainerSingleton {
private ContainerSingleton(){}
private static volatile Map<String, Object> ioc = new HashMap<>();
public static void put(String name, Object obj){
if(!ioc.containsKey(name)){
synchronized (ioc){
if(!ioc.containsKey(name)){
try {
ioc.put(name, obj);
}catch (Exception e){
e.printStackTrace();
}
}
}
}
}
public static Object get(String name){
return ioc.get(name);
}
}
注册式单例
-
枚举单例
枚举从底层屏蔽各种破坏单例的效验
public enum EnumSingleton { INSTANCE; private Object data; public Object getData(){ return data; } public static EnumSingleton getInstance(){ return INSTANCE; } }
threadLocal 伪单例
伪单例,只能在同一个线程内单例,多个线程同时使用时不能保持单例
public class ThreadLocalSingleton {
private ThreadLocalSingleton(){}
private static final ThreadLocal<ThreadLocalSingleton> threadLocal = new ThreadLocal<ThreadLocalSingleton>(){
public ThreadLocalSingleton initialValue(){
return new ThreadLocalSingleton();
}
};
public static ThreadLocalSingleton getInstance() {
return threadLocal.get();
}
}
工厂模式
简单工厂(不属于23中设计模式)
由一个工厂类,一个生产线接口多个生产线实体的实现类组成
在工厂内部根据条件创建指定的生产线实现类,返回生产线接口
通过生产线接口调用执行方法
创建流程
- 创建生产线接口
- 创建生产线实体
- 创建工厂实体,根据条件判断创建生产线实体返回生产线接口
//创建生产线接口
public interface IPhone {
public void start();
public void shutdown();
}
//创建生产线实体
public class HwPhone implements IPhone {
@Override
public void start() {
System.out.println("华为手机开机");
}
@Override
public void shutdown() {
System.out.println("华为手机关机");
}
}
//创建生产线实体
public class XmPhone implements IPhone {
@Override
public void start() {
System.out.println("小米手机开机");
}
@Override
public void shutdown() {
System.out.println("小米手机关机");
}
}
//创建简单工厂
public class Factory {
//name仅代表一个变量,也可以用其他,比如class.getName等
public IPhone create(String name){
if(name == "hw"){
return new HwPhone();
}else if(name == "xm"){
return new XmPhone();
}else{
return null;
}
}
}
//测试
public class Test {
private static Factory factory = new Factory();
public static void main(String[] args) {
IPhone iPhone = factory.create("hw");
iPhone.start();
iPhone.shutdown();
IPhone iPhone1 = factory.create("xm");
iPhone1.start();
iPhone1.shutdown();
}
}

工厂方法
由一个工厂接口,多个实体工厂,一个生产线接口多个生产线实体的实现类组成
创建流程
- 生产线接口
- 创建工厂接口
- 创建生产线实体
- 创建工厂实体,根据不同的工厂实体创建不同的生产线实体,返回生产线接口
//创建生产线接口
public interface IPhone {
public void start();
public void shutdown();
}
//创建工厂接口
public interface IFactory {
public IPhone create();
}
//创建生产线实体
public class HwPhone implements IPhone {
@Override
public void start() {
System.out.println("华为手机开机");
}
@Override
public void shutdown() {
System.out.println("华为手机关机");
}
}
//创建生产线实体
public class XmPhone implements IPhone {
@Override
public void start() {
System.out.println("小米手机开机");
}
@Override
public void shutdown() {
System.out.println("小米手机关机");
}
}
//创建工厂实体
public class HwFactory implements IFactory {
@Override
public IPhone create() {
return new HwPhone();
}
}
//创建工厂实体
public class XmFactory implements IFactory {
@Override
public IPhone create() {
return new XmPhone();
}
}
//测试
public class Test {
private static IFactory hwFactory = new HwFactory();
private static IFactory xmFactory = new XmFactory();
public static void main(String[] args) {
IPhone hw = hwFactory.create();
hw.start();
hw.shutdown();
IPhone xm = xmFactory.create();
xm.start();
xm.shutdown();
}
}

抽象工厂
由一个工厂接口,多个实体工厂,多个生产线接口对应的多个生产线实体的实现类组成
创建流程
- 创建多个生产线接口
- 创建工厂接口
- 创建生产线实体
- 创建多个工厂实体,根据工厂类型创建对应的生产线实体返回对应的生产线接口
//创建生产线接口
public interface IPhone {
public void start();
public void shutdown();
}
//创建生产线接口
public interface IWifi {
public void start();
public void shutdown();
}
//创建工厂接口
public interface IFactory {
public IPhone create();
}
//创建生产线实体
public class HwPhone implements IPhone {
@Override
public void start() {
System.out.println("华为手机开机");
}
@Override
public void shutdown() {
System.out.println("华为手机关机");
}
}
//创建生产线实体
public class HwWifi implements IWifi {
@Override
public void start() {
System.out.println("华为WIFI开机");
}
@Override
public void shutdown() {
System.out.println("华为WIFI关机");
}
}
//创建生产线实体
public class XmPhone implements IPhone {
@Override
public void start() {
System.out.println("小米手机开机");
}
@Override
public void shutdown() {
System.out.println("小米手机关机");
}
}
//创建生产线实体
public class XmWifi implements IWifi {
@Override
public void start() {
System.out.println("小米WIFI开机");
}
@Override
public void shutdown() {
System.out.println("小米WIFI关机");
}
}
//创建工厂实体
public class HwFactory implements IFactory {
@Override
public IPhone createPhone() {
return new HwPhone();
}
@Override
public IWifi createWifi() {
return new HwWifi();
}
}
//创建工厂实体
public class XmFactory implements IFactory {
@Override
public IPhone createPhone() {
return new XmPhone();
}
@Override
public IWifi createWifi() {
return new XmWifi();
}
}
//测试
public class Test {
private static IFactory hwFactory = new HwFactory();
private static IFactory xmFactory = new XmFactory();
public static void main(String[] args) {
IPhone hwPhone = hwFactory.createPhone();
hwPhone.start();
hwPhone.shutdown();
IWifi hwWifi = hwFactory.createWifi();
hwWifi.start();
hwWifi.shutdown();
IPhone xmPhone = xmFactory.createPhone();
xmPhone.start();
xmPhone.shutdown();
IWifi xmWifi = xmFactory.createWifi();
xmWifi.start();
xmWifi.shutdown();
}
}

建造者模式-
原型模式
浅克隆
对象内部使用set对每一个参数赋值(对象传递的是内存地址,所以称之为浅克隆)
public class ShallowPrototype implements Cloneable{
Random random;
public ShallowPrototype() {
}
public Random getRandom() {
return random;
}
public void setRandom(Random random) {
this.random = random;
}
public ShallowPrototype clone() throws CloneNotSupportedException {
return (ShallowPrototype)super.clone();
}
}
深克隆
原型模式就是提供快速构建对象的方法,实现JDK的cloneable接口
需要使用字节码使用
public class DeepPrototype implements Serializable {
Random random;
public DeepPrototype() {
}
public Random getRandom() {
return random;
}
public void setRandom(Random random) {
this.random = random;
}
public DeepPrototype clone(){
DeepPrototype deepPrototype = null;
try {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(this);
byte[] bytes = bos.toByteArray();
ByteArrayInputStream bis = new ByteArrayInputStream(bytes);
ObjectInputStream ois = new ObjectInputStream(bis);
deepPrototype = (DeepPrototype) ois.readObject();
} catch (Exception e) {
e.printStackTrace();
}
return deepPrototype;
}
}
结构型模式
代理模式
静态代理
动态代理
动态代理实现原理(动态代理的对象必须实现接口)
- 拿到被代理的引用,并获取他的所有接口(反射获取)
- JDK Proxy类重新生成一个新的类,实现了被代理类的接口
- 动态生成java代码,将增强逻辑加入的新的代码中(生成新的类,并存在所有的接口)
- 编译成新的java代码的class文件
- 加载并重新运行新的class,得到的类是全新的
目的,都是为了生成新的类,去实现增强代码的逻辑功能
JDK优劣:
- 读取接口的信息
- 必须实现一个接口,目标类相对复杂
- 生成代理逻辑简单,但执行效率相对要低,因为每次都要反射动态调用
CGLib优劣:
- 覆盖父类方法
- 可以代理任何一个普通的类,没有任何要求
- 生成代码逻辑更复杂,效率相对较高,生成一个包含了所有逻辑的FastClass,不再需要反射调用
- 有个坑,不能代理final修饰的方法
- JDK 动态代理实现
// 创建代理类
public class Factory implements InvocationHandler {
private Object target;
public Object getProxyInstance(Object target){
this.target = target;
Class<?> clazz = this.target.getClass();
return Proxy.newProxyInstance(clazz.getClassLoader(), clazz.getInterfaces(), this);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("前置增强。。。。。。");
Object invoke = method.invoke(this.target, args); //返回的是方法执行后的结果集
System.out.println("后置增强。。。。。。");
return invoke;
}
}
//创建接口
public interface IProduct {
void find();
}
//创建实体类,继承接口
public class phone implements IProduct{
public void find(){
System.out.println("方法执行。。。。。。");
}
}
//测试代码
public class Test {
public static void main(String[] args) {
Factory factory = new Factory();
IProduct productProxy = (IProduct)factory.getProxyInstance(new phone());
productProxy.find();
}
}
- cglib 动态代理实现
编写文档时未找到接口
实现 MethodInterceptor
实现intercept方法,根据参数进行设置
优点是代理类不需要实现接口,可以是普通的类,强转成对应的类即可代理
装饰模式
装饰器模式
模拟场景:一杯水,加一份糖加一块钱
//定义接口
public interface Water {
String getMsg();
int getPrice();
}
//定义基础类(一杯水)
public class BaseWater implements Water {
@Override
public String getMsg() {
return "一杯白开水。";
}
@Override
public int getPrice() {
return 5;
}
}
//定义装饰器
public class WaterDecortor implements Water {
private Water water;
public WaterDecortor(Water water) {
this.water = water;
}
@Override
public String getMsg() {
return this.water.getMsg();
}
@Override
public int getPrice() {
return this.water.getPrice();
}
}
//定义加糖
//继承定义的装饰器
public class CandyDecortor extends WaterDecortor{
public CandyDecortor(Water water) {
super(water);
}
@Override
public String getMsg() {
return super.getMsg() + "加一份糖,";
}
@Override
public int getPrice() {
return super.getPrice() + 2;
}
}
//测试
public class Test {
public static void main(String[] args) {
Water water = new BaseWater(); //创建一杯水
System.out.println(water.getMsg() + ":" + water.getPrice());
water = new CandyDecortor(water); //给水加一份糖
System.out.println(water.getMsg() + ":" + water.getPrice());
water = new CandyDecortor(water); //再给水加一份糖
System.out.println(water.getMsg() + ":" + water.getPrice());
}
}

适配器模式
将一个类的接口,转换成客户希望的另一种接口,使原本不兼容的类可以一起工作
Adapter类,通过继承 src类,实现 dst 类接口,完成src->dst的适配。k
//历史创建Vc220V
public class Vc220 {
public int vc(){
return 220;
}
}
//新规范接口DC5V
public interface IDc5 {
public int dc5();
}
//创建适配器,将原规范转换为新规范
public class Adapter extends Vc220 implements IDc5{
private Vc220 vc220;
public Adapter() {}
public void setVc220(Vc220 vc220) {
this.vc220 = vc220;
}
@Override
public int dc5() {
System.out.println("适配器开始执行:" + vc220.vc());
int dc5 = vc220.vc() / 44;
System.out.println("适配器转换结束:" + dc5);
return dc5;
}
}
//测试
public class Test {
public static Adapter adapter = new Adapter();
public static void main(String[] args) {
adapter.setVc220(new Vc220());
adapter.dc5();
}
}

组合模式
桥梁模式
外观模式
享元模式
行为型模式
委派模式(不属于23中设计模式)
基本作用就是负责任务的调度和分配任务,注重结果
- 精简程序逻辑,提高代码可读性
- 消除程序中大量的if…else和switch语句
- 提高算法的保密性和安全性
根据一个调度类,分发请求
//创建员工接口
public interface IEmployee {
public void doing(String command);
}
//创建员工A,B,C......
public class EmployeeA implements IEmployee{
public void doing(String command){
System.out.println("精通 算法 。。。,安排工作:" + command);
}
}
//创建leader,根据不同的命令判断进行任务调度
public class Leader implements IEmployee{
@Override
public void doing(String command) {
if(command.equals("算法")){
new EmployeeA().doing(command);
}else if(command.equals("架构")){
new EmployeeB().doing(command);
}
}
}
//创建老板
public class Boos {
public void command(String command, Leader leader){
leader.doing(command);
}
}
//测试,创建老板实例,发布命令给leader进行执行,leader进行任务调度
public class Test {
public static void main(String[] args) {
new Boos().command("算法", new Leader());
}
}

策略模式
作用
- 避免多重分支语句
应用场景
假如系统有很多类,他们的区别仅在于行为不同
一个系统需要动态的在几种算法中选择一种
优点
- 符合开闭原则
- 避免过多的条件语句
- 提高算法的保密性和安全性
缺点
- 客户端必须知道所有的策略,并自行决定使用哪种策略
- 代码中会产生非常多的策略类,增加维护难度
//创建抽象接口,
public interface IOperation {
int operation(int a, int b);
}
//创建实体类,实现接口方法
public class Add implements IOperation {
@Override
public int operation(int a, int b) {
return a + b;
}
}
//创建实体类,实现接口方法
public class Sub implements IOperation {
@Override
public int operation(int a, int b) {
return a - b;
}
}
//创建策略类
public class Context implements IOperation{
private IOperation iOperation;
public Context() {
}
public void setIOperation(IOperation iOperation) {
this.iOperation = iOperation;
}
@Override
public int operation(int a, int b) {
return iOperation.operation(a, b);
}
}
//根据传入的接口,改变Context执行策略
public class Test {
private static Context context = new Context();
public static void main(String[] args) {
context.setIOperation(new Add());
System.out.println(context.operation(1, 3));
context.setIOperation(new Sub());
System.out.println(context.operation(1, 3));
}
}

命令模式
模板方法模式
- 一次性实现算法不变的部分,可变的部分交给子类来实现
- 各子类公共的部分抽取出来放到父类,避免代码重复
// 构建抽象类
public abstract class AbstractClass {
//定义执行顺序
public void templateMethod(){
this.method1();
//钩子方法,根据值判断是否执行下列方法
if(isCheck()){
this.method2();
}
}
//定义不可重写方法
final void method1(){
System.out.println("方法1执行");
}
//定义抽象方法,必须重写
public abstract void method2();
//定义方法,可重写
public boolean isCheck(){
return false;
}
}
//创建抽象类实现
public class ConcreteAbstract extends AbstractClass {
//可重写方法
@Override
public boolean isCheck() {
return false; //通过改变返回值,决定是否执行重写的钩子方法
}
//必须重写的方法
@Override
public void method2() {
System.out.println("执行方法2");
}
}
//测试
public class Test {
private static ConcreteAbstract concreteAbstract = new ConcreteAbstract();
public static void main(String[] args) {
concreteAbstract.templateMethod();
}
}

责任链模式
//定义执行器抽象类
public abstract class Handler {
//下一个执行器
private Handler nextHandler;
public Handler getNextHandler() {
return nextHandler;
}
public void setNextHandler(Handler nextHandler) {
this.nextHandler = nextHandler;
}
//执行器执行的方法
public abstract int handler(int count);
}
//定义具体执行器
public class ConcreteHandler extends Handler{
@Override
public int handler(int count) {
//业务代码具体操作
System.out.println("执行器0------------------");
//如果下一个执行器存在,则执行
if(null != getNextHandler()){
return getNextHandler().handler(count);
}
return count;
}
}
//测试
public class Test {
public static void main(String[] args) {
Handler handler = new ConcreteHandler();
handler.setNextHandler(new ConcreteHandler1()); //定义的第二个具体执行器,可以一直加
System.out.println(handler.handler(10));
}
}

迭代器模式
中介者模式
观察者模式
又叫发布订阅模式
备忘录模式
访问者模式
状态模式
解释器模式
模式实际应用场景练习
工厂-单例-委派-策略
//创建抽象接口,
public interface IOperation {
int operation(int a, int b);
}
//创建实体类,实现接口方法
public class Add implements IOperation {
@Override
public int operation(int a, int b) {
return a + b;
}
}
//创建实体类,实现接口方法
public class Sub implements IOperation {
@Override
public int operation(int a, int b) {
return a - b;
}
}
//创建策略类
public class Context implements IOperation{
private IOperation iOperation;
public Context() {
}
public void setIOperation(IOperation iOperation) {
this.iOperation = iOperation;
}
@Override
public int operation(int a, int b) {
return iOperation.operation(a, b);
}
}
//创建工厂方法
public class Factory {
//私有化工厂
private Factory() { }
//注册式单例
private static final Map<String, IOperation> MAP = new HashMap<>();
//饿汉-静态代码块初始化
static {
MAP.put(constant.ADD, new Add());
MAP.put(constant.SUB, new Sub());
}
//构建工厂类
//委派模式(注册式单例,通过key进行委派)
//key尽可能使用枚举类型,防止出问题
public static IOperation getIOperation(String key){
if(key.isEmpty()) key = constant.DEFAULT;
return MAP.get(key);
}
//常量
class constant{
static final String ADD = "ADD";
static final String SUB = "SUB";
static final String DEFAULT = ADD;
}
}
//测试
public class Test {
private static Context context = new Context();
public static void main(String[] args) {
String key = Factory.constant.SUB;
context.setIOperation(Factory.getIOperation(key));
System.out.println(context.operation(1, 3));
}
}