打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
Java设计模式很难吗,这篇带你熟悉设计模式

3.1 概述

可以发现,设计模式好像都是类似的。越看越感觉都着不多。其实都是类似面向接口编程的一种体现,只不过侧重点不一样或者说要体现的结果不一样。

3.2 使用场景

问题一:应对可能变化的对象实现

方案:间接创建

模式:工厂模式

问题二:为请求指定相应的操作(类似请假审批,不同时长对应不同职位的审批人)

方案:程序根据请求动态选择操作

模式:责任链模式

3.3 具体说明

3.3.1 策略模式

  • 策略模式说明

一个行为型模式,包含多个行为或职责的业务,通过策略模式简化

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中直接在使用时就通过注解给设置了

3.3.2、装饰器模式

描述:原接口Shape不变,方法数量不变,在方法实现中增加修饰

场景:

场景一:一个类功能简单,满足不了我们的需求

场景二:给原方法增加日志功能,不改变原方法,新的实现类去实现此功能,带入的对象为接口对象

特点

  • 原接口Shape不动,增加新的装饰类ShapeDecorator
  • 原方法名不变,只是增加或修饰此方法体
  • ColorShapeDecorator装饰类持有原对象,只是增加了修饰
public class ColorShapeDecorator extends ShapeDecorator { public ColorShapeDecorator(Shape shape) { super(shape); } @Override public void draw() { setColor(); shape.draw(); } private void setColor() { //设置画图颜色 }}

3.3.3 代理模式

设置一个中间代理来控制访问原目标对象,达到增强原对象的功能和简化访问方式的目的

场景:

场景一:不改变原方法,对原方法增加耗时的计算

场景二: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

3.3.4 适配器模式

描述:原接口不变,增加方法数量

场景:

场景一:原接口不变,在基础上增加新的方法。

场景二:接口的抽象方法很多,不想一一实现,使用适配器模式继承原实现类,再实现此接口

  • 适配器模式适合需要增加一个新接口的需求,在原接口与实现类基础上需要增加新的接口及方法。类似原接口只能method01方法,需求是增加method02方法,同时不再使用之前接口类。

新接口

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(); }}

3.3.5 单例模式

保证被创建一次,节省系统开销。

1)单例实现方式

  • 饿汉式
  • 懒汉式
  • 懒汉式+synchronized
  • 双重校验
  • 静态内部类
  • 枚举(推荐方式)

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(){ //具体需要实现的功能 }}
  • 懒汉式+Synchronized
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();

3.3.6 工厂模式

(简单工厂、抽象工厂):解耦代码。

简单工厂:用来生产同一等级结构中的任意产品,对于增加新的产品,无能为力。

工厂方法:用来生产同一等级结构中的固定产品,支持增加任意产品。

抽象工厂:用来生产不同产品族的全部产品,对于增加新的产品,无能为力;支持增加产品族。

参考文章:
https://zhuanlan.zhihu.com/p/248497545

3.3.7 观察者模式

定义了对象之间的一对多的依赖,这样一来,当一个对象改变时,它的所有的依赖者都会收到通知并自动更新。

3.3.8 外观模式

提供一个统一的接口,用来访问子系统中的一群接口,外观定义了一个高层的接口,让子系统更容易使用。

3.3.9 状态模式

允许对象在内部状态改变时改变它的行为,对象看起来好像修改了它的类。与策略模式类似,策略模式侧重点在一个事的不同实现方式抽离出来,而状态模式是一个事的不同状态抽离出来(开始、进行中、结束),每次状态完成自己的业务逻辑。

3.4 总结:

  • 适配器模式(原功能不变,增加新功能)、装饰器模式(装饰原功能)、代理模式(控制原功能)
  • 策略模式侧重点在一个事的不同实现方式抽离出来,而状态模式是一个事的不同状态抽离出来(开始、进行中、结束),每次状态完成自己的业务逻辑。
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
设计模式笔记(一):Singleton 设计模式
C++ 线程安全的单例模式
单例模式
创建型模式之单例模式
【单例模式】
java 双重检查模式
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服