23种设计模式(持续更新中)

前言
由于博主是边学边更新,所以难免会有瑕疵甚至错误,发现可私信于我,第一时间内修改
预计更新完之后总体上会再次整理一遍
ps:本文更倾向于初学过设计模式,而又没完全记住,相当于用来复习的笔记

创建型模式

单例模式

饿汉式

饿汉式:类加载的时候就创建出实例

/*
弊端:
即使此单例不需要使用,它也会在类加载后创建出来。占用内存,并增加类的初始化时间
 */

public class Hungry {
    // 类的初始化的时候就创建对象
    private static Hungry instance = new Hungry();
    
    // 无参构造设为private,防止其他类通过构造方法实例化
    private Hungry(){
    }
    
    // 通过该静态方法才可获取实例
    public static Hungry getInstance(){
        return instance;
    }
}

懒汉式

懒汉式:先声明一个空变量,需要使用的时候才创建实例

双检锁方式实现懒汉式单例

public class Lazy {

    // 防止重排序使用volatile关键字
    // 重排序会在特殊情况下导致线程不安全
    private static volatile Lazy instance = null;

    // 保证其他类无法通过构造方法创建实例
    private Lazy(){

    }

    public static Lazy getInstance(){
        // 不加这个判空,则每次都要加锁,影响性能
        if(instance == null){
      		// 加锁保证线程安全
            synchronized (Lazy.class){
                // 这里不加判空同样可能存在多次创建实例的情况
                if (instance == null){
                    instance = new Lazy();
                }
            }
        }
        return instance;
    }

}

静态内部类实现懒汉式单例

内部类是在使用时才会加载,所以可以实现懒加载

虚拟机底层是保证了类加载的时候是线程安全的,所以在懒加载创建实例的时候一定是线程安全的

public class StaticLazy {

    // 静态内部类
    private static class StaticLazyHolder {
        public static StaticLazy instance = new StaticLazy();
    }

    // 私有化构造方法
    private StaticLazy(){

    }

    public static StaticLazy getInstance(){
        return StaticLazyHolder.instance;
    }

}

总结

对于构建不复杂,加载完成后会立即使用的单例对象,推荐使用饿汉式

对于构建过程耗时较长,并不是所有使用此类都会用到的单例对象,推荐使用懒汉式

工厂模式

最终版抽象工厂模式

总接口,所有的工厂类都必须实现此接口

// Factory接口
public interface Factory {
    // 提供创建实例的方法
    Fruit create();
}

具体工厂类可以封装(创建类实例时的)细节

// 苹果工厂类
public class AppleFactory implements Factory{
    // 封装创建时的具体细节
    @Override
    public Fruit create() {
        return new Apple();
    }
}

用户调用

/*
   这是最终版本的抽象工厂模式
   优点:
   想要修改创建的具体工厂类,只需要改一行代码即可实现,修改之后调用的方法随之改变成对应的工厂实现
   缺点:
   如果Factory接口需要新增功能,会影响到所有具体的工厂类
   所以只适合增加同类具体工厂,而不适合新增功能
 */


 // 创建苹果
 Factory appleFactory = new AppleFactory();
// 直接调用接口提供的方法,不用知道具体细节
 Fruit apple = appleFactory.create();

 // 创建梨子
 Factory pearFactory = new PearFactory();
// 直接调用接口提供的方法,不用知道具体细节
 Fruit peat = pearFactory.create();

建造型模式

建造型模式用于创建过程稳定,但配置多变的对象
将一个复杂的构建与其表示相分离,使得同样的构建过程可以创建不同的表示
好处在于不会忘记指定配置,保证构建的过程是稳定的

public class MilkTea {
    // 口味类型
    private String type;
    // 大杯 中杯
    private String size;
    // 是否加珍珠
    private boolean pearl;
    // 是否加冰
    private boolean ice;

    public String getType() {
        return type;
    }

    public String getSize() {
        return size;
    }

    public boolean isPearl() {
        return pearl;
    }

    public boolean isIce() {
        return ice;
    }

    private MilkTea(MilkTeaBuilder builder) {
        this.type = builder.type;
        this.size = builder.size;
        this.pearl = builder.pearl;
        this.ice = builder.ice;
    }

    @Override
    public String toString() {
        return "MilkTea{" +
                "type='" + type + '\'' +
                ", size='" + size + '\'' +
                ", pearl=" + pearl +
                ", ice=" + ice +
                '}';
    }
    
    // 建造者
    public static class MilkTeaBuilder{
        private String type;
        private String size;
        private boolean pearl;
        private boolean ice;

        public MilkTeaBuilder(String type) {
            this.type = type;
        }

        public MilkTeaBuilder size(String size){
            this.size = size;
            return this;
        }

        public MilkTeaBuilder pearl(boolean pearl){
            this.pearl = pearl;
            return this;
        }

        public MilkTeaBuilder ice(boolean ice){
            this.ice = ice;
            return this;
        }

        public MilkTea Builder(){
            return new MilkTea(this);
        }
    }
}

用户建造一杯奶茶

MilkTea milkTea = new MilkTea.MilkTeaBuilder("蓝莓味")
    .size("大杯")
    .pearl(true)
    .ice(false)
    .Builder();
System.out.println(milkTea);

原型模式

其实就是给对象提供一个clone方法克隆出新对象

public class MilkTea {
    // 口味类型
    private String type;
    // 是否加冰
    private boolean ice;

    /*
    克隆当前实例
    ps: 如下重写clone方法是无法克隆非基本类型的(会直接引用当前的)(浅拷贝),需要自行修改
     */
    @Override
    public MilkTea clone() throws CloneNotSupportedException {
        return (MilkTea) super.clone();
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值