设计原则与模式

  1. 软件架构设计原则
    1.1 开闭原则 (open-closed principle, OCP) 开放扩展(抽象), 关闭修改
    1.2 依赖倒置原则 (dependence inversion principle, DIP) 高层模块不应该依赖底层模块,二者都应该依赖其抽象
    1.3 单一职责原则 (simple responsibility principle, SRP) 不要存在多余一个导致类变更的原因。
    1.4 接口隔离原则 (Interface Segregation principle, ISP) 用多个专门的接口,不使用单一的总接口
    1.5 迪米特原则 (Law of demeter LoD) 一个对象应该对其他对象保持最少的了解,又叫最少知道原则(Least Knownledge principle, LKP)
    1.6 里氏替换原则 (liskov substitution principle, LSP)是指 如果对每一个类型为T1的对象o1,都有类型为T2的对象o2,使得以T1定义的所有程序P再所有的对象o1都替换成o2时,程序p的行为没有发生变化,那么类型T2是类型T1的子类型
    1.7 合成复用原则 (composite/aggregate reuse principle, CARP) 尽量使用对象组合(has-a)/聚合(containis-a)而不是继承关系达到软件复用的目的。

  2. 设计模式 在 spring 中的使用
    在这里插入图片描述
    在这里插入图片描述

工厂方法模式(Fatory Method Pattern)

工厂方法模式是指定义一个创建对象的接口,但让实现这个接口的类来决定实例化哪个类,工厂方法模式让类的实例化推迟到了子类中进行。在工厂方法模式中用户只需要关心所需产品对应的工厂,无须关心创建的细节,而且加入新的产品时符合开闭原则。

工厂方法模式将 工厂类的职能负重降低,但是带来了 子工厂类 增加的。

抽象工厂模式 (Abastract Factory Pattern)

抽象工厂模式是指提供一个创建一系列相关或相互依赖对象的接口,无须指定他们的具体类。客户端(应用层)不依赖于产品类实例如何被创建、如何被实现等细节,强调的是一系列相关的产品对象(属于同一产品族)一起使用创建对象需要大量重复的代码。需要提供一个产品类的库,所有的产品以同样的接口出现,从而使客户端不依赖于具体实现。

在这里插入图片描述

当 java 对象序列化后,进行反序列化,防止创建新对象的解决方案:

在这里插入图片描述
在这里插入图片描述
ObjectInputStream.readObject() -> readOjbect0->readOrdinaryObject -> desc.hasReadResolveMethod
全局查找发现 ObjectStreamClass()
readResolveMethod = getInheritableMethod(cl, “readResolve”, null, Object.class);
-> invokeReadResolve

通过 JDK 代码可以发现 对象被创建 只是 没有返回, 还是用的 之前创建的对象。
但是当这个操作变得频繁,内存开销依旧很大。

单例模式
好处: 尽量保证内存只有一个实例,减少内存的开销,还可以避免对资源的多重占用。
饿汉 懒汉 序列化 注册 线程(ThreadLocal)

注册式单例模式

枚举类 不知道 反射构建; 序列化 通过 类名 + 类对象 查找唯一枚举对象,不存在 被类加载器加载多次。

原型模式 (Prototype Pattern)

原型模式是指原型实例指定创建对象的种类,并且通过复制这些原型创建新的对象。
在这里插入图片描述

代理模式 (Proxy Pattern)

在这里插入图片描述
静态代理

动态代理
java.lang.reflect.Proxy;
Class<?> clazz = target.getClass();
Proxy.newProxyInstance(clazz.getClassLoader(), clazz.getInterfaces(), this);

手写jdk动态代理

字节码重组
字节码重组

JDK 字节码重组过程:
  1. 获取被代理对象的引用,并且获取它的所有接口,反射获取
public Object getInstance(Object person) throws Exception{
   
	this.target = person; // 被代理对象的引用
	Class<?> clazz = target.getClass();
	return GPProxy.newProxyInstance(new GPClassLoader(),clazz.getInterfaces()/* 反射获取所有的接口	(interface) */,this);
}
  1. 生成并写入一个新的java 类文文件
    生成 implements interface名 + 新增 组合GPInvocationHandler h; 并在构造中 对齐进行赋值。 一个 新的对象文件。
    将interface对象 getMethods() 读取出来 参数名,参数类, 参数值
    生成 method 并使用 class.getMethod 获取方法,并通过GPInvocationHandler 的 invoke 调用此方法。
	sb.append("public class $Proxy0 implements " + interfaces[0].getName() + "{" + ln);
	sb.append("GPInvocationHandler h;" + ln);
	sb.append("public $Proxy0(GPInvocationHandler h) { " + ln);
	sb.append("this.h = h;");
	sb.append("}" + ln);
                
	sb.append("public " +
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值