深入探索 Java 创建型模式
简介
在软件开发中,创建型模式是一类设计模式,主要用于对象的创建过程。它们帮助我们在创建对象时,将对象的创建和使用分离,使得代码更加灵活、可维护和可扩展。Java 提供了多种创建型模式,每种模式都有其独特的应用场景和优势。深入理解这些模式,能够显著提升我们的代码质量和开发效率。
目录
- 基础概念
- 使用方法
- 单例模式
- 工厂模式
- 简单工厂模式
- 工厂方法模式
- 抽象工厂模式
- 建造者模式
- 原型模式
- 常见实践
- 最佳实践
- 小结
基础概念
创建型模式主要解决对象创建过程中的问题,例如如何实例化对象、如何控制对象的创建过程、如何确保对象的唯一性等。通过使用创建型模式,我们可以将对象创建的逻辑封装起来,使得客户端代码只需要关心如何使用对象,而不需要关心对象是如何创建的。这样可以降低代码的耦合度,提高代码的可维护性和可扩展性。
使用方法
单例模式
单例模式确保一个类只有一个实例,并提供一个全局访问点来访问这个实例。
饿汉式单例
public class Singleton {
private static final Singleton INSTANCE = new Singleton();
private Singleton() {}
public static Singleton getInstance() {
return INSTANCE;
}
}
懒汉式单例(线程不安全)
public class Singleton {
private static Singleton INSTANCE;
private Singleton() {}
public static Singleton getInstance() {
if (INSTANCE == null) {
INSTANCE = new Singleton();
}
return INSTANCE;
}
}
懒汉式单例(线程安全,双重检查锁定)
public class Singleton {
private static volatile Singleton INSTANCE;
private Singleton() {}
public static Singleton getInstance() {
if (INSTANCE == null) {
synchronized (Singleton.class) {
if (INSTANCE == null) {
INSTANCE = new Singleton();
}
}
}
return INSTANCE;
}
}
工厂模式
工厂模式是一种创建对象的设计模式,它将对象的创建和使用分离。通过使用工厂类,我们可以将对象创建的逻辑封装起来,使得客户端代码只需要调用工厂类的方法来获取对象,而不需要关心对象的具体创建过程。
简单工厂模式
// 产品接口
interface Product {
void use();
}
// 具体产品类
class ConcreteProduct implements Product {
@Override
public void use() {
System.out.println("使用具体产品");
}
}
// 简单工厂类
class SimpleFactory {
public static Product createProduct() {
return new ConcreteProduct();
}
}
// 客户端代码
public class Client {
public static void main(String[] args) {
Product product = SimpleFactory.createProduct();
product.use();
}
}
工厂方法模式
// 产品接口
interface Product {
void use();
}
// 具体产品类1
class ConcreteProduct1 implements Product {
@Override
public void use() {
System.out.println("使用具体产品1");
}
}
// 具体产品类2
class ConcreteProduct2 implements Product {
@Override
public void use() {
System.out.println("使用具体产品2");
}
}
// 工厂接口
interface Factory {
Product createProduct();
}
// 具体工厂类1
class ConcreteFactory1 implements Factory {
@Override
public Product createProduct() {
return new ConcreteProduct1();
}
}
// 具体工厂类2
class ConcreteFactory2 implements Factory {
@Override
public Product createProduct() {
return new ConcreteProduct2();
}
}
// 客户端代码
public class Client {
public static void main(String[] args) {
Factory factory1 = new ConcreteFactory1();
Product product1 = factory1.createProduct();
product1.use();
Factory factory2 = new ConcreteFactory2();
Product product2 = factory2.createProduct();
product2.use();
}
}
抽象工厂模式
// 产品族接口1
interface ProductA {
void useA();
}
// 产品族接口2
interface ProductB {
void useB();
}
// 具体产品类1.1
class ConcreteProductA1 implements ProductA {
@Override
public void useA() {
System.out.println("使用具体产品A1");
}
}
// 具体产品类1.2
class ConcreteProductB1 implements ProductB {
@Override
public void useB() {
System.out.println("使用具体产品B1");
}
}
// 具体产品类2.1
class ConcreteProductA2 implements ProductA {
@Override
public void useA() {
System.out.println("使用具体产品A2");
}
}
// 具体产品类2.2
class ConcreteProductB2 implements ProductB {
@Override
public void useB() {
System.out.println("使用具体产品B2");
}
}
// 抽象工厂接口
interface AbstractFactory {
ProductA createProductA();
ProductB createProductB();
}
// 具体工厂类1
class ConcreteFactory1 implements AbstractFactory {
@Override
public ProductA createProductA() {
return new ConcreteProductA1();
}
@Override
public ProductB createProductB() {
return new ConcreteProductB1();
}
}
// 具体工厂类2
class ConcreteFactory2 implements AbstractFactory {
@Override
public ProductA createProductA() {
return new ConcreteProductA2();
}
@Override
public ProductB createProductB() {
return new ConcreteProductB2();
}
}
// 客户端代码
public class Client {
public static void main(String[] args) {
AbstractFactory factory1 = new ConcreteFactory1();
ProductA productA1 = factory1.createProductA();
ProductB productB1 = factory1.createProductB();
productA1.useA();
productB1.useB();
AbstractFactory factory2 = new ConcreteFactory2();
ProductA productA2 = factory2.createProductA();
ProductB productB2 = factory2.createProductB();
productA2.useA();
productB2.useB();
}
}
建造者模式
建造者模式将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
// 产品类
class Product {
private String part1;
private String part2;
public void setPart1(String part1) {
this.part1 = part1;
}
public void setPart2(String part2) {
this.part2 = part2;
}
@Override
public String toString() {
return "Product{" +
"part1='" + part1 + '\'' +
", part2='" + part2 + '\'' +
'}';
}
}
// 抽象建造者类
abstract class Builder {
protected Product product = new Product();
public abstract void buildPart1();
public abstract void buildPart2();
public Product getProduct() {
return product;
}
}
// 具体建造者类
class ConcreteBuilder implements Builder {
@Override
public void buildPart1() {
product.setPart1("Part1");
}
@Override
public void buildPart2() {
product.setPart2("Part2");
}
}
// 指挥者类
class Director {
private Builder builder;
public Director(Builder builder) {
this.builder = builder;
}
public Product construct() {
builder.buildPart1();
builder.buildPart2();
return builder.getProduct();
}
}
// 客户端代码
public class Client {
public static void main(String[] args) {
Builder builder = new ConcreteBuilder();
Director director = new Director(builder);
Product product = director.construct();
System.out.println(product);
}
}
原型模式
原型模式是一种创建对象的设计模式,它通过复制一个已有的对象来创建新的对象。
// 原型接口
interface Prototype extends Cloneable {
Prototype clone();
}
// 具体原型类
class ConcretePrototype implements Prototype {
@Override
public Prototype clone() {
try {
return (ConcretePrototype) super.clone();
} catch (CloneNotSupportedException e) {
throw new RuntimeException(e);
}
}
}
// 客户端代码
public class Client {
public static void main(String[] args) {
Prototype prototype = new ConcretePrototype();
Prototype clonedPrototype = prototype.clone();
System.out.println(prototype == clonedPrototype); // false
}
}
常见实践
- 单例模式:常用于管理系统中的全局资源,如数据库连接池、日志记录器等。确保在整个系统中只有一个实例,避免资源的重复创建和浪费。
- 工厂模式:在创建对象的逻辑比较复杂或者需要根据不同条件创建不同类型对象时使用。例如,根据用户的不同权限创建不同的用户对象。
- 建造者模式:适用于创建复杂对象的场景,将复杂对象的创建过程分解为多个简单步骤,使得代码更加清晰和可维护。例如,创建一个包含多个属性和复杂配置的用户对象。
- 原型模式:当创建对象的成本较高,而复制对象的成本较低时,可以使用原型模式。例如,创建大量相似的对象时,可以先创建一个原型对象,然后通过复制原型对象来创建新的对象。
最佳实践
- 选择合适的模式:根据具体的业务需求和场景,选择最合适的创建型模式。例如,如果需要确保对象的唯一性,选择单例模式;如果创建对象的逻辑复杂,选择工厂模式或建造者模式。
- 保持代码简洁:创建型模式的目的是简化对象的创建过程,因此在实现过程中要保持代码简洁,避免引入过多的复杂性。
- 遵循设计原则:在使用创建型模式时,要遵循面向对象设计的原则,如单一职责原则、开闭原则等。确保代码的可维护性和可扩展性。
- 注意线程安全:在多线程环境下使用创建型模式时,要注意线程安全问题。例如,单例模式的实现需要确保在多线程环境下只有一个实例被创建。
小结
Java 创建型模式是一组强大的设计模式,它们在对象创建过程中发挥着重要作用。通过合理使用这些模式,我们可以提高代码的灵活性、可维护性和可扩展性。在实际开发中,要根据具体需求选择合适的模式,并遵循最佳实践,以编写高质量的代码。希望本文能够帮助读者深入理解并高效使用 Java 创建型模式。