可以发现,设计模式好像都是类似的。越看越感觉都着不多。其实都是类似面向接口编程的一种体现,只不过侧重点不一样或者说要体现的结果不一样。
问题一:应对可能变化的对象实现
方案:间接创建
模式:工厂模式

问题二:为请求指定相应的操作(类似请假审批,不同时长对应不同职位的审批人)
方案:程序根据请求动态选择操作
模式:责任链模式

一个行为型模式,包含多个行为或职责的业务,通过策略模式简化
- public class StrategyContext {
- Strategy strategy;
- public StrategyContext(Strategy strategy) {
- this.strategy = strategy;
- }
- /**
- *
- */
- public int context(int a, int b) {
- return strategy.operator(a,b);
- }
- }
策略模式的核心为StrategyContext上下文类,持有strategy对象,在context完成操作。
如何使用策略模式解决大量使用if else 或大量switch问题,策略模式+反射。
策略模式后好像使用都还是要用if else来决定调用哪个类,所以在引入策略模式后,在上下文类还要增加反射。
- public class StrategyContext {
- Strategy strategy;
- public StrategyContext(String type) throws Exception {
- Class clazz = Class.forName(type);
- this.strategy = (Strategy) clazz.newInstance();
- }
- /**
- *
- */
- public int context(int a, int b) {
- return strategy.operator(a,b);
- }
当然这里的type可以用个枚举来解决。感觉代价非常大是不是没必要,不过代码的可读性还是增强了。
p.s. 在框架里策略模式中的Context一般不会直接出现,类似spring中直接在使用时就通过注解给设置了
描述:原接口Shape不变,方法数量不变,在方法实现中增加修饰
场景:
场景一:一个类功能简单,满足不了我们的需求
场景二:给原方法增加日志功能,不改变原方法,新的实现类去实现此功能,带入的对象为接口对象

特点
- public class ColorShapeDecorator extends ShapeDecorator {
- public ColorShapeDecorator(Shape shape) {
- super(shape);
- }
- @Override
- public void draw() {
- setColor();
- shape.draw();
- }
- private void setColor() {
- //设置画图颜色
- }
- }
设置一个中间代理来控制访问原目标对象,达到增强原对象的功能和简化访问方式的目的
场景:
场景一:不改变原方法,对原方法增加耗时的计算
场景二:rpc远程调用,client端进行动态代理类似耗时计算一样,用户不用关心client的具体实现
分类
说明

- /**
- * 与适配器模式的区别,适配器模式主要改变所考虑对象的接口,
- * 而代理模式不能改变所代理类的接口。与装饰器模式的区别,
- * 装饰器模式是为了增强功能,代理模式是为了加以控制
- */
- public class ProxySigntureService implements SigntureService {
- private SigntureService signatureService;
- /**
- * Default constructor
- */
- public ProxySigntureService(SigntureService signatureService) {
- this.signatureService = signatureService;
- }
- public void sign() {
- //控制对这个对象的访问
- // 实现电子签名
- }
- }
- public class DynamicProxySignatureService implements InvocationHandler {
- private Object obj;
- public DynamicProxySignatureService(Object obj) {
- this.obj = obj;
- }
- @Override
- public Object invoke(Object proxyObj, Method method, Object[] objects)
- throws Throwable {
- return method.invoke(obj,objects);
- }
- }
参考文章:https://blog.csdn.net/liujiahan629629/article/details/19428485
描述:原接口不变,增加方法数量
场景:
场景一:原接口不变,在基础上增加新的方法。
场景二:接口的抽象方法很多,不想一一实现,使用适配器模式继承原实现类,再实现此接口

新接口
- public interface Targetable {
- /**
- *
- */
- public void method01();
- /**
- *
- */
- public void method02();
- }
原接口实现类
- public class Source {
- public void method01() {
- // TODO implement here
- }
- }
适配器类,用于实现新接口。继承原实现类,同时实现新接口。
- public class Adapter extends Source implements Targetable {
- /**
- *
- */
- public void method02() {
- // TODO implement here
- }
- }
测试类
- public class AdapterTest {
- public static void main(String[] args) {
- Targetable targetable = new Adapter();
- targetable.method01();
- targetable.method02();
- }
- }
保证被创建一次,节省系统开销。
1)单例实现方式
2)实现代码
- package com.hanko.designpattern.singleton;
- /**
- * 饿汉式 (饿怕了,担心没有吃,所以在使用之前就new出来)
- *优点:实现简单,安全可靠
- *缺点:在不需要时,就已实例化了
- * @author hanko
- * @version 1.0
- * @date 2020/9/14 18:50
- */
- public class HungrySingleton {
- //特点一 静态私有变量 直接初始化
- private static HungrySingleton instance = new HungrySingleton();
- //特点二 构造函数私有
- private HungrySingleton(){
- }
- public static HungrySingleton getInstance(){
- return instance;
- }
- public void doSomething(){
- //具体需要实现的功能
- }
- }
- package com.hanko.designpattern.singleton;
- /**
- * 懒汉式(非常懒,所以在要使用时再去new)
- *优点:简单
- *缺点:存在线程安全问题
- * @author hanko
- * @version 1.0
- * @date 2020/9/14 18:50
- */
- public class SluggardSingleton {
- //特点一 静态私有变量,先不初始化
- private static SluggardSingleton instance;
- //特点二 构造函数私有
- private SluggardSingleton(){
- }
- //特点三 null判断,没有实例化就new
- public static SluggardSingleton getInstance(){
- if(instance == null){
- instance = new SluggardSingleton();
- }
- return instance;
- }
- public void doSomething(){
- //具体需要实现的功能
- }
- }
- package com.hanko.designpattern.singleton;
- /**
- * 懒汉式(非常懒,所以在要使用时再去new)
- *优点:简单
- *缺点:存在线程安全问题
- * @author hanko
- * @version 1.0
- * @date 2020/9/14 18:50
- */
- public class SluggardSingleton {
- //特点一 静态私有变量,先不初始化
- private static SluggardSingleton instance;
- //特点二 构造函数私有
- private SluggardSingleton(){
- }
- //特点三 null判断,没有实例化就new
- public static synchronized SluggardSingleton getInstance(){
- if(instance == null){
- instance = new SluggardSingleton();
- }
- return instance;
- }
- public void doSomething(){
- //具体需要实现的功能
- }
- }
- package com.hanko.designpattern.singleton;
- /**
- * 双重校验
- *对懒汉式单例模式做了线程安全处理增加锁机制
- * volatile变量级
- * synchronized 类级
- * @author hanko
- * @version 1.0
- * @date 2020/9/15 9:53
- */
- public class DoubleCheckSingleton {
- //特点一 静态私有变量,增加volatile变量级锁
- private static volatile DoubleCheckSingleton instance;
- //特点二 构造函数私有
- private DoubleCheckSingleton(){
- }
- //特点三 双重null判断 synchronized类级锁
- public static DoubleCheckSingleton getInstance(){
- if (instance == null){
- synchronized(DoubleCheckSingleton.class){
- if (instance == null){
- instance = new DoubleCheckSingleton();
- }
- }
- }
- return instance;
- }
- }
- package com.hanko.designpattern.singleton;
- /**
- * 内部静态类方式
- *优点:静态内部类不会在InnerStaticSingleton类加载时加载,
- * 而在调用getInstance()方法时才加载
- *缺点:存在反射攻击或者反序列化攻击
- * @author hanko
- * @version 1.0
- * @date 2020/9/15 10:03
- */
- public class InnerStaticSingleton {
- //特点一:构造函数私有
- private InnerStaticSingleton(){
- }
- //特点二:静态内部类
- private static class InnerSingleton{
- private static InnerSingleton instance = new InnerSingleton();
- }
- public InnerSingleton getInstance(){
- return InnerSingleton.instance;
- }
- public void doSomething(){
- //do Something
- }
- }
- package com.hanko.designpattern.singleton;
- /**
- * 枚举实现单例简单安全
- *
- * @author hanko
- * @version 1.0
- * @date 2020/9/14 19:01
- */
- public enum EnumSingleton {
- INS;
- private Singleton singleton;
- EnumSingleton() {
- singleton = new Singleton();
- }
- public void doSomething(){
- singleton...
- //具体需要实现的功能
- }
- }
- EnumSingleton.INS.doSomething();
(简单工厂、抽象工厂):解耦代码。
简单工厂:用来生产同一等级结构中的任意产品,对于增加新的产品,无能为力。
工厂方法:用来生产同一等级结构中的固定产品,支持增加任意产品。
抽象工厂:用来生产不同产品族的全部产品,对于增加新的产品,无能为力;支持增加产品族。
参考文章:几种常用的设计模式--工厂模式 - 知乎
定义了对象之间的一对多的依赖,这样一来,当一个对象改变时,它的所有的依赖者都会收到通知并自动更新。
提供一个统一的接口,用来访问子系统中的一群接口,外观定义了一个高层的接口,让子系统更容易使用。
允许对象在内部状态改变时改变它的行为,对象看起来好像修改了它的类。与策略模式类似,策略模式侧重点在一个事的不同实现方式抽离出来,而状态模式是一个事的不同状态抽离出来(开始、进行中、结束),每次状态完成自己的业务逻辑。