创建型设计模式

创建型

简单工厂

public interface Product{}

public class ConcreteProduct implements Product {
}
public class ConcreteProduct1 implements Product {
}
public class ConcreteProduct2 implements Product {
}
public class SimpleFactory{
    public Product createProduct(int type) {
        int type = 1;
        if (type == 1) {
            return new ConcreteProduct();
        } else if (type == 2) {
            return new ConcreteProduct1();
        } else if (type == 3) {
            return new ConcreteProduct2();
        }
    }
}
使用的场景?
创建逻辑比较简单,不关心对象的创建逻辑,对象种类较少

本质是什么?
创建对象的封装,多态

它解决了什么问题?
解耦,调用方不需要知道有哪些子类以及应当实例化哪个子类,避免 new 直接依赖具体类。
把对象创建逻辑集中到工厂里,复用创建逻辑,减少重复代码。

它体现了设计模式中什么原则?
单一职责原则(SRP):工厂类只负责创建对象,客户端不需要关心具体创建过程
依赖倒置原则(DIP):调用方依赖抽象(接口),而不是依赖具体实现

存在的缺陷?
如果对象种类多,工厂类会有很多 if-else,变得难以维护。
新增产品时,需要修改工厂类

你认为与它相关的设计模式有哪些? 它们之间的区别有哪些?
工厂方法模式	每个产品都有自己的工厂	解决简单工厂扩展性差的问题,每个子类工厂独立
抽象工厂模式	生产多个相关产品族	适用于一组相关对象的创建
策略模式	通过不同策略处理逻辑	可结合工厂模式,避免 if-else


*开源架构中哪些使用了这一模式?
MyBatis:SqlSessionFactory 生产 SqlSession
Spring BeanFactory:底层用简单工厂管理 Bean

工厂方法

pubblic interface Product{
    void method();
}
public class P1 implements Product {
     @Override
    public void method() {
        System.out.println("p1");
    }
}
public class P2 implements Product {
     @Override
    public void method() {
        System.out.println("p2");
    }
}

public interface Factory {
    Product create();
}
public class P1Factory implements Factory {
    @Override
    public Product create() {
        return new P1Factory();
    }
}

public class P2Factory implements Factory {
    @Override
    public Product create() {
        return new P2Factory();
    }
}

public class FactoryMethodDemo {
    public static void main(String[] args) {
       
        Product factory = new P1Factory();
        Coffee coffee = factory.create();
        coffee.method();

        
        factory = new P2Factory();
        coffee = factory.createCoffee();
        coffee.method();
    }
}

使用的场景?
产品种类较多,并且可能扩展(如数据库驱动、日志系统)。
客户端不想直接依赖具体类,而是通过抽象接口操作对象。
对象创建逻辑复杂,需要封装在工厂中,避免影响客户端代码。
需要遵循“开闭原则”,允许扩展新产品而不修改现有工厂代码。

本质是什么?
本质: 将对象的创建延迟到子类,避免直接在客户端代码中使用 new 关键字。
简单来说,它是 简单工厂模式的升级版,让每种产品都有独立的工厂,避免了 if-else 代码膨胀的问题。

它解决了什么问题?
避免代码重复:每次创建新对象时,不需要重复写实例化代码,工厂类可以复用。
降低耦合:客户端代码依赖于抽象工厂接口,而不依赖具体实现,增强了灵活性。
符合开闭原则:新增产品时只需新增具体工厂类,而不需要修改现有工厂代码。

它体现了设计模式中什么原则?
开闭原则(OCP,Open-Closed Principle)
扩展新产品时,只需新增工厂,而不影响已有代码。
单一职责原则(SRP,Single Responsibility Principle)
工厂类的唯一职责是创建对象,而非控制对象的业务逻辑。
依赖倒置原则(DIP,Dependency Inversion Principle)
代码依赖于抽象(接口),而不是具体类,增强可扩展性。

存在的缺陷?
增加代码复杂度:每个产品都需要一个工厂类,导致代码量变多。
新增工厂类较多:如果产品种类过多,会导致工厂类数量膨胀,管理较为复杂。
类爆炸问题:当产品数量大时,可能会有大量工厂类,使代码结构复杂。

