23种设计模式----创建型模式(工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式)

1.单例模式

  单例模式(Singleton Pattern):确保某一个类只有一个实例,而且自己实例化并向整个系统提供这个实例。
  通用类图如下:
  
  通用代码如下:

public class Singleton {
    private static final Singleton singleton = new Singleton();

    // 限制产生多个对象,如果该类是抽象类,该方法可以省略
    private Singleton() {
    }

    // 获取实例对象
    public static Singleton getSingleton() {
        return singleton;
    }

    // 其他方法,尽量是static方法
    public static void doSomgting() {}
}

2.工厂方法模式

  工厂方法模式(Factory Method Pattern):定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例延迟到其子类。
通用类图如下:

在工厂方法模式中,抽象产品类Product负责定义产品的共性,实现对事物最抽象的定义;Creator为抽象创建类,也不是抽象工厂,具体如何创建产品类是由具体的实现工厂ConcreteProduct完成的。
1.抽象产品类

public abstract class Product {
    // 产品类的公式方法
    public void method1() {
        // 业务逻辑处理
    }

    // 抽象方法
    public abstract void method2();
}

2.具体产品类

/**
 * 具体产品类可以有多个
 */
public class ConcreteProduct extends Product {
    // 实现抽象方法
    public void method2() {

    }
}

3.抽象工厂类

public abstract class Creator {
    /**
     * 创建一个产品对象,其输入参数类型可以自行设置
     * 通常为String、Enum、Class等,当然也可以为空
     */
    public abstract <T extends Product> T createProduct(Class<T> c);

}

4.具体工厂类

public class ConcreteCreator extends Creator {

    public <T extends Product> T createProduct(Class<T> c) {
        Product product = null;
        try {
            product = (Product) Class.forName(c.getName()).newInstance();
        } catch (Exception e) {
            // 异常处理
        }
        return (T) product;
    }
}

5.场景类

public class Client {
    public static void main(String[] args) {
        Creator creator = new ConcreteCreator();
        Product product = creator.createProduct(ConcreteProduct.class);

        // 继续业务处理
    }
}

2.1.工厂方法模式的优点
  1).良好的封装性,代码结构清晰。
  2).工厂方法模式的扩展性非常优秀。在增加产品类的情况下,只要适当地修改具体或扩展工厂类即可。
  3).屏蔽产品类。这一点很重要,产品类的实现如何变化,调用者都不需要关心,它只需要关心产品的接口。如果从数据Mysql切换到Oracle,只要切换驱动名称就行。
  4).是典型的解耦框架。高层模块值需要知道产品的抽象类,其他的实现类都不用关心,符合迪米特法则,我们不需要的就是不要去交流;也符合依赖倒置原则,只依赖产品类的抽象;也符合里氏替换原则,使用产品子类替换产品父类。


3.抽象工厂抽象

  抽象工厂模式(Abstract Factory Pattern): 为创建一组相关或相互依赖的对象提供一个接口,而且无需指定它们的具体类。
  
抽象工厂模式是工厂方法模式的升级版本,


4.建造者模式

  建造者模式(Builder Pattern): 将一个复杂对象的构建与它的表示分离,使得相同的构建过程可以创建不同的表示。
  
Product产品类
  通常是实现了模板方法模式,也就是有模式方法和基本方法。这类一般是定义产品的基本该有的方法。
Builder抽象建造者
  规范产品的组建,一般是由子类实现。
ConcreteBuilder具体建造者
  实现抽象类定义的所有方法,并且返回一个组建好的对象。
Director导演类
  负责安排已有模块的顺序,然后告诉Builder开始建造,具体如何构建一个产品在这里定义
  
优点
  1).封装性:不用关心具体的模型内部是如何实现的
  2).多个建造者独立,容易扩展

使用场景
  1).相同的方法,不同的执行顺序,产生不同的事件结果时,可以采用
  2).多个部件或零件,都可以装配到一个对象中,但是产生的运行结果又不相同时,可以采用
  3).产品类非常复杂,或者产品类中的调用顺序不同产生了不同的效能,可以采用

注意事项:建造者模式关注的是零件类型和装配工艺(顺序),这是它与工厂方法模式最大不同的地方,两者注重点不同


5.原型模式

  原型模式(Prototype Pattern): 用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象,而不是通过new关键字产生一个对象。
  
  原型模式的核心是一个clone方法,通过该方法进行对象的拷贝,Java提供了一个Cloneable接口来标示这个对象是可拷贝的。
  为什么说是”标示”呢?因为Cloneable里面一个方法都没有的,这个接口只是一个标记作用,在JVM中具有这个标记的对象对有可能被拷贝。那怎么才能从”有可能被拷贝”转换为”可以被拷贝”呢?那就是覆盖clone()方法(因为Java类中所有类的老祖宗是Object,所以覆写的其实是Object类中的clone方法,clone()是native的)。
  
  浅复制:clone只是拷贝本对象,其对象内部的数组、引用对象引用类型都不拷贝,还是指向原生对象的内部元素地址。这种拷贝确实是非常浅,两个对象共享一个私有变量,你改我改大家改。需要注意的是clone方法只有内部的数组和引用对象才不拷贝,其他的原始类型比如int,long,char等都会被拷贝。但对于String类型,java希望代把它认为是基本类型,它是没有clone方法,处理机制也比较特殊,通过字符池(stringpool)在需要的时候才在内存中创建新的字符串,可以把String当做基本类使用。

