创建型设计模式详解
0.说明
创建型模式总体上比较简单,它们的作用就是为了产生实例对象,算是各种工作的第一步了,因为我们写的是面向对象 的代码,所以我们第一步当然是需要创建一个对象了。
简单工厂模式最简单;工厂模式在简单工厂模式的基础上增加了选择工厂的维度,需要第一步选择合适的工厂;抽象工厂模式有产品族的概念,如果各个产品是存在兼容性问题的,就要用抽象工厂模式。单例模式就不说了,为了保证全局使用的是同一对象,一方面是安全性考虑,一方面是为了节省资源;建造者模式专门对付属性很多的那种类,为了让代码更优美;原型模式用得最少,了解和 Object 类中的 clone() 方法相关的知识即可。
1.简单工厂模式
1.1 基本概念:
一个工厂类 XxxFactory,里面有一个静态方法,根据不同的传参,返回不同的子类实例。
1.2 代码说明
public class SimpleFoodFactory {
public static Food makeFood(String foodName) {
if (foodName.equals("noodle")) {
Noodle noodle = new Noodle();
noodle.setFrom("China");
noodle.setPrice("20");
return noodle;
} else if (foodName.equals("chicken")) {
Chicken chicken = new Chicken();
chicken.setFrom("American");
chicken.setPrice("25");
return chicken;
} else {
return null;
}
}
}
1.3代码说明
Food 为 Noodle 和 Chicken的父类,强调职责单一 原则,一个类只提供一种功能,SimpleFoodFactory 的功能就是只要负责生产各种 Food。
2.工厂模式
2.1 基本概念
简单工厂模式很简单,如果它能满足我们的需要,我觉得就不要折腾了。之所以需要引入工厂模式,是因为我们往往需要使用两个或两个以上的工厂。
2.2 代码说明
/**
* @author lb
* @date 2022年10月27日 16:11
*/
public interface FoofFactory {
Food makeFood(String foodName);
}
/**
* @author lb
* @date 2022年10月27日 16:12
*/
public class ChineseFoodFactory implements FoofFactory{
@Override
public Food makeFood(String foodName) {
if (foodName.equals("A")) {
return new ChineseFoodA();
} else if (foodName.equals("B")) {
return new ChineseFoodB();
} else {
return null;
}
}
}
/**
* @author lb
* @date 2022年10月27日 16:12
*/
public class AmericanFoodFactory implements FoofFactory{
@Override
public Food makeFood(String foodName) {
if (foodName.equals("A")) {
return new AmericanFoodA();
} else if (foodName.equals("B")) {
return new AmericanFoodB();
} else {
return null;
}
}
}
2.3 代码说明
ChineseFoodA、ChineseFoodB、AmericanFoodA、AmericanFoodB 都继承自 Food。
3.抽象工厂模式
3.1 基本概念
当涉及到产品族 的时候,就需要引入抽象工厂模式了。
3.2 代码说明
public static void main(String[] args) {
// 第一步就要选定一个“大厂”
ComputerFactory cf = new AmdFactory();
// 从这个大厂造 CPU
CPU cpu = cf.makeCPU();
// 从这个大厂造主板
MainBoard board = cf.makeMainBoard();
// 从这个大厂造硬盘
HardDisk hardDisk = cf.makeHardDisk();
// 将同一个厂子出来的 CPU、主板、硬盘组装在一起
Computer result = new Computer(cpu, board, hardDisk);
}
3.3 说明
抽象工厂的问题也是显而易见的,比如我们要加个显示器,就需要修改所有的工厂,给所有的工厂都加上制造显示器的方法。这有点违反了对修改关闭,对扩展开放 这个设计原则。
4.单例模式
4.1 基本概念
对象new出来的对象实例只有一个
4.2 代码说明
/**饿汉模式**/
public class Singleton {
// 首先,将 new Singleton() 堵死
private Singleton() {};
// 创建私有静态实例,意味着这个类第一次使用的时候就会进行创建
private static Singleton instance = new Singleton();
public static Singleton getInstance() {
return instance;
}
// 瞎写一个静态方法。这里想说的是,如果我们只是要调用 Singleton.getDate(...),
// 本来是不想要生成 Singleton 实例的,不过没办法,已经生成了
public static Date getDate(String mode) {return new Date();}
}
/**饱汉模式**/
public class Singleton {
// 首先,也是先堵死 new Singleton() 这条路
private Singleton() {}
// 和饿汉模式相比,这边不需要先实例化出来,注意这里的 volatile,它是必须的
private static volatile Singleton instance = null;
public static Singleton getInstance() {
if (instance == null) {
// 加锁
synchronized (Singleton.class) {
// 这一次判断也是必须的,不然会有并发问题
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
/**循环模式**/
public class Singleton3 {
private Singleton3() {}
// 主要是使用了 嵌套类可以访问外部类的静态属性和静态方法 的特性
private static class Holder {
private static Singleton3 instance = new Singleton3();
}
public static Singleton3 getInstance() {
return Holder.instance;
}
}
4.3 代码说明
饱汉模式:双重检查,指的是两次检查 instance 是否为 null; volatile 在这里是需要的,希望能引起读者的关注。