1. JAVA 设计模式-创建

1、原型模式

依赖

<dependencies>
<dependency>
      <groupId>org.apache.commons</groupId>
      <artifactId>commons-lang3</artifactId>
      <version>3.9</version>
</dependency>
<dependency>
  <groupId>org.projectlombok</groupId>
  <artifactId>lombok</artifactId>
  <version>1.18.10</version>
</dependency>
<dependency>
  <groupId>com.alibaba</groupId>
  <artifactId>fastjson</artifactId>
  <version>1.2.68</version>
</dependency>
 </dependencies>
  • 以下为4种克隆方式:浅克隆、深克隆(序列化、apache工具包、json方式
package com.san.designers.creation.clone;
import com.aliyun.openservices.shade.com.alibaba.fastjson.JSON;
import lombok.Data;
import org.apache.commons.lang3.SerializationUtils;
import java.io.*;
import java.util.ArrayList;
import java.util.List;

/**
 * <p>深克隆、浅克隆
 * @author Threeboys33
 * @version 1.0.0
 **/
@Data
public class Person implements Cloneable, Serializable{
    private static final long serialVersionUID = -5383294242566779941L;
    private int id;
    private String name;
    private List<Role> roles = new ArrayList<>();

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }

    //字节流方式
    public Person deepStreamClone() {
        ByteArrayOutputStream bs = new ByteArrayOutputStream();
        ObjectOutputStream os = null;
        ObjectInputStream is = null;
        try {
            os = new ObjectOutputStream(bs);
            os.writeObject(this);
            ByteArrayInputStream bi = new ByteArrayInputStream(bs.toByteArray());
            is = new ObjectInputStream(bi);
            return (Person)is.readObject();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        return null;
    }

    //apache工具包
    public Person deepApacheClone() {
        Person clone = SerializationUtils.clone(this);
        return clone;
    }

    //json方式
    public Person deepJsonClone() {

        String s = JSON.toJSONString(this);
        return JSON.parseObject(s, Person.class);
    }

    public static void main(String[] args) throws CloneNotSupportedException {
        Person person = new Person();
        person.setId(1);
        person.setName("san");
        Role it = new Role("IT", 11);
        person.roles.add(it);

        Person clone = (Person)person.clone();
        clone.roles.add(new Role("Doctor", 15));
        System.err.println("====浅克隆方式 Serializable,clone接口需要实现,属性修改需要维护====");
        System.out.println("浅克隆判断对象是否相等:" + (person == clone));
        System.out.println("浅克隆引用判断对象是否相等:"+ (person.roles == clone.roles));
        System.out.println("角色列表:" + person);
        System.out.println("浅克隆角色列表:" + clone);
        person.roles.remove(1);
        System.out.println();

        Person dsClonePerson = person.deepStreamClone();
        System.err.println("====序列化克隆 Serializable接口需要实现 额外代码====");
        System.out.println("序列化方式深克隆判断对象是否相等:" + (person == dsClonePerson));
        System.out.println("序列化方式深克隆引用判断对象是否相等:"+ (person.roles == dsClonePerson.roles));
        System.out.println("角色列表:" + person);
        System.out.println("序列化深克隆角色列表:" + dsClonePerson);
        System.out.println("角色列表对象引用是否相同:" + (person.roles.get(0) == dsClonePerson.roles.get(0)));
        System.out.println();

        Person apacheUtilsClonePerson = person.deepApacheClone();
        apacheUtilsClonePerson.roles.add(new Role("boss",20));
        System.err.println("====apache化克隆 Serializable接口需要实现====");
        System.out.println("apache方式深克隆判断对象是否相等:" + (person == apacheUtilsClonePerson));
        System.out.println("apache方式深克隆引用判断对象是否相等:"+ (person.roles == apacheUtilsClonePerson.roles));
        System.out.println("角色列表:" + person);
        System.out.println("序列化深克隆角色列表:" + apacheUtilsClonePerson);
        System.out.println("角色列表对象引用是否相同:" + (person.roles.get(0) == apacheUtilsClonePerson.roles.get(0)));
        System.out.println();

        Person jsonClonePerson = person.deepJsonClone();
        jsonClonePerson.roles.add(new Role("employee",20));
        System.err.println("====json化克隆 Cloneable,Serializable接口不需要实现 ,且子类不能覆盖父类属性,每个内必须有默认的构造方法====\n");
        System.out.println("json方式深克隆判断对象是否相等:" + (person == jsonClonePerson));
        System.out.println("json方式深克隆引用判断对象是否相等:"+ (person.roles == jsonClonePerson.roles));
        System.out.println("角色列表:" + person);
        System.out.println("序列化深克隆角色列表:" + jsonClonePerson);
        System.out.println("角色列表对象引用是否相同:" + (person.roles.get(0) == jsonClonePerson.roles.get(0)));
        System.out.println();
    }
}
@Data
class Role implements Serializable{
    private static final long serialVersionUID = -1840644784097690344L;
    private String role;
    private int compensation;
    public Role() {}
    public Role(String role, int compensation) {
        this.role = role;
        this.compensation = compensation;
    }
}
  • Hashmap的克隆
class HashMap{
@Override
public Object clone() {
  HashMap<K,V> result;
  try {
    result = (HashMap<K,V>)super.clone();
  } catch (CloneNotSupportedException e) {
    // this shouldn't happen, since we are Cloneable
    throw new InternalError(e);
  }
  result.reinitialize();
  result.putMapEntries(this, false);
  return result;
}
final void putMapEntries(Map<? extends K, ? extends V> m, boolean evict) {
  int s = m.size();
  if (s > 0) {
    if (table == null) { // pre-size
      float ft = ((float)s / loadFactor) + 1.0F;
      int t = ((ft < (float)MAXIMUM_CAPACITY) ?
               (int)ft : MAXIMUM_CAPACITY);
      if (t > threshold)
        threshold = tableSizeFor(t);
    }
    else if (s > threshold)
      resize();
    for (Map.Entry<? extends K, ? extends V> e : m.entrySet()) {
      K key = e.getKey();
      V value = e.getValue();
      putVal(hash(key), key, value, false, evict);
    }
  }
}}
  • ArrayList的克隆
class ArrayList{
public Object clone() {
  try {
    ArrayList<?> v = (ArrayList<?>) super.clone();
    v.elementData = Arrays.copyOf(elementData, size);
    v.modCount = 0;
    return v;
  } catch (CloneNotSupportedException e) {
    // this shouldn't happen, since we are Cloneable
    throw new InternalError(e);
  }
}}

2、单例模式

  • 饿汉式
/**
 * <p> 此饿汉式,在类比较多的时候,由于存在ROOT trace链不可达的情况下,内存容易浪费
 * 初始化的时候,时间较长
 * 容易被暴力反射所影响
 * 容易被序列化所影响
 * @author Threeboys33
 * @version 1.0.0
 **/
public class HungrySingleton {
    private static HungrySingleton instance = new HungrySingleton();
    public HungrySingleton() {}
    public static HungrySingleton getInstance() {
        return instance;
    }
}
  • 双重检查锁
/**
 * <p>此处代码复杂,亦能被强力反射和序列化破坏
 * @author Threeboys33
 * @version 1.0.0
 **/
public class DoubleCheckSingleton {

    private static volatile DoubleCheckSingleton instance;

    private DoubleCheckSingleton() { }

    public static DoubleCheckSingleton getInstance() {
        if (instance == null) {//此处是为了较少锁的范围
            synchronized (DoubleCheckSingleton.class) {
                if (instance == null) {//此处是为了在并发情况下,获得锁后对对象状态的检测
                    //此处可能由于低层指令的冲排序,所以要用volatile关键进行规避
                    instance = new DoubleCheckSingleton();
                }
                return instance;
            }
        } else
            return instance;
    }
}
  • 内部类
/**
 * <p>被强力反射和序列化破坏。
 * @author Threeboys33
 * @version 1.0.0
 **/
public class InnerClassSingleton {
    private static InnerClassSingleton instance;
    private InnerClassSingleton(){
        if (instance != null) {
            //防止被反射影响
            throw new Error("此实例不能被反射生成");
        }
    }

    public InnerClassSingleton getInstance() {
        if (instance == null) {
            instance = InnerClass.INTANCEHOLD;
        }
        return instance;
    }
    private static class InnerClass{
        public static final InnerClassSingleton INTANCEHOLD= new InnerClassSingleton();
    }

    //防止被序列化操作影响,但实际实例化了两次,新创建的没有返回,容器式可以解决这个问题
    public InnerClassSingleton readResolve() {
        return instance;
    }
}
  • 注册式

import java.util.concurrent.ConcurrentHashMap;
/**
 * <p>spring中的容器使用的就是ConcurrentHashMap
 * @author Threeboys33
 * @version 1.0.0
 **/
public class HashMapSingleton {
    private static ConcurrentHashMap<String, Object> map = new ConcurrentHashMap<>();
    public static Object getInstance(String clazzName) throws ClassNotFoundException, IllegalAccessException,
            InstantiationException {
        if (!map.contains(clazzName)) {
            synchronized (map) {
                if (!map.contains(clazzName)) {
                    map.put(clazzName, Class.forName(clazzName).newInstance());
                    return Class.forName(clazzName).newInstance();
                }
            }
        }
        return map.get(clazzName);
    }
}
  • ThreadLocal方式
/**
 * <p>此方式在于每个线程获得的对象是唯一的,做到线程隔离的作用
 * @author Threeboys33
 * @version 1.0.0
 **/
public class ThreadLocalSingleton {
    ThreadLocal<ThreadLocalSingleton> local = new ThreadLocal<ThreadLocalSingleton>(){
        @Override
        protected ThreadLocalSingleton initialValue() {
            return new ThreadLocalSingleton();
        }
    };
    private ThreadLocalSingleton(){}
    public ThreadLocalSingleton getInstance() {
        return local.get();
    }
}

3、建造模式

import lombok.Data;
/**
 * <p>对象的初始化过程太过复杂,
 * 字段增多的情况下排列组合式的构建方法,将构建过程的选择提供给用户,这个可以有默认值
 * 顺序不一样,产生的结果也不一样,如StringBuild
 * 与使用分离开
 *
 * 适用于字段多,且产品属性相对稳定,否则容易违背开闭原则
 * 会多出新的工具类,Build,ConcreteBuild
 * @author Threeboys33
 * @version 1.0.0
 **/
@Data
public class Car {
    //基本项
    private String tire;
    private String engine;
    private String mailbox;
    private String carriage;
    //可选项
    private String conditioner;
    private String rail;
}

class CarBuilder {
    private Car car = new Car();

    public CarBuilder addTire(String tire) {
        car.setTire(tire);
        return this;
    }

    public CarBuilder addEngine(String engine) {
        car.setEngine(engine);
        return this;
    }

    public CarBuilder addMailBox(String mailbox) {
        car.setMailbox(mailbox);
        return this;
    }

    public CarBuilder addCarriage(String carriage) {
        car.setCarriage(carriage);
        return this;
    }

    public CarBuilder addConditioner(String conditioner) {
        car.setConditioner(conditioner);
        return this;
    }

    public CarBuilder addRail(String rail) {
        car.setRail(rail);
        return this;
    }

    public Car build() {
        return this.car;
    }

    public static void main(String[] args) {
        //建造者模式会引入新的类
        CarBuilder build = new CarBuilder();
        //初始化的条件太多
        build.addCarriage("6.8").addEngine("v4").addTire("6").addMailBox("40L");
        //选择性
        build.addRail("3m").addConditioner("Gree");
    }
}

4、工厂模式

工厂模式有简单工厂模式,方法工厂模式,抽象工厂模式

  • 简单工厂模式
/**
 * <p>适用创建的对象较少,产品不复杂,根据传入的参数决定产生何种具体对象
 *
 * @author Threeboys33
 * @version 1.0.0
 **/

//产品空调
interface AirConditioner {
    //温度调控
    void tempering();
}

//具体实现
class GreeAirConditioner implements AirConditioner{
    @Override
    public void tempering() {
        System.out.println("格力1.5P温度调控");
    }
}

class MediAirConditioner implements AirConditioner {
    @Override
    public void tempering() {
        System.out.println("美的1.5P温度调控");
    }
}

public class SimpleFactory {
    public static AirConditioner create(Class<? extends AirConditioner> clazz) {
        try {
            return clazz.newInstance();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        return null;
    }

    public static void main(String[] args) {
        SimpleFactory.create(MediAirConditioner.class).tempering();
    }
}
  • 工厂方法模式
/**
 * <p>创建对象需要大量的代码,通过指定子类来确定创建合适的对象
 *
 * @author Threeboys33
 * @version 1.0.0
 **/

//产品空调
interface AirConditioner {
    //温度调控
    void tempering();
}

//具体实现
class MediAirConditioner implements AirConditioner{
    @Override
    public void tempering() {
        System.out.println("美的1.5P温度调控");
    }
}

class GreeAirConditioner implements AirConditioner {
    @Override
    public void tempering() {
        System.out.println("格力2P温度调控");
    }
}

interface AirConditionerFactory {
    AirConditioner create();
}

class MediAirConditionerFactory implements AirConditionerFactory {
    @Override
    public AirConditioner create() {
        return new MediAirConditioner();
    }
}

class GreeAirConditionerFacotry implements AirConditionerFactory {
    @Override
    public AirConditioner create() {
        return new GreeAirConditioner();
    }
}

public class MethodFactory {
    private static AirConditionerFactory factory;
    public static void main(String[] args) {
        factory = new MediAirConditionerFactory();
        AirConditioner airConditioner = factory.create();
        airConditioner.tempering();
    }
}
  • 抽象工厂模式
import lombok.Data;
/**
 * <p>抽象工厂模式是根据产品族和产品梯度来维护的
 * 如 Nike下的衣服有短袖、短裤、鞋子等,这是一个产品族
 * 而每个产品,如短袖厂商可能有nike adidas nb等
 * 各个产品之间又有一定的关系,譬如短袖、短裤都是衣服,属于夏装
 *
 * 创建了大量的维护类,维护过于复杂,如果底层的产品进行修改,那么从底到上都要维护
 *
 * @author Threeboys33
 * @version 1.0.0
 **/

//短袖
@Data
abstract class Tshirt {
    protected String name;
    protected abstract void showArms();
}
class NikeTshirt extends Tshirt {
    public NikeTshirt(String name) {
        this.name = name;
    }
    @Override
    protected void showArms() {
        System.out.println(this + " show flag");
    }
}
class AdidasTshirt extends Tshirt {
    public AdidasTshirt(String name) {
        this.name = name;
    }

    @Override
    protected void showArms() {
        System.out.println(this + " show flag");
    }
}

//短裤
@Data
abstract class Shorts {
    protected String name;
    protected abstract void showLegs();
}
class NikeShorts extends Shorts{
    public NikeShorts(String name) {
        this.name = name;
    }

    @Override
    protected void showLegs() {
        System.out.println(this + " show legs");
    }
}
class AdidasShorts extends Shorts{
    public AdidasShorts(String name) {
        this.name = name;
    }
    @Override
    protected void showLegs() {
        System.out.println(this + " show legs");
    }
}

@Data
class Dressing {
    private Tshirt shirt;
    private Shorts shorts;
    //短袖
    void upperBody(){
        shirt.showArms();
    }
    //短裤
    void lowerBody(){
        shorts.showLegs();
    }
}

interface ClothesFactory {
    Tshirt createTshirt();
    Shorts createShort();
}

class NikeClotheFactory implements ClothesFactory {
    @Override
    public Tshirt createTshirt() {
        return new NikeTshirt("Nike 短袖");
    }

    @Override
    public Shorts createShort() {
        return new NikeShorts("Nike 短裤");
    }
}

class AdidasClotheFactory implements ClothesFactory {
    @Override
    public Tshirt createTshirt() {
        return new AdidasTshirt("Adidas 短袖");
    }

    @Override
    public Shorts createShort() {
        return new AdidasShorts("Adids 短裤");
    }
}

public class AbstractorFactory {
    public static void main(String[] args) {
        Dressing dressing = new Dressing();
        dressing.setShirt(new NikeClotheFactory().createTshirt());
        dressing.setShorts(new AdidasClotheFactory().createShort());
        dressing.upperBody();
        dressing.lowerBody();
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值