23种设计模式代码详细介绍(一)-创建型模式

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/jjc120074203/article/details/78475919

今天给大家简单分享关于23设计模式:
总体来说设计模式分为三大类:
一、创建型模式,共五种:工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。
二、结构型模式,共七种:适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。
三、行为型模式,共十一种:策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。

本章主要详细 对创建模式这5种设计模式进行详解:

  • 工厂方法模式
  • 抽象工厂模式
  • 单例模式
  • 建造者模式
  • 原型模式

普通工厂模式:

原理:就是建立一个工厂类,统一对实现了同一接口的一些类进行实例的创建。这里写图片描述

//定义一个接口
public interface Delivery {

    /**
     * 单个
     * @return
     */
    public String Delivery();

}

编写实现类

public class A_Delivery implements Delivery {

    @Override
    public String Delivery() {
        return "A - Delivery -is Sending ";
    }

}

public class B_Delivery implements Delivery {

    @Override
    public String Delivery() {
        return "B - Delivery -is Sending ";
    }

}

创建普通工厂

/**
 * 普通工厂类
 * @author cjl
 *
 */
public class NorFactory {

    /**
     * 普通单个工厂
     * @param flag
     * @return
     */
    public Delivery sendSingleDelivery(int flag){
        if (flag > 0) {
            return new A_Delivery();
        }
        return new B_Delivery();
    } 
}

Test

public class testMain {

    public static void main(String[] args) {
        // 可以采用注解的方式进行计算
        NorFactory nor = new NorFactory();
        Delivery send=nor.sendSingleDelivery(3);
        //调用
        System.out.println(send.Delivery());
    }
}

创建多个普通工厂

public class NorFactory {

    //创建 针对A类物流发送的方法
    public Delivery send_A_Delivery(){
        return new A_Delivery();
    }
    //创建 针对B类物流发送的方法
    public Delivery send_B_Delivery(){
        return new B_Delivery();
    }
}

Test

public class testMain {

    public static void main(String[] args) {
        // 可以采用注解的方式进行计算
        NorFactory nor = new NorFactory();
        Delivery sendA=nor.send_A_Delivery();
        Delivery sendB=nor.send_B_Delivery();

        System.out.println(sendA.Delivery());
        System.out.println(sendB.Delivery());
    }
}

创建静态工厂

public class NorFactory {

    //创建 针对A类物流发送的方法
    public static DeliverysendStatic_A_Delivery(){
        return new A_Delivery();
    }
    //创建 针对B类物流发送的方法
    public static Delivery sendStatic_B_Delivery(){
        return new B_Delivery();
    }
}

Test

public class testMain {

    public static void main(String[] args) {
    // 可以采用注解的方式进行计算
    NorFactory nor = new NorFactory();

    Delivery sendA=NorFactory.sendStatic_A_Delivery();
    Delivery sendB=NorFactory.sendStatic_B_Delivery();

    System.out.println(sendA.Delivery());
    System.out.println(sendB.Delivery());
    }
}

通过对比列子可以发现 普通工厂,多个普通工厂 ,静态工厂 这类特点如下:
1、多个普通工厂,静态工厂相比,普通工厂 而言不需要传递参数进行调用各个方法。只需要实例化就可以调用。
2、普通工厂,多个普通工厂 ,静态工厂 适用的场景:凡是出现了大量的产品需要创建,并且具有共同的接口功能时,可以通过工厂方法模式进行创建。
3、普通工厂,多个普通工厂 ,静态工厂缺点:拓展性相对较弱。比如 新增一个物流又新增一个功能C,norFactory工厂如果要整合C的功能的话,就必须修改代码才能实现通过norFactory调用C的功能。因此可以采用【抽象工厂】 如下的方法解决此类问题。

抽象工厂模式
抽象工厂模式特点:

  • 每个具体工厂类可以创建多个具体产品类的实例
  • 一个抽象工厂类,可以派生出多个具体工厂类
  • 功能扩展性相比普通工厂模式要好点

如图:
这里写图片描述

//定义一个接口
public interface Delivery {

    /**
     * 单个
     * @return
     */
    public String Delivery();

}

编写实现类

public class A_Delivery implements Delivery {

    @Override
    public String Delivery() {
        return "A - Delivery -is Sending ";
    }

}

public class B_Delivery implements Delivery {

