Spring中的用到的设计模式

1、单例模式
意义:1、减少性能开销,避免对象频繁创建销毁;
      2、避免资源多重占用,如同时对同一个文件做写操作
场景:1、唯一序列号
      2、访问量
      3、创建一个对象需要消耗的资源过多,如要访问IO和数据库等资源
应用:spring中的每个bean(默认是饿汉,容器的初始化的时候就已经将所有的bean都加载进去了,@Lazy注解能设置成懒汉单例模式)
// 饿汉单例模式,对象初始化的时候就已经创建,性能更好
public class Singleton1 {
    private static Singleton1 singleton1 = new Singleton1();

    private Singleton1(){}

    public static Singleton1 getInstance(){
        return singleton1;
    }
}

// 懒汉单例模式,对象第一次调用的时候创建,节省内存(Java中内部类是延迟加载的,不使用不加载)
class Singleton2 {
    private Singleton2(){}

    private static class SingletonFactory {
        private static Singleton2 singleton2 = new Singleton2();
    }

    public static Singleton2 getInstance() {
        return SingletonFactory.singleton2;
    }
}
2、工厂模式
定义:把对象的创建和使用的过程分开。就是Class A 想调用 Class B ,那么A只是调用B的方法,B的实例化交给用工厂类
场景:1、创建复杂,需要一定代码量,需要重复创建  
应用:1、MyBatis中SqlSessionFactory。
      2、spring中的BeanFactory用到了简单工厂
// 抽象产品
interface Desk {
    String getType();
}

// 具体产品
class WoodenDesk implements Desk{
    private String type = "木质桌";
    @Override
    public String getType() {
        return type;
    }
}

// 具体产品
class PlasticDesk implements Desk {
    private String type = "塑料桌";
    @Override
    public String getType() {
        return type;
    }
}

// 抽象产品
interface Chair {
    String getType();
}

// 具体产品
class WoodenChair implements Chair {
    private String type = "木质椅";
    @Override
    public String getType() {
        return type;
    }
}

// 具体产品
class PlasticChair implements Chair {
    private String type = "塑料椅";
    @Override
    public String getType() {
        return type;
    }
}

/**
 * 简单工厂:一个工厂类创建所有产品的对象
 */
public class SimpleFactory {
    public Desk createDesk(String type){
        Desk desk = null;
        if (type.equals("Wooden")) {
            desk = new WoodenDesk();
        } else if (type.equals("Plastic")) {
            desk = new PlasticDesk();
        }
        return desk;
    }
}

/**
 * 工厂方法:在简单工厂的基础上,把工厂类抽象化,每类产品都有一个工厂类
 */
// 工厂方法模式——抽象工厂
interface DeskFactory {
    Desk createDesk();
}

// 工厂方法模式——具体工厂
class WoodenDeskFactory implements DeskFactory {
    @Override
    public Desk createDesk(){
        return new WoodenDesk();
    }
}

// 工厂方法模式——具体工厂
class PlasticDeskFactory implements DeskFactory {
    @Override
    public Desk createDesk() {
        return new PlasticDesk();
    }
}

/**
 * 抽象工厂:相较于工厂方法增加产品族的概念,工厂方法里是一个工厂生产一类产品,抽象工厂
 * 是一个工厂生产一组产品。
 */
// 抽象工厂模式——抽象工厂
interface FurnitureFactory {
    Desk createDesk();
    Chair createChair();
}

// 抽象工厂模式——具体工厂
class WoodenFurnitureFactory implements FurnitureFactory {
    @Override
    public Desk createDesk() {
        return new WoodenDesk();
    }

    @Override
    public Chair createChair() {
        return new WoodenChair();
    }
}

// 抽象工厂模式——具体工厂
class PlasticFurnitureFactory implements FurnitureFactory {
    @Override
    public Desk createDesk() {
        return new PlasticDesk();
    }

    @Override
    public Chair createChair() {
        return new PlasticChair();
    }
}
    public static void main(String[] args) {
        // 简单工厂
        Desk wooden = new SimpleFactory().createDesk("Wooden");
        System.out.println(wooden.getType());
        Desk plastic = new SimpleFactory().createDesk("Plastic");
        System.out.println(plastic.getType());

        // 工厂方法
        Desk desk = new WoodenDeskFactory().createDesk();
        System.out.println(desk.getType());
        Desk desk1 = new PlasticDeskFactory().createDesk();
        System.out.println(desk1.getType());

        // 抽象工厂
        WoodenFurnitureFactory factory = new WoodenFurnitureFactory();
        Chair chair = factory.createChair();
        Desk desk2 = factory.createDesk();
        System.out.println(chair.getType());
        System.out.println(desk2.getType());
    }
