设计模式网上已经有很多人写了,但是发现有些要么写得比较简单,没有说清楚,要么甚至有些理解错误的。看了很多资料,重新用自己的理解梳理总结一下,将5种创建型模式归纳一下。重点描述一下工厂模式和抽象工厂模式。
创建对象的操作交由工厂完成。例如创建一个汽车类(CarClass implement CarInterface)的对象,是通过一个某品牌汽车工厂类(bencCarFactory implement CarFactoryInterface)的生产汽车方法(CarClass:produceCar())来创建。一个工厂只能生产一个单一的类对象。
1)先获取工厂:CarFactoryInterface CarFactory=getCarFactory();
2)利用工厂获取对象:CarInterface car= CarFactory. produceCar()
优点或者场景:
1)类CarInterface不能预料到他必须创建的对象的类。CarInterface并不能预料到他是要创建奔驰车呢,还是福特车呢。创建什么车,只能根据获取到的什么工厂来决定。
2)类(接口CarFactoryInterface)希望其子类(XXCarFactory)指定它(或者说允许子类决定)要创建的对象。
(spring中就只有一个默认工厂,用的是简单工厂模式。简单工厂模式不是说违背了开闭原则吗,为啥还要用简单工厂模式呢。简单工厂模式的问题在于,工厂每要支持创建一个新的类的对象,就要修改代码。违反了开闭原则,但是spring的工厂是是通过反射来实现的对象创建,就不用去修改工厂内部的创建代码了。变相解决了这个问题。同时又非常的简单好理解,不用像工厂模式一样要创建很多工厂。所以平时见得最多的反而是简单工厂模式,例如还有jdbc得DriverManger.getConnetion,也优点类似简单工厂模式,可以把DriverManger当成工厂,Connetion当成工厂生产出来得产品,工厂只有一个,但是根据数据库得不同可能返回不同的数据库连接)
一个工厂能生产一系列相关类的对象(相关的对象系列是共同使用的,否则可以用工厂模式)。对比如上工厂模式,就是奔驰汽车厂bencCarFactory不仅能生产奔驰小汽车(BencXiaocheCarClass implement XiaocheCarInterface),还能生产奔驰货车(BencHuocheClass implement HuocheCarInterface)。
一如一段代码中要用到小车和货车两个类,还是先获取工厂
1)先获取工厂:CarFactoryInterface CarFactory=getCarFactory();
2)利用工厂获取货车对象:
XiaocheCarInterface car= CarFactory. produceXiaocheCar()
3)利用工厂获取小车对象:
CarInterface car= CarFactory. produceHuocheCar()
抽象工厂更容易在产品系列中转换。不需要重新获取工厂了。
将复杂类的构建与其表示相分离。这样相同的构造过程可以创建不同的对象。
Java中很多builder类的对象就是这种模式。例如StringBuilder,只需要相同的append就可以创建出不同的String对象。
核心优点:
1)可以对产品的内部表示进行改变,将构造代码和表示代码相分离。
很多书上都是这么写的,很多人也没有进一步解释。什么是构造代码,什么是表示代码?
构造代码:指用于创建对象的代码,它包括对象的实例化、初始化和设置属性等操作,java中就是类的构造函数。
表示代码:指用于描述对象的属性和行为的代码,它包括对象的属性定义、方法定义和业务逻辑,在java中就是类的数学和非构造方法。
构造方法交给构造器来实现了,而不再类中来实现。就是构造代码和表示代码分离。
2)可以对产品的内部表示进行改变。Builder模式允许我们定义多个具体的Builder类,每个Builder类都可以按照不同的方式构建产品。这些不同的Builder类可以有不同的内部表示方式,可以在对象的构建过程中添加、删除或修改属性。通过使用Builder模式,我们可以根据需求选择不同的Builder类来构建对象,而不需要修改客户端代码。这样可以使得我们在不改变客户端代码的情况下,灵活地切换产品的内部表示方式。
通过直接复制克隆原型对象来创建新对象。可以在不了解创建对象的确切类以及如何创建等细节的情况下,直接通过克隆原型(obj.clone)来实现新对象的创建。
优点:1)减少对象创建的开销。2)简化对象创建过程。3)支持动态配置对象。
应用场景:1)要在运行时动态载入新对象时。2)当创建对象的过程比较复杂或耗时,3)创建多个相似对象,等场景
确保一个类只有一个实例。
对单个实例的受控制访问,性能更高,资源消耗减少。只是要注意线程安全。
逻辑上只需要一个实例时。