你认为与它相关的设计模式有哪些? 它们之间的区别有哪些?
简单工厂模式	一个工厂类创建所有对象	适用于产品种类较少、对象创建逻辑简单	不符合开闭原则,新增产品需要修改工厂
工厂方法模式	每种产品都有独立的工厂	适用于产品较多、未来可能扩展的情况	符合开闭原则,但类数量较多
抽象工厂模式	提供一组相关产品的工厂	适用于多个产品族的情况(如 Windows/Mac UI 组件)	创建的是一组相关产品,而非单一产品
建造者模式	复杂对象的逐步构建	对象创建步骤较多,属性较复杂	用于一步步构造复杂对象,而不是简单实例化

*开源架构中哪些使用了这一模式?
Spring Framework(Spring IOC 容器)

BeanFactory 使用工厂方法模式创建和管理 Bean。
ApplicationContext.getBean() 方法背后使用了工厂模式。
JDBC(Java Database Connectivity)

DriverManager.getConnection(url, user, password) 背后就是工厂模式。
JDBC 连接工厂负责创建数据库连接,而不是客户端直接实例化 Connection。
Log4j / SLF4J

LoggerFactory.getLogger(Class clazz) 通过工厂方法创建 Logger 实例,而不是 new Logger()。
Apache Commons DBCP(数据库连接池)

BasicDataSource 通过工厂模式管理数据库连接池,确保连接复用,提升性能。
JDK 并发库

Executors.newFixedThreadPool() 返回 ThreadPoolExecutor,封装线程池创建逻辑,避免直接 new Thread()。


抽象工厂

抽象工厂可以看作是工厂方法的升级,因为工厂方法只能生产一个对象,但是抽象工厂可以生产不同族群,与工厂方法不同点是多了AbstractFactory,可以根据他创建出多个对象,这些对象有很大的相关性

public class AbstractProductA{}
public class AbstractProductB{}
public class ProductA1 extends AbstractProductA{}
public class ProductA2 extends AbstractProductA{}
public class ProductB1 extends AbstractProductB{}
public class ProductB2 extends AbstractProductB{}
public abstract class AbstractFactory {
    abstract AbstractProductA createProductA();
    abstract AbstractProductB createProductB();
}
public class ConcreteFactory1 extends AbstractFactory {
    AbstractProductA createProductA() {
        return new ProductA1();
    }
    AbstractProductB createProductB() {
        return new ProductB1();
    }
}
public class ConcreteFactory2 extends AbstractFactory {
     AbstractProductA createProductA() {
        return new ProductA2();
    }

    AbstractProductB createProductB() {
        return new ProductB2();
    }
}

public class Client {
    public static void main(String[] args) {
        AbstractFactory abstractFactory = new ConcreteFactory1();
        AbstractProductA productA = abstractFactory.createProductA();
        AbstractProductB productB = abstractFactory.createProductB();
        // do something with productA and productB
    }
}

使用的场景?
1.抽象工厂模式适用于创建一组相关或相互依赖的对象,而不需要指定它们的具体类
如:数据库访问:如 JDBC 在不同数据库(MySQLPostgreSQLOracle)之间切换。
如果系统需要创建一系列相关对象,并且需要保证它们之间的兼容性,抽象工厂模式是最佳选择

本质是什么?
抽象工厂模式的本质是工厂方法的延伸,它封装了一组相关或相互依赖的对象的创建逻辑,避免客户端直接实例化具体类,提升了解耦性和可扩展性。


它解决了什么问题?
1.避免硬编码创建多个相关对象(如 UI 组件、数据库连接、协议适配器)。
2.确保一组对象是兼容的(如 Windows UI 组件不与 MacOS UI 混用)。
3.提高可扩展性(新增产品族时,只需添加新工厂,不影响现有代码)

它体现了设计模式中什么原则?
1.依赖倒置原则(DIP):客户端依赖于抽象接口,而不是具体实现。
2.单一职责原则(SRP):工厂类只负责对象的创建,产品类负责自身逻辑。
3.开放封闭原则(OCP):可以扩展新的工厂和产品,而无需修改现有代码。

存在的缺陷?
增加代码复杂度:引入多个工厂、抽象接口,代码结构变得复杂。

