单例模式之创建型模式

在前面已经提到过饿汉模式和懒汉模式,这里就不再赘述。https://blog.csdn.net/qq_40511747/article/details/106016210

本文章主要讲的是登记式模式、上限多例类、建造者模式

登记式模式

登记式模式就是利用一个map(登记簿)封装了一组单例模式的实例,将这些对象存放在登记簿当中对于已经存在的单例类,直接返回,对于不存在的单例类,先实例化,然后注册,之后再返回。

下面是示例代码

package com.tth.createtype.regsingleton;

import java.util.HashMap;

/* 登记式单例模式
 * 基本思想:
 * 登记式单例模式维护了一组单例类的实例,
 * 将这些实例都放在map(登记簿)当中,
 * 对于已经登记过的实例,则从map中返回
 * 对于没有登记的,则先登记,然后返回
 */
//其实登记式单例模式还是饿汉模式和懒汉模式的结合
//在刚开始登记的时候,提前把类实例化,存放在map(登记簿)当中
//对于不存在的name,则先创建一个类,去登记,然后返回


public class RegSingleton {
    private static HashMap<String,RegSingleton> map = new HashMap<>();

    static {
        RegSingleton single = new RegSingleton();
        map.put(single.getClass().getName(),single);
    }
    //保护的默认无参构造方法
    protected RegSingleton(){

    }
    //静态方法工厂,返回此类的唯一实例
    public static RegSingleton getInstance(String name){
        if(name == null){
            name = RegSingleton.class.getName();
            System.out.println("name == null --->name = " + name);
        }
        if(map.get(name) == null){
            try {
                map.put(name,(RegSingleton)Class.forName(name).newInstance());
            } catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) {
                e.printStackTrace();
            }
        }
        return map.get(name);
    }

    //假设这是一段逻辑方法
    public String test() {
        return "我是一段逻辑方法";
    }

    public static void main(String[] args) {
        RegSingleton singleton = RegSingleton.getInstance(null);
        System.out.println(singleton.test());
    }
}

登记式单例模式是饿汉模式和懒汉模式的结合体,首先在static代码块中会在程序编译的时候提前加载,并添加到登记簿当中,这就是饿汉模式,还有就是对于不存在的name的单例类,就先实例化,然后登记,最后返回,这就是懒汉模式。

 

有上限多例类

一个实例数目有上限的多例类已经把实例的上限当做逻辑的一部分,并建造了多例类的内部,这种多例模式叫做有上限多例模式

package com.tth.createtype.multiobject;

import java.util.HashMap;
import java.util.Map;
import java.util.Random;

public class Multition {
    //指定内存中可以存在的实例的个数
    private static int maxNumberOfObj = 3;

    //存放实例的map
    private static Map<Integer,Multition> multitions = new HashMap<>();

    //某一实例在map中存放的位置
    private static int index;

    //在类被加载的时候创建指定个数的实例
    static {
        for(int i = 0;i < maxNumberOfObj;i++){
            multitions.put(i,new Multition());
        }
    }
    private Multition(){

    }
    public static Multition getInstance(){
        Random random = new Random();
        index = random.nextInt(maxNumberOfObj);
        Multition multition = multitions.get(index);
        return multition;
    }
    public int getIndex(){
        return index;
    }
}

说明白点其实就是一个类中利用map容器存入多个单例类,在取出的时候随机获得,单例类里面的模式是饿汉模式,在static代码块里面,编译时就被jvm加载。

生成器(建造者)模式

建造者模式使用多个简单的对象一步一步构建成一个复杂的对象,这种类型的设计模式属于创建型模式,他提供了一种创建对象的最佳方式

生成器模式将一个复杂对象的构建与他的表示分离,使得同样的构建过程可以创建不同的表示意图,就需要应用建造者模式,也叫生成器模式

建造者模式可以将产品的内部表象与产品的生成过程分割开来,从而可以使一个建造过程生成具有不同的内部表象的产品对象,如果使用了建造者模式,那么用户就只需要指定建造者的类型就可以得到他们,而具体建造过程和细节对用户是封装的。

建造者模式,将一个复杂对象的构建与它的表示进行分离,使得同样的构建过程可以产生不同的表示

代码示例

Builder接口

package com.tth.builder.demo;

// 一个产品该有的具体构建
// 建造者接口,固定建造完整产品的步骤
// 是任何人在创建产品时不会发生遗漏步骤
public interface Builder {
    void addPar1();
    void addPar2();
    Product createProduct();
}

 Director类

package com.tth.builder.demo;

//指挥者,将创建Product实例的步骤封装起来
public class Director {
    //用户告诉指挥者需要创建哪类产品,有指挥者实现具体的创建
    public static Product create(Builder builder){
        builder.addPar1();
        builder.addPar2();
        return builder.createProduct();
    }
}

 product类

package com.tth.builder.demo;

import java.util.ArrayList;
import java.util.List;
//产品类,一个完整的产品由多个部分组成
public class Product {
    //产品的构成
    private List<Object> list = new ArrayList<>();
    //添加产品的各个组件
    public void add(Object object){
        list.add(object);
    }

    public void show(){
        list.forEach(row-> System.out.println(row));
    }
}

 具体产品类1

package com.tth.builder.demo;

//具体的构建者,实现抽象建造者接口,由于实现了建造者接口,因此必须实现接口中的方法,否则编译不通过
//虽然该类中不会造成遗失产品步骤,但是如果直接使用该类创建产品时,还是需要知道创建该产品的具体细节
//因此还需要一个很关键的角色,指挥者,通过指挥者来隔离用户与构建者过程的关联
public class SpecificBuilder1 implements Builder{
    Product product = new Product();
    @Override
    public void addPar1() {
        product.add("parA");
    }

    @Override
    public void addPar2() {
        product.add("parB");
    }

    @Override
    public Product createProduct() {
        return product;
    }
}

 具体产品类2

package com.tth.builder.demo;

//具体的构建者,实现抽象建造者接口,由于实现了建造者接口,因此必须实现接口中的方法,否则编译不通过
//虽然该类中不会造成遗失产品步骤,但是如果直接使用该类创建产品时,还是需要知道创建该产品的具体细节
//因此还需要一个很关键的角色,指挥者,通过指挥者来隔离用户与构建者过程的关联
public class SpecificBuilder2 implements Builder{
    Product product = new Product();
    @Override
    public void addPar1() {
        product.add("par1");
    }

    @Override
    public void addPar2() {
        product.add("par2");
    }

    @Override
    public Product createProduct() {
        return product;
    }
}

 测试代码

package com.tth.builder.demo;

public class Test {
    public static void main(String[] args) {
        SpecificBuilder1 specificBuilder1 = new SpecificBuilder1();
        //通过指挥者来创建对象,保证在任何情况下都有统一的过程
        Product product1 = Director.create(specificBuilder1);
        product1.show();

        SpecificBuilder2 specificBuilder2 = new SpecificBuilder2();
        Product product2 = Director.create(specificBuilder2);
        product2.show();
    }
}

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值