OPP七大原则
- 对扩展开放,对修改关闭
- 继承必须确保父类所拥有的性质在子类中仍然成立
- 面向接口编程
- 控制粒度大小,高内聚,低耦合
- 为各个类建立它们需要的专用接口
- 只与“直接朋友”交谈,不和“陌生人”说话(看情况,过多使用中间类会有大量冗余)
- 尽量使用组合或聚合等关联来实现,其次考虑继承实现
创建型模式
(怎么去创建对象,让对象的创建与使用分离)
1.1 单例模式(全局唯一)
public class Demo1{ //JVM保证安全,只加载一次
private Demo1(){
}
private static class DemoHolder {
private final static Demo1 INSTANCE = new Demo1()
}
public static Demo1 getInstance(){
return DemoHolder. INSTANCE
}
}
public enum Demo2{ //不仅解决线程安全,还可以防止反序列化
INSTANCE;
public void m(){}
}
1.2 工厂模式
本质:
- 实例化对象不用new,用工厂方法替代
- 将选择实现类,创建对象统一管理和控制,从而将调用者和实现类解耦
三种模式:
-
1.2.1 简单工厂模式(关注产品)
- 实现:通过if,switch实现
- 生产同一等级结构中任意产品
- 缺点:增加新的产品时需要修改代码
-
1.2.2工厂方法模式(关注产品)
- 实现:每一个产品都需要一个单独的工厂来实现
- 生产同一等级结构中的固定产品(支持增加任意产品)
- 缺点:代码过多
-
1.2.3抽象工厂模式(关注产品族)
- 围绕一个超级工厂创建其他工厂,超级工厂又称为其他工厂的工厂
- 优点:1. 无需关心创建细节;2. 将一系列产品统一到一起创建
- 缺点:产品稳定情况下非常强大,但在产品不稳定的情况下,需要修改大量代码。
- 围绕一个超级工厂创建其他工厂,超级工厂又称为其他工厂的工厂
1.3 建造者模式(创建复杂对象的最佳方式)
将构建和表示分离,实现解耦
1.4 原型模式(通常与工厂模式相结合)
-
就是实现Cloneable的clone方法
-
实现clone方法的类存在引用对象是,单纯的clone是浅克隆,需要对引用对象再克隆才能深克隆(序列化、反序列化需要操作IO,效率降低)
@Override protected Object clone() ththrows CloneNotSupportedException{ Object obj = supper.clone(); Video v = (Lei)obj; v.creaateTime = (Date)this.createTime.clone();//将这个对象的属性也进行克隆 return obj; }
结构型模式
(将类或者对象以某种布局组成更大的结构)
2.1 适配器模式
尽量使用对象适配器,而不是类适配器
2.2 桥接模式
将抽象部分与实现部分分离,使它们可以独立的变化
- 好处:
- 类似多继承方案但更好,极大的减少了子类的个数,降低管理好维护成本
- 提高了系统的可扩充性,在两个变化维度中任意扩展一个维度。符合开闭原则
- 缺点:
- 增加系统的理解与设计难度
- 该模式要求正确识别系统中两个独立变化的维度,使用范围有一定局限性。
2.3 代理模式(SpringAOP的底层)
-
2.3.1 静态代理
-
角色分析:
- 抽象角色:一般会使用接口或者抽象类来解决
- 真实角色:被代理的角色
- 代理角色:代理真实角色, 代理真实角色后,做一些附属操作
- 客户:访问代理对象的人
-
代码步骤:
-
接口
public interface Rent{ public void rent(); }
-
真实角色
public class Host implements Rent{ public void rent(){ sout("出租房子") } }
-
代理角色
public class ProxyRent implements Rent{ private Host host; public ProxyRent(){} public ProxyRent(Host host){ SeeHouse(); Host.rent(); hetong(); fare(); } public void SeeHouse(){sout("看房")} public void hetong(){sout("签合同")} public void fare(){sout("收中介费")} }
-
客户端访问代理角色
public class Client{ public static void main(String[] args){ Host host = new Host(); ProxyRent proxyrent = new ProxyRent(); proxyrent.rent(); } }
-
-
好处:
- 真实角色更加纯粹,不用关注公共的业务
- 公共业务交给代理角色,实现了业务分工
- 公共业务发生扩展,方便集中管理
-
缺点:
- 一个真实角色就会产生一个代理角色,开发效率变低
-
-
2.3.2动态代理
- 动态代理和静态代理角色一样
- 动态代理的代理类是动态生成的,不是我门直接写好的!
- 动态代理分为两大类:基于接口的动态代理,基于类的动态代理
- 基于接口:JDK动态代理
- 基于类:cglib
- 基于java字节码:javasist
- 需要了解的两个类:Proxy(生成动态代理角色),InvocationHandler(调用处理程序,并返回结果)
- 好处:
- 静态代理好处
- 一个动态代理类代理的是一个接口,一般就是对应的一类业务
2.4 装饰模式
不改变现有对象结构的情况下,动态地给该对象增加一些职责(即增加其额外功能)的模式(IO流常用)
2.5 组合模式
树状结构专用模式
2.6 外观模式
为多个复杂的子系统提供一个一致的接口,而使这些子系统更加容易被访问的模式。
优点:“迪米特法则”的典型应用
缺点:该模式下进行扩展或移除违反“开闭原则”
2.7 享元模式
重复利用对象
行为型模式
(让类或者对象之间怎么相互协作,完成单个对象无法完成的任务)
3.1 Strategy 策略模式
定义一系列的算法,把它们一个个封装起来, 并且使它们可相互替换。