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

来源:互联网 发布:java 如何截断字符串 编辑:程序博客网 时间:2024/06/09 03:17

今天给大家简单分享关于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()方法即可。

原创粉丝点击