在前面已经提到过饿汉模式和懒汉模式,这里就不再赘述。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();
}
}