注意:使用原型模式时,引用的成员变量必须满足两个条件才不会被拷贝;一是类的成员变量,而不是方法内变量;二是必须是一个可变的引用对象,而不是一个原始类型或不可变对象。

  深复制:将一个对象复制后,不论是基本数据类型还有引用类型,都是重新创建的。简单来说,就是深复制进行了完全彻底的复制,而浅复制不彻底。

通用源码:

public class Prototype implements Cloneable, Serializable {
    private static final long serialVersionUID = 1L;
    private String string;

    private SerializableObject obj;


    /* 浅复制 */
    public Prototype clone() {
        Prototype prototype = null;
        try {
            prototype = (Prototype) super.clone();
        } catch (CloneNotSupportedException e) {
            // 异常处理
        }
        return prototype;
    }

    /**
     * 要实现深复制,需要采用流的形式读入当前对象的二进制输入,再写出二进制数据对应的对象。
     */
    public Object deepClone() throws IOException, ClassNotFoundException {
        /* 写入当前对象的二进制流 */
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(bos);
        oos.writeObject(this);

        /* 读出二进制流产生的新对象 */
        ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
        ObjectInputStream ois = new ObjectInputStream(bis);
        return ois.readObject();
    }

    public String getString() {
        return string;
    }

    public void setString(String string) {
        this.string = string;
    }

    public SerializableObject getObj() {
        return obj;
    }

    public void setObj(SerializableObject obj) {
        this.obj = obj;
    }

}

class SerializableObject implements Serializable {
    private static final long serialVersionUID = 1L;
}
    @org.junit.Test
    public void test1(){
        Prototype prototype = new Prototype();
        while (true) {
            Prototype clonePrototype = prototype.clone(); // !!!

            // 其他的操作
        }
    }

原型模式的优点:
1).性能优良
  原型模式是在内存二进制流的拷贝,要比直接new一个对象性能好很多,特别是要在一个循环体内产生大量的对象时,原型模式可以更好地体现其优点。
2).构造函数不会执行,要注意使用。
  对象拷贝时构造函数确实没有被执行,这点从原理来讲也是可以讲得通的,Object类的clone方法的原理是从内存中(具体地说就是堆内存)以二进制流的方式来进行拷贝,重新分配一个内存块,那构造函数没有被执行也是非常正常的了。

使用场景
  1).资源优化场景:类初始化需要消化非常多的资源,这个资源包括数据、硬件资源等。
  2).通过new产生一个对象需要非常繁琐的数据准备或访问权限,则可以使用原型模式。
  3).一个对象多个修改者的场景,而且各个调用者可能都需要修改其值时,可以用原型模式拷贝多个对象供调用者使用。
  在实际项目中,原型模式很少单独出现,一般是和工厂方法模式一起出现,通过clone的方法创建一个对象,然后由工厂方法提供给调用者。原型模式已经与Java融为一体,大家可以拿来使用。

clone与final
对象的clone与对象内的final关键字是有冲突的,正常的,final类型是不能重赋值的。所以要使用clone方法,类的成员变量上不要增加final关键字。

  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java设计模式是一组经过实践验证的面向对象设计原则和模式,可以帮助开发人员解决常见的软件设计问题。下面是常见的23种设计模式: 1. 创建型模式(Creational Patterns): - 工厂方法模式(Factory Method Pattern) - 抽象工厂模式(Abstract Factory Pattern) - 单例模式(Singleton Pattern) - 原型模式(Prototype Pattern) - 建造者模式(Builder Pattern) 2. 结构型模式(Structural Patterns): - 适配器模式(Adapter Pattern) - 桥接模式(Bridge Pattern) - 组合模式(Composite Pattern) - 装饰器模式(Decorator Pattern) - 外观模式(Facade Pattern) - 享元模式(Flyweight Pattern) - 代理模式(Proxy Pattern) 3. 行为型模式(Behavioral Patterns): - 责任链模式(Chain of Responsibility Pattern) - 命令模式(Command Pattern) - 解释器模式(Interpreter Pattern) - 迭代器模式(Iterator Pattern) - 中介者模式(Mediator Pattern) - 备忘录模式(Memento Pattern) - 观察者模式(Observer Pattern) - 状态模式(State Pattern) - 策略模式(Strategy Pattern) - 模板方法模式(Template Method Pattern) - 访问者模式(Visitor Pattern) 4. 并发型模式(Concurrency Patterns): - 保护性暂停模式(Guarded Suspension Pattern) - 生产者-消费者模式(Producer-Consumer Pattern) - 读写锁模式(Read-Write Lock Pattern) - 信号量模式(Semaphore Pattern) - 线程池模式(Thread Pool Pattern) 这些设计模式可以根据问题的特点和需求来选择使用,它们提供了一些可复用的解决方案,有助于开发高质量、可维护且易于扩展的软件系统。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值