设计模式的六大原则
1、开闭原则(Open Close Principle)
对扩展开放,对修改关闭。
2、里氏代换原则(Liskov Substitution Principle)
任何基类可以出现的地方,子类一定可以出现。
3、依赖倒转原则(Dependence Inversion Principle)
对接口编程,依赖于抽象而不依赖于具体。
4、接口隔离原则(Interface Segregation Principle)
使用多个隔离的接口,比使用单个接口要好。降低依赖,降低耦合。
5、迪米特法则(最少知道原则)(Demeter Principle)
一个实体应当尽量少的与其他实体之间发生相互作用,使得系统功能模块相对独立。
6、合成复用原则(Composite Reuse Principle)
尽量使用合成/聚合的方式,而不是使用继承。
Java的23中设计模式
分类 |
设计模式 |
创建型 5
扫描二维码关注公众号,回复:
7750353 查看本文章
|
工厂方法模式(FactoryMethod)、抽象工厂模式(AbstractFactory)、建造者模式(Builder)、原型模式(Prototype)、单例模式(Singleton) |
结构型 7 |
适配器模式(Adapter)、桥接模式(Bridge)、组合模式(Composite)、装饰器模式(Decorator)、门面模式(Facade)、享元模式(Flyweight)、代理模式(Proxy) |
行为型 11 |
解释器模式(Interpreter)、模板方法模式(TemplateMethod)、责任链模式(ChainofResponsibility)、命令模式(Command)、迭代器模式(Iterator)、调解者模式(Mediator)、备忘录模式(Memento)、观察者模式(Observer)、状态模式(State)、策略模式(Strategy)、访问者模式(Visitor) |
------ 创建型 -----
单例模式(Singleton):
定义:
在一个JVM中,保证类只有一个实例。
应用场景:
Windows 任务管理器,回收站, Spring IoC默认创建的对象。
优缺点:
优点:节约内存,重复利用,方便管理。
缺点:线程安全性问题。
创建方式:
1. 饿汉式: 类初始化时,会立即加载该对象,线程天生安全,调用效率高。
2. 懒汉式: 类初始化时,不会初始化该对象,真正需要使用的时候才会创建该对象,具备懒加载功能。
3. 静态内部类: 结合了懒汉式和饿汉式各自的优点,真正需要对象的时候才会加载,加载类是线程安全的。
4. 双重检测锁:增加volatile关键字,解决重排序问题。
5. 枚举单例: 使用枚举实现单例模式 优点:实现简单、调用效率高,枚举本身就是单例,由jvm从根本上提供保障!避免通过反射和反序列化的漏洞, 缺点没有延迟加载。
public class EnumSingleton { private EnumSingleton(){} public static EnumSingleton getInstance(){ return Singleton.INSTANCE.getInstance(); } private enum Singleton{ INSTANCE; private EnumSingleton singleton; //JVM会保证此方法绝对只调用一次 Singleton(){ singleton = new EnumSingleton(); } public EnumSingleton getInstance(){ return singleton; } } }
如何选择单例模式:
不需要延迟加载:枚举或饿汉式,枚举更好。
需要延迟加载:静态内部类或懒汉式,静态内部类更好。
工厂模式(Factory):
工厂模式分简单工厂(不属于23种之一),工厂方法,抽象工厂。
简单工厂 : 用来生产同一等级结构中的任意产品。(不支持拓展增加产品)
工厂方法 :用来生产同一等级结构中的固定产品。(支持拓展增加产品)
抽象工厂 :用来生产不同产品族的全部产品。(不支持拓展增加产品;支持增加产品族)
简单工厂优缺点:
优点:能够根据外界给定的信息,决定究竟应该创建哪个具体类的对象。
缺点:一个工厂集合所有实例的创建,违法高内聚,责任分配,不易扩展,要改代码。
工厂方法(FactoryMethod):
核心工厂抽象出来,只负责具体工厂的接口,不负责具体创建,而将具体创建交个子类工厂去做。
抽象工厂(AbstractFactory):
用于生产不同产品族,比如Intel产品族和AMD产品族。
抽象工厂模式与工厂方法模式的最大区别就在于,工厂方法模式针对的是一个产品等级结构;而抽象工厂模式则需要面对多个产品等级结构。
建造者模式(Builder):
将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
工厂模式创建单个类,建造者创建复合对象类。复合对象指类具有不同属性。
应用场景:
肯德基买套餐。汉堡,可乐不变。其他薯条,炸鸡翅组合经常变化,生成不同的套餐。
原型模式(Prototype):
原型表面该模式有一个样板实例,从这个样板对象中复制一个内部属性一致的对象,叫克隆,被复制的实例就是“原型”。
原型模式多用于复制创建复杂的或者构造耗时的实例,因为这种情况下,复制一个已经存在的实例可使程序运行更高效。
应用场景:
Spring IoC里的创建的多例就是原型。
------ 结构型 ------
代理模式(Proxy):
通过代理控制对象的访问,可以详细访问某个对象的方法,在这个方法调用前处理,或调用后处理。分静态代理和动态代理。
静态代理:需要生产代理类。需要代理的接口多了,就会生成很多静态代理类。
动态代理:JDK动态代理,CGlib代理(操作字节码)
应用场景:
租房中介,Spring AOP, 事务原理,日志打印,权限控制,远程调用等等。
JDK动态代理,目标业务类必须实现接口。
具体是实现InvocationHandler接口的调用处理对象。
CGLIB动态代理,不需要委托类实现接口。操作字节码生成子类。
CGLIB动态代理与JDK动态区别
java动态代理是利用反射机制生成一个实现代理接口的匿名类,在调用具体方法前调用InvokeHandler来处理。
而cglib动态代理是利用asm开源包,对代理对象类的class文件加载进来,通过修改其字节码生成子类来处理。
适配器模式(Adapter):
将一个类的接口转换成希望的另一个接口。适配器模式让那些接口不兼容的类可以一起工作。别名包装器(Wrapper)。
适配器模式有两种:类适配器、对象适配器
类适配器使用对象继承的方式,是静态的定义方式;而对象适配器使用对象组合的方式,是动态组合的方式。
1. 类适配器模式:通过继承来实现适配器功能。
应用场景:
SpringMVC
外观模式(Facade):
又叫门面模式,隐藏系统的复杂性,并向客户端提供了一个客户端可以访问系统的接口。
应用场景:
用户注册完之后,需要调用短信接口,微信接口,邮件接口。只提供一个接口发消息接口,隐藏内部复杂实现。
------ 行为型 ------
模板方法模式(TemplateMethod):
定义一个操作中的算法骨架,而将一些步骤延迟到子类实现。重复代码全部在父类里面,不同业务的,抽取给子类进行实现。处理步骤在父类中定义好,具体的实现延迟到子类中定义。
应用场景:银行办业务。银行给我们提供了一个模板就是:先取号,排对,办理业务(核心部分我们子类完成),给客服人员评分,完毕。
Servlet的doGet/doPost方法,Hibernate的模板程序,Spring中JDBCTemplate, RestTemplate等。
策略模式(Stragey):
针对一组算法或逻辑,将每一个算法或逻辑封装到具有共同接口的独立的类中,从而使得它们之间可以相互替换。策略模式使得算法或逻辑可以在不影响到客户端的情况下发生变化。OCP开闭原则。
应用场景:
不同等级会员打折力度不同,分为三种策略,初级会员,中级会员,高级会员。
观察者模式(Observer):
主要用于1对N的通知。当一个对象的状态变化时,他需要及时告知一系列对象,令他们做出相应。
两种实现方式:
推:把通知以广播的方式发送给所有观察者,所有的观察者只能被动接收。
拉:观察者只要知道有情况即可,至于什么时候获取内容,获取什么内容,都可以自主决定。
应用场景:
跨系统消息交换场景,消息队列,事件监听处理。