版权声明:本文为博主原创,未经博主允许不得转载。 https://blog.csdn.net/weixin_36904568/article/details/90140697
一:工厂模式
工厂模式:通过工厂,封装创建对象的代码,不需要具体实例化,使用工厂实例化
(一)简单工厂
1. 定义
又叫做静态工厂方法模式。简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例。
2. 使用
一个静态方法通过参数,创建需要的对象
- 抽象产品类
- 具体产品类
- 静态工厂类
- 业务类
- 具体业务方法:使用静态工厂生产的产品
(1)产品
package FactoryPattern.SimpleFactoryPattern;
/**
* 抽象产品
*/
public interface Product {
public void operate();
}
package FactoryPattern.SimpleFactoryPattern;
/**
* 具体产品A
*/
public class ProductA implements Product{
@Override
public void operate() {
System.out.println("产品A的业务逻辑");
}
}
package FactoryPattern.SimpleFactoryPattern;
/**
* 具体产品B
*/
public class ProductB implements Product{
@Override
public void operate() {
System.out.println("产品B的业务逻辑");
}
}
(2)静态工厂
package FactoryPattern.SimpleFactoryPattern;
/**
* 静态工厂
*/
public class Factory {
public static Product createProduct(String type){
switch (type) {
case "A":
return new ProductA();
case "B":
return new ProductB();
default:
throw new RuntimeException("not found this type!");
}
}
}
(3)测试
package FactoryPattern.SimpleFactoryPattern;
public class Test {
public static void main(String[] args) {
Product product = Factory.createProduct("A");
product.operate();
product = Factory.createProduct("B");
product.operate();
product = Factory.createProduct("C");
product.operate();
}
}
3. 特点
- 当系统引入新的产品的时候无需修改业务方法
- 工厂类集中了所有的创建逻辑,过于臃肿
- 无法变更正在创建的对象
(二)工厂方法
定义
又叫做虚拟构造子模式或者多态性工厂模式。通过定义创建对象的接口,由子类动态决定实例化,将实际创建工作推迟到子类中。
使用
抽象工厂方法(类的继承)
- 抽象工厂类
- 抽象工厂方法:单一产品
- 具体工厂类
- 具体工厂方法:创建具体产品
- 抽象产品类
- 具体产品类
- 业务类
- 具体业务方法:使用抽象工厂类生产的抽象产品
(1)工厂
package FactoryPattern.FactoryFunctionPattern;
/**
* 抽象工厂
*/
public abstract class Factory {
public abstract Product createProduct(String type);
}
package FactoryPattern.FactoryFunctionPattern;
/**
* 具体工厂A——产生A风格的具体产品
*/
public class FactoryA extends Factory {
@Override
public Product createProduct(String type) {
if (type.equals("1"))
return new ProductA_1();
else if (type.equals("2"))
return new ProductA_2();
else
throw new RuntimeException("not found this type!");
}
}
package FactoryPattern.FactoryFunctionPattern;
/**
* 具体工厂B——产生B风格的具体产品
*/
public class FactoryB extends Factory {
@Override
public Product createProduct(String type) {
if (type.equals("1"))
return new ProductB_1();
if (type.equals("2"))
return new ProductB_2();
else
throw new RuntimeException("not found this type!");
}
}
(2)产品
package FactoryPattern.FactoryFunctionPattern;
/**
* 抽象产品
*/
public interface Product {
public void operate();
}
package FactoryPattern.FactoryFunctionPattern;
/**
* 具体产品A
*/
public class ProductA_1 implements Product {
@Override
public void operate() {
System.out.println("产品A_1的业务逻辑");
}
}
package FactoryPattern.FactoryFunctionPattern;
/**
* 具体产品A
*/
public class ProductA_2 implements Product {
@Override
public void operate() {
System.out.println("产品A_2的业务逻辑");
}
}
package FactoryPattern.FactoryFunctionPattern;
/**
* 具体产品B
*/
public class ProductB_1 implements Product {
@Override
public void operate() {
System.out.println("产品B_1的业务逻辑");
}
}
package FactoryPattern.FactoryFunctionPattern;
/**
* 具体产品B
*/
public class ProductB_2 implements Product {
@Override
public void operate() {
System.out.println("产品B_2的业务逻辑");
}
}
(3)测试
package FactoryPattern.FactoryFunctionPattern;
public class Test {
public static void main(String[] args) {
//使用产品A1的业务
Factory factory = new FactoryA();
Product product = factory.createProduct("1");
product.operate();
//使用产品B2的业务
factory = new FactoryB();
product = factory.createProduct("2");
product.operate();
}
}
3. 特点
- 增加新的产品类型时,系统完全支持“开-闭原则”
- 允许系统在不修改具体工厂的情况下引进新的产品
(三)抽象工厂
1. 定义
抽象工厂模式:提供一个接口,用于创建相关或依赖对象的产品族,不需要明确具体工厂类
- 产品族:由位于不同产品等级结构中,功能相关联的产品组成的家族
- 产品等级结构:由相同的结构的产品组成
2. 使用
- 抽象工厂接口:相关联的产品组合
- 多个抽象工厂方法:多个产品
- 具体工厂
- 多个实现工厂方法
- 抽象产品类
- 具体产品类
- 业务类
- 具体业务方法:使用抽象工厂接口生产的抽象产品
(1)工厂
package FactoryPattern.AbstractFactoryPattern;
/**
* 抽象工厂
*/
public interface Factory {
//产品结构A的产品
public ProductA createProductA();
//产品结构B的产品
public ProductB createProductB();
}
package FactoryPattern.AbstractFactoryPattern;
/**
* 具体工厂——实现产品族1
*/
public class Factory1 implements Factory {
@Override
public ProductA createProductA() {
return new ProductA_1();
}
@Override
public ProductB createProductB() {
return new ProductB_1();
}
}
package FactoryPattern.AbstractFactoryPattern;
/**
* 具体工厂——实现产品族2
*/
public class Factory2 implements Factory {
@Override
public ProductA createProductA() {
return new ProductA_2();
}
@Override
public ProductB createProductB() {
return new ProductB_2();
}
}
(2)产品
package FactoryPattern.AbstractFactoryPattern;
/**
* 抽象产品
*/
public interface Product {
public void operate();
}
package FactoryPattern.AbstractFactoryPattern;
/**
* 具体产品A
*/
public interface ProductA extends Product {
public void operateA();
}
package FactoryPattern.AbstractFactoryPattern;
/**
* 具体产品B
*/
public interface ProductB extends Product {
public void operateB();
}
package FactoryPattern.AbstractFactoryPattern;
import FactoryPattern.FactoryFunctionPattern.Product;
/**
* 具体产品A
*/
public class ProductA_1 implements ProductA {
@Override
public void operate() {
System.out.println("产品A_1的基本功能");
}
@Override
public void operateA() {
System.out.println("产品A_1的特别功能");
}
}
package FactoryPattern.AbstractFactoryPattern;
import FactoryPattern.FactoryFunctionPattern.Product;
/**
* 具体产品A
*/
public class ProductA_2 implements ProductA {
@Override
public void operate() {
System.out.println("产品A_2的基本功能");
}
@Override
public void operateA() {
System.out.println("产品A_2的特别功能");
}
}
package FactoryPattern.AbstractFactoryPattern;
import FactoryPattern.FactoryFunctionPattern.Product;
/**
* 具体产品B
*/
public class ProductB_1 implements ProductB {
@Override
public void operate() {
System.out.println("产品B_1的基本功能");
}
@Override
public void operateB() {
System.out.println("产品B_1的特别功能");
}
}
package FactoryPattern.AbstractFactoryPattern;
import FactoryPattern.FactoryFunctionPattern.Product;
/**
* 具体产品B
*/
public class ProductB_2 implements ProductB {
@Override
public void operate() {
System.out.println("产品B_2的基本功能");
}
@Override
public void operateB() {
System.out.println("产品B_2的特别功能");
}
}
(3)测试
package FactoryPattern.AbstractFactoryPattern;
public class Test {
public static void main(String[] args) {
//组装第1组的产品
Factory factory1 = new Factory1();
ProductA a = factory1.createProductA();
ProductB b = factory1.createProductB();
a.operateA();
b.operateB();
//组装第2组的产品
Factory factory2 = new Factory2();
a = factory2.createProductA();
b = factory2.createProductB();
a.operateA();
b.operateB();
}
}
3. 特点
- 系统的产品有多于一个的产品族,而系统只需要其中某一族的产品
- 起到了一定的约束作用,同属于同一个产品族的产品必须配套使用
- 切换产品族的时候,只要提供不同的抽象工厂实现就可以
- 不太容易扩展新的产品,需要修改抽象工厂
二:单例模式
1. 定义
确保类中只有一个实例,由自己创建,并且提供一个全局访问点
2. 使用
(1)即时实现(饿汉式)——空间换时间
- 私有构造器
- 私有静态变量:初始化为具体对象,记录唯一实例
- 公共静态构造方法
- 返回唯一实例
package SingletonPattern;
/**
* 即时单例
*/
public class ImmediatelySingletion {
//一开始就创建
private static ImmediatelySingletion singletion = new ImmediatelySingletion();
private ImmediatelySingletion(){}
public static ImmediatelySingletion getInstance(){
return singletion;
}
}
(2)延时实现(懒汉式)——时间换空间
- 私有构造器
- 私有静态变量:初始化为空值,记录唯一实例
- 公共静态构造方法:检查是否存在实例
- 创建唯一实例
- 返回唯一实例
package SingletonPattern;
/**
* 延时实现
*/
public class DelayedSingleton {
//暂未初始化
private static DelayedSingleton singleton;
private DelayedSingleton(){}
public static DelayedSingleton getInstance(){
if (singleton == null)
singleton = new DelayedSingleton();
return singleton;
}
}
(3)枚举
单元素的枚举类型已经成为实现Singleton的最佳方法。用枚举来实现单例非常简单,只需要编写一个包含单个元素的枚举类型即可。
package SingletonPattern;
/**
* 枚举类
*/
public enum EnumSingleton {
//枚举单元素
singleton;
public void operation(){
System.out.println("枚举类的业务逻辑");
}
}
3. 多线程
(1)即时实现
(2)延迟实现
使用synchorized修饰公共静态构造方法
public static synchronized DelayedSingleton getInstance(){
if (singleton == null)
singleton = new DelayedSingleton();
return singleton;
}
特点:效率低,在每次创建实例的时候都会同步
(3) 双重检查加锁
- 使用volatile修饰私有静态变量
- 公共静态构造方法
- 第一重检查: 检查是否存在实例
- 第二重检查:进入同步块过后,再次检查实例是否存在
- 创建唯一实例
- 返回唯一实例
package SingletonPattern;
/**
* 双重加锁检查
*/
public class DuplicationCheck {
//不会被本地线程缓存
private static volatile DuplicationCheck singleton;
private DuplicationCheck(){}
public static DuplicationCheck getInstance(){
if (singleton == null){
synchronized (DuplicationCheck.class){
if (singleton == null)
singleton = new DuplicationCheck();
}
}
return singleton;
}
}
特点:volatile关键字可能会屏蔽掉虚拟机中一些必要的代码优化,效率较低
扫描二维码关注公众号,回复:
6216944 查看本文章
(4) Lazy initialization holder class模式
类级内部类:由static修饰的成员式内部类
多线程缺省同步锁:由静态初始化器(在静态字段上或static{}块中的初始化器)初始化数据时会自动同步
package SingletonPattern;
/**
* 通过静态内部类创建对象
*/
public class StaticInnerClass {
private StaticInnerClass(){}
/**
* 被调用时才会加载,由JVM保护线程安全
*/
private static class holderClass{
private static StaticInnerClass singleton = new StaticInnerClass();
}
public static StaticInnerClass getInstance(){
return holderClass.singleton;
}
}
三:生成器模式
1. 定义
将产品的内部结构(零件)与产品的生产过程分割开来,使一个建造过程可以按步骤构造出具有不同结构的产品。
- 对象:产品
- 对象的不同性质:产品的不同零件
2. 使用
- 部分构造
- 抽象构造者:定义抽象方法,规范产品对象的各个组成零件的建造,提供产品
- 具体构造者:实现抽象方法,提供具体的产品
- 具体产品类:具体构造的成果
- 整体构造
- 整体构建者:按照确定的步骤,根据不同的构造者构造产品
- 客户:使用具体构造者,通过整体构建者建造产品
(1)部分构造
package BuildPattern;
/**
* 抽象建造者
*/
public abstract class Builder {
//建造步骤
public void buildA(int param){
}
public void buildB(int param){
}
//返回产品
public Product getProduct(){
return null;
}
}
package BuildPattern;
/**
* 具体构造产品A
*/
public class BulderA extends Builder {
private Product a = new Product();
@Override
public void buildA(int param) {
a.setA(param);
}
@Override
public Product getProduct() {
return a;
}
}
package BuildPattern;
/**
* 具体构造产品B
*/
public class BuilderB extends Builder {
private Product b = new Product();
@Override
public void buildB(int param) {
b.setB(param);
}
@Override
public Product getProduct() {
return b;
}
}
package BuildPattern;
/**
* 具体产品
*/
public class Product {
int a = 0;
int b = 0;
public int getA() {
return a;
}
public void setA(int a) {
this.a = a;
}
public int getB() {
return b;
}
public void setB(int b) {
this.b = b;
}
@Override
public String toString() {
return "Product{" +
"a=" + a +
", b=" + b +
'}';
}
}
(2)整体构造
package BuildPattern;
/**
* 整体构建
*/
public class Director {
private Builder builder;
public Director(Builder builder){
this.builder = builder;
}
public void construct(int a,int b){
builder.buildA(a);
builder.buildB(b);
}
}
(3)测试
package BuildPattern;
public class Test {
public static void main(String[] args) {
Builder builder = new BulderA();
Director director = new Director(builder);
director.construct(100,100);
Product product = builder.getProduct();
System.out.println(product);
}
}
3. 特点
- 封装对象的创建过程
- 隐藏产品内部的结构:每一个内部成分本身可以是对象,也可以仅仅是产品对象的一个组成部分
- 允许多个步骤创建对象:避免对象的属性相互依赖
四:原型模式
1. 定义
用一个原型对象指明所有创建的对象的类型,然后用复制这个原型对象的办法创建出更多同类型的对象。
2. 使用
(1)简单形式
- 抽象原型
- 具体原型:被复制的对象
- 客户:提出创建对象的请求(明确对象个数)
package PrototypePattern;
/**
* 抽象接口
*/
public interface Prototype {
public Object clone();
}
package PrototypePattern;
/**
* 具体实例
*/
public class PrototypeA implements Prototype {
@Override
public Object clone() {
return new PrototypeA();
}
}
package PrototypePattern;
public class Test {
private Prototype prototype;
public Test(Prototype prototype){
this.prototype = prototype;
}
public Prototype clone(){
return (Prototype) prototype.clone();
}
public static void main(String[] args) {
Prototype prototype = new PrototypeA();
Test test = new Test(prototype);
System.out.println(test.clone());
}
}
(2)登记形式
- 抽象原型
- 具体原型:被复制的对象
- 客户:提出创建对象的请求(不确定对象个数)
- 原型管理器:创建具体原型类的对象并记录
package PrototypePattern.RegisterPrototype;
/**
* 抽象接口
*/
public interface Prototype {
public Object clone();
public void setName(String name);
public String getName();
}
package PrototypePattern.RegisterPrototype;
/**
* 具体实例
*/
public class PrototypeA implements Prototype {
private String name;
@Override
public Object clone() {
return new PrototypeA();
}
@Override
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "PrototypeA{" +
"name='" + name + '\'' +
'}';
}
}
package PrototypePattern.RegisterPrototype;
/**
* 具体实例
*/
public class PrototypeB implements Prototype {
private String name;
@Override
public Object clone() {
return new PrototypeB();
}
@Override
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "PrototypeB{" +
"name='" + name + '\'' +
'}';
}
}
package PrototypePattern.RegisterPrototype;
import java.util.HashMap;
import java.util.Map;
/**
* 原型管理者
*/
public class PrototypeRegistry {
private Map<String,Prototype> map;
public PrototypeRegistry(){
map = new HashMap<>();
}
public void add(String id,Prototype prototype){
map.put(id,prototype);
}
public void remove(String id){
map.remove(id);
}
public Prototype getPrototype(String id){
Prototype prototype = map.get(id);
if (prototype != null)
return (Prototype) prototype.clone();
return null;
}
}
package PrototypePattern.RegisterPrototype;
public class Test {
public static void main(String[] args) {
PrototypeRegistry registry = new PrototypeRegistry();
//创建原型
Prototype a = new PrototypeA();
Prototype b = new PrototypeB();
registry.add("a",a);
registry.add("b",b);
//获取原型的复制
Prototype c = registry.getPrototype("a");
c.setName("我是a的复制");
System.out.println(c);
//获取原型的复制
Prototype d = registry.getPrototype("b");
d.setName("我是b的复制");
System.out.println(d);
Prototype e = registry.getPrototype("c");
System.out.println(e);
}
}
3. 特点
- 隐藏创建对象的复杂性
- 允许在运行时动态改变具体的实现类型
- 每一个类都必须配备一个克隆方法
4. JAVA的克隆
(1)条件
- 克隆对象与原对象不是同一个对象。
- 克隆对象与原对象的类型相同
- 如果对象x的equals()方法定义其恰当的话,那么x.clone().equals(x)应当成立
(2)分类
浅度克隆
只负责克隆按值传递的数据(基本数据类型、String类型),而不复制它所引用的对象
实现:Java语言的所有类都会继承一个clone()方法
深度克隆
除了浅度克隆要克隆的值外,还负责克隆引用类型的数据。其他被引用的对象的变量将指向被复制过的新对象
实现:利用序列化实现深度克隆。
- 先使对象实现Serializable接口
- 将对象序列化
- 将对象反序列化
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();
}