    @Override
    public String Delivery() {
        return "B - Delivery -is Sending ";
    }

}

创建抽象工厂类接口

public interface DeliveryProvider {
    public Delivery handleProvider();
}

实现接口

@Service("A_Provider_Factory")
public class A_Provider_Factory implements DeliveryProvider {

    //接口实现对A类物流数据的封装
    @Override
    public Delivery handleProvider() {
        return new A_Delivery();
    }

}
@Service("B_Provider_Factory")
public class B_Provider_Factory implements DeliveryProvider {

    //接口实现对B类物流数据的封装
    @Override
    public Delivery handleProvider() {
        return new B_Delivery();
    }

}

Test

public static void main(String[] args) {
    /*采用注解注释  
    @Autowired
    @Qualifier("XXXXname")
    private DeliveryProvider DeliveryProvider;
    */
    DeliveryProvider DpA=new A_Provider_Factory();
    Delivery Dps=DpA.handleProvider();
    System.out.println(Dps.Delivery());
    //采用注解注释 
    DeliveryProvider DpB=new B_Provider_Factory();
    Delivery Dpsb=DpB.handleProvider();
    System.out.println(Dpsb.Delivery());
}

建造者模式
将各种产品集中起来进行管理,用来创建复合对象。

/**
 * 建造者模式
 * @author cj
 *
 */
public class BuildFactory {

    private List<Delivery> tempList = new ArrayList<Delivery>();

    // 创建A对应的数据格式
    public void A_Provider_Builder(int a) {
        for (int i = 0; i < a; i++) {
            tempList.add(new A_Delivery());// 重复创建数据A
        }
    }

    // 创建B对应的数据格式
    public void B_Provider_Builder(int a) {
        for (int i = 0; i < a; i++) {
            tempList.add(new B_Delivery());// 重复创建数据B
        }
    }
}

Test

    BuildFactory bf = new BuildFactory();
    bf.A_Provider_Builder(4);
    bf.B_Provider_Builder(3);

单例模式
目的:确保一个类只有一个实例,而且自行实例化并向整个系统提供这个实例。
单例模式应该是23种设计模式中最简单的一种模式了。它有以下几个要素:
1. 私有的构造方法
2. 指向自己实例的私有静态引用
3. 以自己实例为返回值的静态的公有的方法

单例模式 通常分两种:饿汉模式 | 懒汉模式

饿汉模式:

/**
 * 单例模式(饿汉单例模式)
 * @author cjl
 *
 */
public class SingleHungerClass {

    //私有的构造方法
    private SingleHungerClass(){

    } 
    //方法1 指向自己实例的私有静态私有引用方法
    private static SingleHungerClass sc=new SingleHungerClass();

    //方法2
    private static SingleHungerClass sc=null;
    static{
        sc=new SingleHungerClass();
    }


    //以自己为实例返回值的静态共有方法
    public static SingleHungerClass getInstance(){
        return sc;
    }
}

方法1 和方法2 实现功能效果基本一样。饿汉式 需要注意的一点:当类被加载的的时候,会将实例化类返回给引用。

懒汉模式

**
 * 懒汉单例模式
 * @author cjl
 *
 */
public class SingleLazyClass {
    //定义一个私有构造函数
    private SingleLazyClass(){

    }
    //定义一个指向自己实例的 的静态引用
    private static SingleLazyClass slc= new SingleLazyClass();

    // 方法 1定义一个以自己为返回值静态实例的静态方法 (获取当前实例方法的时候 才会获取对象)
    private static synchronized SingleLazyClass getInstance(){
        if (slc==null) {
            return new SingleLazyClass();
        }
        return slc;
    }
    // 方法 2 优化方法1 这样不需要需要每次获取的方法的时候都获取对对象上锁。第一次的上锁就行
    private  static  SingleLazyClass getBetterInstnace(){
        if (slc==null) {
            synchronized(slc){
                if (slc==null) {
                    slc=new SingleLazyClass();
                }
            }
        }
        return slc;
    }
}

方法 1 和方法2 区别是 方法2 是优化了方法1 的效果 ,懒汉实例化特点是 只有当前获取实例对象方法的时候,才会获取当前实例对象(方法1) ,但是大家注意 synchronized 并不是每次都需要调用方法的时候都需要synchronized ,其实只有第一次的时候就可以(方法2)。