你认为与它相关的设计模式有哪些? 它们之间的区别有哪些?
1.工厂方法模式(Factory Method)	抽象工厂模式的基础	工厂方法模式创建单个对象,抽象工厂创建一组对象
2.简单工厂模式(Simple Factory)	抽象工厂模式的简化版本	由一个工厂创建所有对象,扩展性差
3.建造者模式(Builder)	可以结合使用	抽象工厂关注产品族,建造者模式关注产品构建步骤
4.原型模式(Prototype)	替代抽象工厂	通过克隆对象创建实例,而不是由工厂创建

*开源架构中哪些使用了这一模式?
1.Spring
ApplicationContext 作为 抽象工厂,创建 Bean
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
MyBean myBean = context.getBean(MyBean.class);

2.JDBC
DriverManager 作为抽象工厂,适配不同数据库:
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/db", "user", "pass");

3.MyBatis
SqlSessionFactory 作为抽象工厂,创建 SqlSession

生成器

// 1. 复杂对象:User
class User {
    private String name;
    private int age;
    private String phone;
    private String email;

    // 2. 私有构造函数,防止直接实例化
    private User(Builder builder) {
        this.name = builder.name;
        this.age = builder.age;
        this.phone = builder.phone;
        this.email = builder.email;
    }

    // 3. 静态内部类 Builder
    public static class Builder {
        private String name;
        private int age;
        private String phone;
        private String email;

        // 提供链式调用的方法
        public Builder setName(String name) {
            this.name = name;
            return this;
        }

        public Builder setAge(int age) {
            this.age = age;
            return this;
        }

        public Builder setPhone(String phone) {
            this.phone = phone;
            return this;
        }

        public Builder setEmail(String email) {
            this.email = email;
            return this;
        }

        // 生成最终对象
        public User build() {
            return new User(this);
        }
    }

    @Override
    public String toString() {
        return "User{name='" + name + "', age=" + age + ", phone='" + phone + "', email='" + email + "'}";
    }
}

// 使用 Builder 构造对象
public class BuilderPatternDemo {
    public static void main(String[] args) {
        User user = new User.Builder()
                .setName("张三")
                .setAge(25)
                .setPhone("15831400722")
                .setEmail("1085738057@qq.com")
                .build();

        System.out.println(user);
    }
}
// User{name='张三', age=25, phone='15831400722', email='1085738057@qq.com'}
使用的场景?
生成器模式的使用场景
生成器模式适用于以下情况:
需要创建复杂对象,但其创建步骤和表示是独立的。
需要使用相同的创建过程,但生成不同的对象。
需要构造对象时,避免使用冗长的构造函数(即“构造函数重载地狱”)。

构造复杂对象(如游戏角色)
角色可能包含武器、护甲、技能等组件,每个组件有不同的属性。
生成器模式可以一步步构造角色,而不是直接调用一个超长的构造函数。

本质是什么?
本质: 分步创建复杂对象,并允许相同的创建过程生成不同的表示。
生成器模式关注**“如何创建”对象,而不是“创建什么”**。


它解决了什么问题?
避免复杂对象的构造函数混乱(解决“构造函数重载地狱”)。
提供对象创建的可读性(比多个构造函数参数更清晰)。
可以通过不同的构建步骤,创建不同的对象。
支持流式 API 调用(链式调用,增强可读性)

它体现了设计模式中什么原则?
单一职责原则(SRP):将复杂对象的构造与其表示分离,使得构造过程更清晰。
开闭原则(OCP):可以创建不同的具体生成器,而不会影响已有代码。
依赖倒置原则(DIP):客户端依赖于抽象的 Builder 接口,而不是具体实现。

存在的缺陷?
增加了代码复杂性:相比直接实例化对象,多了一个 Builder 类。
不适用于简单对象:如果对象的创建过程很简单,使用构造函数或工厂模式会更合适。


你认为与它相关的设计模式有哪些? 它们之间的区别有哪些?
工厂方法模式(Factory Method)	生成器模式也是一种创建型模式,但更关注构造过程	工厂方法创建对象时,通常只有一个方法,而生成器提供分步构造