3、适配器模式
定义:将原本不兼容的接口融合在一起工作。比如要访问的接口A没有我们想要的方法,接口B中有合适的方法,但是不能改变访问接口(就是固定了通过A调)。
应用:1、spring中的AOP用到了类适配器,Spring提供了AspectJAfterReturningAdvice,AspectJMethodBeforeAdvice,AspectJAroundAdvice,AspectJAfterAdvice这几个advice中,AspectJAfterReturningAdvice和AspectJMethodBeforeAdvice没有实现MethodInterceptor接口,spring提供了AfterReturningAdviceAdapter和MethodBeforeAdviceAdapter实现了MethodInterceptor作为适配器
      2、springmvc中HandlerAdapter
interface Ps2 {
    void isPs2();
}

interface Usb {
    void isUsb();
}

class Usber implements Usb {
    @Override
    public void isUsb() {
        System.out.println("USB口");
    }
}

/**
 * 类适配器:定义一个适配器继承B的实现类BB并实现A,在A的抽象方法实现里调用B的方法
 */
public class Adapter extends Usber implements Ps2 {
    @Override
    public void isPs2() {
        isUsb();
    }
}

/**
 * 对象适配器:定义个一个适配器实现A,在适配器里面通过构造器注入B的对象。在A的抽象方法实现里通过B 
 * 的对象调用B的方法
 */
class Adapter2 implements Ps2 {
    private Usb usb;

    public Adapter2(Usb usb){
        this.usb = usb;
    }

    @Override
    public void isPs2() {
        usb.isUsb();
    }
}

/**
 * 接口适配器模式:当一个接口又很多方法,我们只需要其中一些方法,如果直接实现会导致实现类很臃肿, 
 * 我们定义一个抽象类(适配器)继承A,通过抽象类来实现A中的方法(空实现),
 * 使用的时候创建适配器的子类重写需要用到的方法。
 */
interface A {
    void a();
    void b();
    void c();
}

abstract class Adapter3 implements A {
    public void a(){}
    public void b(){}
    public void c(){}
}

class Ashili extends Adapter3 {
    public void a(){
        System.out.println("实现A方法被调用");
    }
}
    public static void main(String[] args) {
        Ps2 classAdapter = new Adapter();
        classAdapter.isPs2(); // 类适配器
        
        Ps2 objectAdapter = new Adapter2(new Usber());
        objectAdapter.isPs2(); // 对象适配器

        A interfaceAdapter = new Ashili();
        interfaceAdapter.a(); // 接口适配器
    }
4、装饰者模式
定义:在不改变对象结构的情况下动态的向一个现有的对象添加新的功能。相比于继承来说装饰者模式更灵 活。比如增加3种功能和不同功能组合,继承的话得写6个子类,装饰者只需要写3个,用的时候自己去组合
应用:1、spring中的Wrapper和Decorator
     2、jdk的IO包
//抽象组件
interface Component {
    void wearClothes();

    void walkToWhere();
}

//具体组件
class Person implements Component {
    @Override
    public void wearClothes() {
        System.out.println("穿什么呢。。");
    }

    @Override
    public void walkToWhere() {
        System.out.println("去哪里呢。。");
    }
}

//抽象装饰者
public abstract class Decorator implements Component {
    private Component component;

    public Decorator(Component component) {
        this.component = component;
    }

    public void wearClothes() {
        component.wearClothes();
    }

    public void walkToWhere() {
        component.walkToWhere();
    }
}

//具体装饰者
class ConcreteDecoratorZero extends Decorator {
    public ConcreteDecoratorZero(Component component) {
        super(component);
    }

    public void goHome() {
        System.out.println("进房子。。");
    }

    public void findMap() {
        System.out.println("书房找找Map。。");
    }

    @Override
    public void wearClothes() {
        super.wearClothes();
        goHome();
    }

    @Override
    public void walkToWhere() {
        super.walkToWhere();
        findMap();
    }
}

//具体装饰者
class ConcreteDecoratorFirst extends Decorator {
    public ConcreteDecoratorFirst(Component component) {
        super(component);
    }

    public void goClothespress() {
        System.out.println("去衣柜找找看。。");
    }

    public void findPlaceOnMap() {
        System.out.println("在Map上找找。。");
    }

    @Override
    public void wearClothes() {
        super.wearClothes();
        goClothespress();
    }