懒汉模式 线程是不安全的如图:
这里写图片描述

  • 1、2线程同时进入了第一个if判断
  • 1首先进入synchronized块,由于instance为null,所以它执行slc= new SingleLazyClass();
  • 由于JVM内部的优化机制,JVM先画出了一些分配给SingleLazyClass实例的空白内存,并赋值给instance成员(注意此时JVM没有开始初始化这个实例),然后1离开了synchronized块。
  • 2进入synchronized块,由于instance此时不是null,因此它马上离开了synchronized块并将结果返回给调用该方法的程序。
  • 此时2线程打算使用SingleLazyClass实例,却发现它没有被初始化,于是错误发生了。

原型模式
原型模式 实际上是根据一个已知对象实例获取/创建/拷贝一个对象种类。主要用的是对象里面 Clone()|实现Cloneable方法。原型模式一个原型对象的clone方法可以复制原型对象到一个新的对象中。

定义一个基本类

/**
 * 定义原型bean
 * @author cjl
 *
 */
public class Orign {
    private String className;

    private String classType;


    public Orign(String className, String classType) {
        super();
        this.className = className;
        this.classType = classType;
    }

    public String getClassName() {
        return className;
    }

    public void setClassName(String className) {
        this.className = className;
    }

    public String getClassType() {
        return classType;
    }

    public void setClassType(String classType) {
        this.classType = classType;
    }


}

创建一个类

/**
 * 原型模式
 * @author  cjl
 * 
 * 1.继承Cloneable
 * 2.复写clone()
 *
 */
public class OrignFactory implements Cloneable{

    private String classFactoryName;

    private String classFactoryType;

    private  Orign orign;

    private List<String> list=new ArrayList<String>();


  //克隆 自己
    @Override
    public OrignFactory clone() throwsCloneNotSupportedException {
        return (OrignFactory) super.clone();
    }
    //展示clone 数据
    @Override
    public String toString() {
        return "className:"+this.classFactoryName+",classType:"+classFactoryType+",Orign-Name"+orign.getClassName() +",Orign-Type"+orign.getClassType()+ ",list-size:"+list.size();
    }
    public String getClassFactoryName() {
        return classFactoryName;
    }

    public void setClassFactoryName(String classFactoryName) {
        this.classFactoryName = classFactoryName;
    }

    public String getClassFactoryType() {
        return classFactoryType;
    }

    public void setClassFactoryType(String classFactoryType) {
        this.classFactoryType = classFactoryType;
    }

    public Orign getOrign() {
        return orign;
    }

    public void setOrign(Orign orign) {
        this.orign = orign;
    }

    public List<String> getList() {
        return list;
    }

    public void setList(List<String> list) {
        this.list = list;
    }


    public OrignFactory() {

    }

    public OrignFactory(String classFactoryName, String classFactoryType, Orign orign, List<String> list) {
        super();
        this.classFactoryName = classFactoryName;
        this.classFactoryType = classFactoryType;
        this.orign = orign;
        this.list = list;
    }

}

Test

@Test
// 调用抽象工厂
public void testOrgin() throws CloneNotSupportedException {
        Orign or1=new Orign("O1","O2");
         List<String> list=new ArrayList<String>();
         list.add("1");
         list.add("2");
         list.add("3");
         list.add("4");
        OrignFactory nof=new OrignFactory("OF1","OF2",or1,list);
        System.out.println(nof.toString());
        System.out.println("------------复制------------------");
        OrignFactory nof2=nof.clone();
        System.out.println(nof2.toString());
        Orign or2=new Orign("O3","O4");
        System.out.println("-----------从新赋值----------------");
        nof2.setOrign(or2);
        nof2.getList().remove(3);
        System.out.println(nof2.toString());
    }

返回结果

className:OF1,classType:OF2,Orign-NameO1,Orign-TypeO2,list-size:4
-------------------------------
className:OF1,classType:OF2,Orign-NameO1,Orign-TypeO2,list-size:4
-------------------------------
className:OF1,classType:OF2,Orign-NameO3,Orign-TypeO4,list-size:3

原型模式是比较简单的设计模式。它没有复杂的多态继承体系之类的,只需要类实现Cloneable接口并重写clone()方法即可。

猜你喜欢

转载自blog.csdn.net/jjc120074203/article/details/78475919