抽象工厂模式(Abstract Factory)	生成器模式可以与抽象工厂模式结合使用	抽象工厂创建一组相关对象,而生成器逐步构造一个复杂对象

原型模式(Prototype)	生成器模式适用于构造复杂对象,原型模式适用于克隆已有对象	生成器通过一步步创建对象,而原型模式通过复制已有对象


*开源架构中哪些使用了这一模式?
Lombok(Java)
@Builder 注解用于自动生成 Builder 模式的代码:
@Builder
public class User {
    private String name;
    private int age;
}
User user = User.builder().name("张三").age(25).build();


StringBuilder(Java 标准库)
StringBuilder 允许通过链式调用一步步构造字符串:
String result = new StringBuilder()
    .append("Hello ")
    .append("World")
    .toString();
    
MyBatis 提供 SQL 构造器,让 SQL 语句更可读:
java
复制
编辑
String sql = new SQL()
    .SELECT("id", "name")
    .FROM("user")
    .WHERE("age > 18")
    .toString();

原型模式

public class ConcretePrototype extends ProtoType{

    private String field;

    public ConcretePrototype(String field)
    {
        this.field = field;
    }
    @Override
    ProtoType myClone() {
        return new ConcretePrototype(field);
    }

    @Override
    public String toString() {
        return this.field;
    }

    public static void main(String[] args) {
        ConcretePrototype prototype = new ConcretePrototype("abc");
        ProtoType protoType = prototype.myClone();
        System.out.println("protoType = " + protoType);
    }
}
使用的场景?
1.对象创建成本较高(如涉及数据库查询、复杂计算或 I/O 操作),而创建副本的成本较低。
2系统不应依赖具体类,而是希望通过复制已有对象来创建新对象。
3需要避免“new”带来的复杂性,如工厂方法模式创建对象可能需要大量配置,而原型模式可以快速复制已有对象。
4对象的状态相似,仅部分属性不同,适合用克隆的方式创建


本质是什么?
原型模式的本质是“克隆”,即通过复制一个已有对象,创建一个新的对象,而不是通过 new 关键字重新创建实例。
它通常提供一个 clone() 方法,使对象自己拷贝自己。


它解决了什么问题?
1避免对象创建的昂贵代价(如数据库查询、计算)。
2在运行时动态创建类的新实例,而不依赖类的构造方法。

它体现了设计模式中什么原则?
1开闭原则(OCP):可以通过修改已有对象的原型来生成新对象,而不需要修改原有的代码结构。
2单一职责原则(SRP):将“创建对象”的职责从具体类的构造函数中分离出来,使用 clone() 方法来完成。

存在的缺陷?
1深拷贝和浅拷贝的问题:
浅拷贝(Shallow Copy)只复制对象的基本属性,对象内部的引用仍指向原对象的内存地址,可能导致数据共享问题。
深拷贝(Deep Copy)则会递归复制所有引用对象,但实现复杂,且可能需要手动实现 clone() 方法。

2无法克隆不可变对象(Immutable Object):
如 String、Integer 等不可变对象,克隆时仍然会指向原对象,可能会带来意外的问题。

3对象间的复杂依赖:
如果对象内部依赖过多,克隆时可能出现依赖关系断裂或数据一致性问题。

你认为与它相关的设计模式有哪些? 它们之间的区别有哪些?
1工厂模式(Factory Pattern)	都是创建型模式	工厂模式通过 new 创建对象,而原型模式通过克隆已有对象
2单例模式(Singleton Pattern)	原型模式可能与单例冲突	单例模式保证全局只有一个实例,而原型模式支持多个克隆对象
3备忘录模式(Memento Pattern)	也涉及对象状态复制	备忘录模式用于存储对象的历史状态,而原型模式是创建新对象

*开源架构中哪些使用了这一模式?
1Spring 框架
Spring 的 Bean 作用域支持 prototype,每次请求都会返回一个新的 Bean 实例(类似克隆)。

2Dubbo
在 RPC 调用时,Dubbo 可能会使用原型模式对请求参数进行复制,避免线程安全问题。

3MyBatis
MyBatis 的 CacheKey 机制中,可能会使用对象克隆以减少重复计算。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

皇家小黄

创作不易!!!!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值