    @Override
    public void walkToWhere() {
        super.walkToWhere();
        findPlaceOnMap();
    }
}

//具体装饰者
class ConcreteDecoratorTwo extends Decorator {
    public ConcreteDecoratorTwo(Component component) {
        super(component);
    }

    public void findClothes() {
        System.out.println("找到一件D&G。。");
    }

    public void findTheTarget() {
        System.out.println("在Map上找到神秘花园和城堡。。");
    }

    @Override
    public void wearClothes() {
        super.wearClothes();
        findClothes();
    }

    @Override
    public void walkToWhere() {
        super.walkToWhere();
        findTheTarget();
    }
}
    public static void main(String[] args) {
        // 装饰者
        Component person = new Person();
        Decorator decorator = new ConcreteDecoratorTwo(new ConcreteDecoratorFirst(new      
                                     ConcreteDecoratorZero(person)));
        decorator.wearClothes();
        decorator.walkToWhere();
5、代理模式
定义:为对象提供一种代理,以控制对这个对象的访问。分为动态代理、静态代理。
     动态代理有jdk动态代理、cglib,jdk动态代理是生成抽象角色的实现类,cglib是生成真实角色的子类,java1.6以后的版本不论单例多例jdk动态代理性能更高
应用:1、spring中AOP(JdkDynamicAopProxy、CglibAopProxy),spring默认使用jdk动态代理,当bean没有实现接口时用cglib,可以在spring配置里通过<aop:aspectj-autoproxy proxy-target-class="true"/>强制使用cglib
// 抽象角色
interface Star {
    void confer(); //面谈
    void sing(); //唱歌
    void collectMoney(); //收钱
}

// 真实角色
class RealStar implements Star {
    @Override
    public void confer() {
        System.out.println("RealStar.confer()");
    }

    @Override
    public void sing() {
        System.out.println("RealStar(周杰伦).sing()");
    }

    @Override
    public void collectMoney() {
        System.out.println("RealStar.collectMoney()");
    }
}

// 代理角色-静态代理
public class StaticProxy implements Star {
    private Star star;

    public StaticProxy(Star star) { //到时候传进来真实的star
        super();
        this.star = star;
    }

    @Override
    public void confer() {
        System.out.println("ProxyStar.confer()");
    }

    @Override
    public void sing() {
        //其他事都能干,唯一不能干的就是唱歌,唱歌还是得要周杰伦本人来唱
        star.sing(); //让他本人来唱
    }

    @Override
    public void collectMoney() {
        System.out.println("ProxyStar.collectMoney()");
    }
}

/**
 *  代理角色-JDK动态代理
 *  动态代理优点:1、一个代理处理器能代理多个对象,而静态代理每个对象都要创建代理类
 *             2、运行时自动创建代理类和实例化,不运行不创建
 */
class JDKProxyUtils{
    public static Object getProxy(Object target, Supplier s){
        return Proxy.newProxyInstance(
                target.getClass().getClassLoader(),    // 和目标对象一样的类加载器
                target.getClass().getInterfaces(), // 目标对象的接口列表
                (proxy, method, args) -> { // InvocationHandler的匿名内部类lambda表达式写法
                    System.out.println(s.get());
                    //调用目标对象的方法
                    return method.invoke(target, args);
                });
    }
}
    public static void main(String[] args) {
        // 静态代理
        Star real = new RealStar();
        Star proxy = new StaticProxy(real);
        proxy.confer();
        proxy.sing();
        proxy.collectMoney();

        // jdk动态代理
        Star proxy3 = (Star) JDKProxyUtils.getProxy(real, () -> "打印日志");
        proxy3.confer();
        proxy3.sing();
        proxy3.collectMoney();
    }
6、观察者模式
定义:定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个被观察者。这个被观察者状态变化时,会通知所有的观察者对象,使他们能够自动更新自己。
应用:1、spring中的listener
     2、java的util包自带Observable和Observer分别对应Subject和Observer的角色
// 抽象主题
interface Subject {
    void attach(Observer observer);
    void notify(String message);
}

// 具体主题
class ConcreteSubject implements Subject {
    //储存订阅公众号的微信用户
    private List<Observer> weixinUserlist = new ArrayList();

    @Override
    public void attach(Observer observer) {
        weixinUserlist.add(observer);
    }

    @Override
    public void notify(String message) {
        for (Observer observer : weixinUserlist) {
            observer.update(message);
        }
    }
}

// 抽象观察者
public interface Observer {
    void update(String message);
}

// 具体观察者
class WeixinUser implements Observer {
    private String name;
    public WeixinUser(String name) {
        this.name = name;
    }
    @Override
    public void update(String message) {
        System.out.println(name + "-" + message);
    }
}
    public static void main(String[] args) {
        ConcreteSubject mSubscriptionSubject = new ConcreteSubject();
        WeixinUser user1 = new WeixinUser("杨影枫");
        WeixinUser user2 = new WeixinUser("月眉儿");
        WeixinUser user3 = new WeixinUser("紫轩");
        mSubscriptionSubject.attach(user1);
        mSubscriptionSubject.attach(user2);
        mSubscriptionSubject.attach(user3);
        mSubscriptionSubject.notify("刘望舒的专栏更新了");
    }
7、策略模式
定义:定义一系列的算法,把每一个算法封装起来, 并且使它们可相互替换。
应用:spring实例化对象
//策略接口
public interface Strategy {
    double getPrice(double standardPrice);
}

// 具体策略-新客户小批量
class NewCustomerFewStrategy implements Strategy {
    @Override
    public double getPrice(double standardPrice) {
        System.out.println("新客户小批量,不打折");
        return standardPrice;
    }
}

// 具体策略-新客户大批量
class NewCustomerManyStrategy implements Strategy {
    @Override
    public double getPrice(double standardPrice) {
        System.out.println("新客户大批量,打九折");
        return standardPrice * 0.9;
    }
}

// 具体策略-老客户小批量
class OldCustomerFewStrategy implements Strategy {
    @Override
    public double getPrice(double standardPrice) {
        System.out.println("老客户小批量,打八折");
        return standardPrice * 0.8;
    }
}

// 具体策略-老客户大批量
class OldCustomerManyStrategy implements Strategy {
    @Override
    public double getPrice(double standardPrice) {
        System.out.println("老客户大批量,打八折");
        return standardPrice * 0.7;
    }
}
/**
 * 负责和具体的策略交互,具体的算法和直接的客户端分离。
 */
class Context {
    private Strategy strategy;

    public Context(Strategy strategy) {
        super();
        this.strategy = strategy;
    }

    public void getPrice(double standardPrice) {
        System.out.println("报价为:" + strategy.getPrice(standardPrice));
    }
}
    public static void main(String[] args) {
        Strategy s1 = new OldCustomerManyStrategy();
        Context ctx = new Context(s1); //通过构造方法注入策略
        ctx.getPrice(1000);
    }
8、模板方法模式
定义:通过抽象类把不变部分的算法(基本方法)封装到父类实现,可变部分(模板方法)则可以通过子类继承来实现,允许子类通过重写钩子方法来改变基本方法的执行。
public abstract class Template {
    // 模板方法
    protected abstract void start(); //发动

    protected abstract void stop();  //停止

    protected abstract void alarm(); //鸣笛

    protected abstract void engineBoom(); //轰鸣

    // 基本方法
    final public void run() { //车总归要跑
        this.start();
        this.engineBoom();
        if (this.isAlarm()) { //想让它叫就叫,不想就不叫
            this.alarm();
        }
        this.stop();
    }

    // 钩子方法
    protected boolean isAlarm() { //我们加了一个判断方法,默认返回true
        return true;
    }
}

class HummerH1 extends Template {
    @Override
    public void start() {
        System.out.println("H1发动……");
    }

    @Override
    public void stop() {
        System.out.println("H1停止……");
    }

    @Override
    public void alarm() {
        System.out.println("H1鸣笛……");
    }

    @Override
    public void engineBoom() {
        System.out.println("H1轰鸣……");
    }
}

class HummerH2 extends Template {
    private boolean alarmFlag = false; //判断标记

    @Override
    public void start() {
        System.out.println("H2发动……");
    }

    @Override
    public void stop() {
        System.out.println("H2停止……");
    }

    @Override
    public void alarm() {
        System.out.println("H2鸣笛……");
    }

    @Override
    public void engineBoom() {
        System.out.println("H2轰鸣……");
    }

    @Override
    protected boolean isAlarm() { //覆写isAlarm方法,返回判断标记
        return this.alarmFlag;
    }

    public void setAlarm(boolean isAlarm) { //设置判断标记
        this.alarmFlag = isAlarm;
    }
}
    public static void main(String[] args) {
        HummerH1 h1 = new HummerH1();
        h1.run();
        HummerH2 h2 = new HummerH2();
        h2.setAlarm(false);
        h2.run();
    }

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值