Spring--设计模式

一、简介

设计模式是软件工程领域的一组最佳实践,它们提供了一种通用解决方案来解决常见问题。Spring框架中融入了多种设计模式,以增强其灵活性、可扩展性和可重用性。

二、单例模式

Spring的单例模式指的是:确保一个类只有一个实例,并提供一个全局访问点。Spring管理的bean默认都是单例的,通过配置文件中的singleton属性进行控制。下面是一些单例模式的样例:

1.懒汉模式(线程不安全)
  优点:懒加载启动快,资源占用小,使用时才实例化,无锁。
  缺点:非线程安全。
public class LazySingleton {
  // 定义私有变量存储实例
  private static LazySingleton singleton = null;
  
  // 私有构造方法,控制实例无法在外部通过new创建实例
  private LazySingleton() {}
  
  public static LazySingleton getInstance() {
    if (singleton == null) {
      singleton = new LazySingleton ();
    }
    return singleton;
  }
}

2.懒汉模式(线程安全)
public class LazySingleton {
  // 定义私有变量存储实例
  private static LazySingleton singleton = null;
  
  // 私有构造方法,控制实例无法在外部通过new创建实例
  private LazySingleton() {}
  
  // 加入synchronized 为独占排他锁,并发性能差。即使在创建成功以后,获取实例仍然是串行化操作。
  public static *synchronized*  LazySingleton getInstance() {
    if (singleton == null) {
      singleton = new LazySingleton ();
    }
    return singleton;
  }
}

3.懒汉模式(双重加锁检查DCL)
public class LazySingleton {
  // 对保存实例的变量添加volatile的修饰,保证实例变量的可见性
  private static volatile  LazySingleton singleton = null;
  
  // 私有构造方法,控制实例无法在外部通过new创建实例
  private LazySingleton() {}
  
  public static LazySingleton getInstance() {
  	// 先检查实例是否存在,如果不存在才进入下面的同步块,否则直接返回现有实例
    if (singleton == null) {
		// 同步块,线程安全的创建实例
		synchronized(LazySingleton .class){
			//再次检查实例是否存在,如果不存在才真的创建实例
			if(singleton == null){
				singleton = new LazySingleton ();
			}
		} 
	}
		return singleton;
  }
}

4.饿汉模式
  优点:饿汉模式天生是线程安全的,使用时没有延迟。
  缺点:启动时即创建实例,启动慢,有可能造成资源浪费。
public class Singleton {
	//直接在这里创建类实例,只会创建一次
    private static Singleton instance = new Singleton();

	//私有构造方法,控制实例无法在外部通过new创建实例
    private Singleton(){}

	//定义一个方法来为客户端提供类实例,这个方法需要定义成类方法,也就是要加static
    public static Singleton getInstance(){
		//直接使用已经创建好的实例
        return instance;
    }
}

5.静态内部类
public class Singleton {
    /**
     * 类级的内部类,也就是静态的成员式内部类,该内部类的实例与外部类的实例
     * 没有绑定关系,而且只有被调用到才会装载,从而实现了延迟加载
     */
    private static class SingletonHolder{
        /**
         * 静态初始化器,由JVM来保证线程安全
         */
        private static Singleton instance = new Singleton();
    }
    // 私有构造方法,控制实例无法在外部通过new创建实例
    private Singleton(){}
    
    public static  Singleton getInstance(){
        return SingletonHolder.instance;
    }
}
这种方式同样利用了classloder的机制来保证初始化instance时只有一个线程,而这种方式是Singleton类被装载了,
instance不一定被初始化。因为SingletonHolder类没有被主动使用,只有显示通过调用getInstance方法时,
才会显示装载SingletonHolder类,从而实例化instance。想象一下,如果实例化instance很消耗资源,我想让他延迟加载,
另外一方面,我不希望在Singleton类加载时就实例化,因为我不能确保Singleton类还可能在其他的地方被主动使用从而被加载,
那么这个时候实例化instance显然是不合适的。

三、工厂模式

在Spring框架中,工厂模式主要体现在以下几种形式:

  • 简单工厂模式(Simple Factory Pattern):简单工厂模式是最直观的一种工厂模式,它通过一个单独的工厂类来创建其他类的实例。在Spring中,BeanFactory和ApplicationContext接口就是简单工厂模式的体现。例如,当你调用ApplicationContext.getBean("beanName")来获取Bean时,Spring容器就会返回与"beanName"关联的Bean实例。
1. 首先,定义一个产品接口和具体的产品实现类:
public interface Product {
    void use();
}

public class ConcreteProductA implements Product {
    @Override
    public void use() {
        System.out.println("使用产品A");
    }
}

public class ConcreteProductB implements Product {
    @Override
    public void use() {
        System.out.println("使用产品B");
    }
}

2. 然后,实现一个简单工厂类:
public class SimpleFactory {
    public Product createProduct(String type) {
        switch (type) {
            case "A":
                return new ConcreteProductA();
            case "B":
                return new ConcreteProductB();
            default:
                throw new IllegalArgumentException("未知的产品类型");
        }
    }
}

3. 接下来,在Spring的配置文件中注册工厂类和产品:
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="
           http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans.xsd">

    <!-- 注册简单工厂 -->
    <bean id="simpleFactory" class="com.example.SimpleFactory"/>

    <!-- 注册产品A -->
    <bean id="productA" class="com.example.ConcreteProductA"/>

    <!-- 注册产品B -->
    <bean id="productB" class="com.example.ConcreteProductB"/>
</beans>

4. 最后,通过Spring的ApplicationContext来获取工厂类的实例,并使用它来创建产品:
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");

// 获取工厂类
SimpleFactory factory = context.getBean("simpleFactory", SimpleFactory.class);

// 创建并使用产品A
Product productA = factory.createProduct("A");
productA.use();

// 创建并使用产品B
Product productB = factory.createProduct("B");
productB.use();
  • 工厂方法模式(Factory Method Pattern):工厂方法模式是通过定义一个用于创建对象的接口,让子类决定要实例化哪一个类。在Spring中,FactoryBean接口就是工厂方法模式的应用。FactoryBean接口要求实现该类的实例必须是一个单例,并且这个实例本身也是被容器管理的Bean。
1. 首先,定义一个产品接口和具体的产品实现类:
public interface Product {
    void show();
}

public class ProductA implements Product {
    @Override
    public void show() {
        System.out.println("这是产品A");
    }
}

2. 接着,创建一个FactoryBean实现类:
public class ProductFactory implements FactoryBean<Product> {
    @Override
    public Product getObject() throws Exception {
        // 返回产品实例
        return new ProductA();
    }

    @Override
    public Class<?> getObjectType() {
        // 返回产品的类类型
        return Product.class;
    }

    @Override
    public boolean isSingleton() {
        // 返回true表示单例
        return true;
    }
}

3. 接下来,在Spring的配置文件中注册FactoryBean:
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="
           http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans.xsd">

    <!-- 注册FactoryBean -->
    <bean id="productFactory" class="com.example.ProductFactory"/>

    <!-- 当请求Product类型的Bean时,将会从productFactory中获取 -->
    <bean id="product" class="org.springframework.beans.factory.config.ListFactoryBean">
        <property name="targetBeanName" value="productFactory"/>
    </bean>
</beans>

4. 最后,通过Spring的ApplicationContext获取由FactoryBean创建的产品对象:
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");

// 获取由FactoryBean创建的产品对象
Product product = context.getBean("product", Product.class);
product.show();
  • 抽象工厂模式:抽象工厂模式提供一个接口来创建一系列相关或依赖对象,而不需要指定它们具体的类。在Spring中,可以使用AbstractApplicationContext来创建不同类型的ApplicationContext,每个ApplicationContext可以针对特定的应用程序需求进行配置。
1. 首先,定义一个产品接口和几种产品的具体实现类:
public interface Product {
    String use();
}

public class ProductA implements Product {
    @Override
    public String use() {
        return "使用产品A";
    }
}

public class ProductB implements Product {
    @Override
    public String use() {
        return "使用产品B";
    }
}

2. 然后,创建一个抽象工厂接口和具体的工厂实现类:
public interface AbstractFactory {
    Product createProductA();
    Product createProductB();
}

public class ConcreteFactoryA implements AbstractFactory {
    @Override
    public Product createProductA() {
        return new ProductA();
    }

    @Override
    public Product createProductB() {
        return new ProductB();
    }
}

public class ConcreteFactoryB implements AbstractFactory {
    @Override
    public Product createProductA() {
        return new ProductA();
    }

    @Override
    public Product createProductB() {
        return new ProductB();
    }
}

3. 接下来,在Spring的配置文件中使用组件扫描和自动装配来创建具体的工厂实例:
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="
           http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans.xsd
           http://www.springframework.org/schema/context
           http://www.springframework.org/schema/context/spring-context.xsd">

    <!-- 激活注解扫描 -->
    <context:component-scan base-package="com.example"/>

    <!-- 定义一个Map,用于存放不同工厂的实例 -->
    <util:map id="factories" map-class="java.util.HashMap">
        <entry key="FactoryA" value-ref="concreteFactoryA"/>
        <entry key="FactoryB" value-ref="concreteFactoryB"/>
    </util:map>
</beans>

4. 最后,在代码中使用Spring的ApplicationContext来获取具体的工厂实例,并通过工厂实例创建产品:
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");

// 获取工厂实例
AbstractFactory factory = (AbstractFactory) context.getBean("FactoryA");

// 创建产品
Product productA = factory.createProductA();
Product productB = factory.createProductB();

// 使用产品
System.out.println(productA.use());
System.out.println(productB.use());

四、代理模式

在Spring框架中,代理模式是一种非常重要的设计模式,它被广泛应用于AOP(面向切面编程)和事务管理等方面。Spring的代理模式主要分为两大类:静态代理和动态代理。

  • 静态代理:是在编译时就已经确定好的代理对象,它需要手动编写一个代理类来实现目标类的接口或者继承目标类。这种方式比较简单,但是不够灵活,因为每次增加新的业务逻辑都需要修改代理类的代码。
  • 动态代理:是在运行时动态生成的代理对象,它通过反射机制在运行时动态创建一个实现了目标接口的代理类。Spring主要使用JDK动态代理和CGLIB代理两种方式来实现动态代理。
    • JDK动态代理:JDK动态代理只能代理实现了接口的类,它通过字节码技术在运行时动态地生成一个子类,这个子类实现了所有的接口,并在内部持有目标对象的引用。当调用接口方法时,代理对象会截取方法调用并执行相关的逻辑。
    • CGLIB代理:CGLIB是一个第三方的字节码处理库,它可以在运行时扩展Java类和实现Java接口。与JDK动态代理相比,CGLIB可以代理没有实现接口的类,它通过继承目标类并覆盖其方法来实现代理。

以下是一个基于Spring AOP的代理模式实现样例:

1. 首先,我们定义一个目标接口:
public interface Service {
    void execute();
}

2. 然后,创建实现该接口的目标类:
public class ServiceImpl implements Service {

    @Override
    public void execute() {
        System.out.println("执行业务操作");
    }
}

3. 接下来,定义一个切面类,用于拦截目标类的方法调用:
@Aspect
@Component
public class LoggingAspect {

    @Before("execution(* com.example.Service.*(..))")
    public void logBeforeService() {
        System.out.println("方法执行前的日志记录");
    }
}

4. 然后,在Spring配置文件或使用注解配置中,开启AOP支持并定义切面组件:
@Configuration
@EnableAspectJAutoProxy // 启用基于注解的自动代理
public class AppConfig {
}

5. 最后,在主应用程序中使用目标对象:
public class MainApp {
    public static void main(String[] args) {
        ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
        
        // 获取代理对象
        Service service = context.getBean(Service.class);
        
        // 调用方法,此时会触发切面的逻辑
        service.execute();
    }
}

五、观察者模式

在Spring框架中,观察者模式通常是通过事件处理机制来实现的,这是观察者模式的一种应用。在Spring中,可以通过定义事件和监听器来实现观察者模式。通过Spring的事件发布/订阅机制,可以实现解耦的观察者模式,使得事件的发布者和监听器之间不需要直接的引用关系。以下是Spring观察者模式的一个简单实现示例:

1. 首先定义一个事件类:
public class MyEvent extends ApplicationEvent {

    private final String message;

    public MyEvent(Object source, String message) {
        super(source);
        this.message = message;
    }

    public String getMessage() {
        return message;
    }
}

2. 接着,创建一个监听器接口:
public interface MyEventListener extends ApplicationListener<MyEvent> {
    void onApplicationEvent(MyEvent event);
}

3. 然后实现监听器接口:
@Component
public class MyEventListenerImpl implements MyEventListener {

    @Override
    public void onApplicationEvent(MyEvent event) {
        System.out.println("接收到事件: " + event.getMessage());
    }
}

4. 在Spring配置中,需要注册事件监听器:
@Configuration
public class EventConfig {

    public EventConfig(MyEventListener myEventListener) {
        SimpleApplicationEventMulticaster eventMulticaster = new SimpleApplicationEventMulticaster();
        eventMulticaster.addApplicationListener(myEventListener);
        // 设置为Spring应用上下文中的事件发布者
        ((AbstractApplicationContext) myEventListener).setEventMulticaster(eventMulticaster);
    }
}

5. 最后,在需要触发事件的地方发布事件:
@Component
public class MyEventPublisher {

    private final ApplicationEventPublisher publisher;

    @Autowired
    public MyEventPublisher(ApplicationEventPublisher publisher) {
        this.publisher = publisher;
    }

    public void publishEvent() {
        MyEvent event = new MyEvent(this, "Hello, Spring!");
        publisher.publishEvent(event);
    }
}

六、模板方法模式

在Spring框架中,模板方法模式是一种行为设计模式,它在抽象类中定义了算法的骨架,将一些步骤延迟到子类中实现。通过这种方式,Spring框架的模板方法模式允许子类在不改变算法结构的前提下,重写算法中的某些步骤,从而实现代码复用和灵活性。Spring框架中的很多组件都采用了模板方法模式,例如JdbcTemplateHibernateTemplate等。以下是一个简单的模板方法模式的实现示例:

1. 首先,定义一个抽象类,其中包含模板方法和一些钩子方法(hook methods):
public abstract class AbstractTemplate {

    // 模板方法,定义算法的骨架
    public final void templateMethod() {
        beforeHook();
        doStep();
        afterHook();
    }

    // 钩子方法1,子类可以重写该方法以提供具体实现
    protected void beforeHook() {
        // 默认实现,可以被覆盖
    }

    // 钩子方法2,子类可以重写该方法以提供具体实现
    protected abstract void doStep();

    // 钩子方法3,子类可以重写该方法以提供具体实现
    protected void afterHook() {
        // 默认实现,可以被覆盖
    }
}

2. 然后,创建子类继承抽象类,并重写钩子方法:
public class ConcreteClass extends AbstractTemplate {

    @Override
    protected void doStep() {
        // 实现具体步骤
        System.out.println("执行具体步骤");
    }
}

3. 最后,使用抽象类的模板方法调用子类的具体实现:
public class Client {

    public static void main(String[] args) {
        AbstractTemplate template = new ConcreteClass();
        template.templateMethod();
    }
}

七、适配器模式

在Spring的设计哲学中,适配器模式是一种常见的模式,它允许Spring容器提供灵活的方式来集成和扩展现有组件,无论是在Web层还是在AOP编程中。通过这种方式,Spring提高了其框架的可扩展性和可重用性。以下是适配器模式常用的两种形式:

  • Web MVCHandlerAdapter:在Spring MVC中,HandlerAdapter是一个关键组件,它负责协调控制器(Controller)和处理器映射(HandlerMapping)。HandlerAdapter定义了一个统一的接口,允许不同类型的控制器以相同的方式被Spring MVC框架调用。这意味着无论控制器是基于简单的Java类、注解方法还是其他任何机制,HandlerAdapter都能够适配并执行它们。
  • AOP Proxy:Spring AOP(面向切面编程)使用适配器模式来创建代理对象。在Spring中,可以通过配置或注解来声明一个切面(Aspect),而AOP框架则需要创建一个代理对象来包装目标对象(Target Object),以便在执行目标方法前后添加额外的行为(Advice)。

下面是使用HandlerAdapter来处理不同类型的控制器请求的适配器模式样例:

1. 首先,假设我们有一个简单的控制器接口:
public interface SimpleController {
    String handleRequest(HttpServletRequest request);
}

2. 然后,我们有一个具体的控制器实现:
public class HelloWorldController implements SimpleController {
    @Override
    public String handleRequest(HttpServletRequest request) {
        // 处理请求并返回响应字符串
        return "Hello, World!";
    }
}

3. 接下来,我们定义SimpleControllerHandlerAdapter,它实现了HandlerAdapter接口:
public class SimpleControllerHandlerAdapter implements HandlerAdapter {

    @Override
    public boolean supports(Object handler) {
        // 检查是否支持当前的handler
        return handler instanceof SimpleController;
    }

    @Override
    public ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        if (!supports(handler)) {
            throw new IllegalArgumentException("Unsupported handler type: " + handler.getClass().getName());
        }
        
        SimpleController controller = (SimpleController) handler;
        String viewName = controller.handleRequest(request);
        
        // 这里我们简单地将响应内容作为视图名称返回
        return new ModelAndView(viewName);
    }

    @Override
    public long getLastModified(HttpServletRequest request, Object handler) {
        // 返回内容最后修改时间,此处为了简化,直接返回-1
        return -1;
    }
}

4. 最后,在Spring的配置中注册这个适配器:
@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Bean
    public SimpleControllerHandlerAdapter simpleControllerHandlerAdapter() {
        return new SimpleControllerHandlerAdapter();
    }

    // 其他配置...
}
在这个样例中,SimpleControllerHandlerAdapter适配器检查传入的handler是否为SimpleController的实例,
如果是,则调用它的handleRequest方法来处理请求,并返回一个ModelAndView对象表示响应。
这样,当Spring MVC框架接收到一个请求时,它可以使用这个适配器来调用相应的控制器,并生成适当的响应。

八、装饰器模式

在Spring框架中,装饰器模式通常是通过使用AOP(面向切面编程)来实现的。装饰器模式允许在运行时动态地给一个对象添加一些额外的职责,而不改变其结构。这在Spring中非常有用,因为它提供了一种灵活的方式来增强对象的行为,而无需创建大量的子类。下面是一个使用Spring AOP实现装饰器模式的样例:

1. 定义一个业务接口:
public interface BusinessService {
    void performTask();
}

2. 实现业务接口:
public class SimpleBusinessService implements BusinessService {
    @Override
    public void performTask() {
        System.out.println("Performing simple task.");
    }
}

3. 定义一个装饰器接口:
public interface ServiceDecorator extends BusinessService {
    void additionalFunction();
}

4. 实现装饰器接口:
public class Decorator implements ServiceDecorator {
    private BusinessService businessService;

    public Decorator(BusinessService businessService) {
        this.businessService = businessService;
    }

    @Override
    public void performTask() {
        businessService.performTask();
        additionalFunction();
    }

    @Override
    public void additionalFunction() {
        System.out.println("Additional function is called.");
    }
}

5. 在Spring配置文件中配置AOP代理:
<aop:config>
    <aop:pointcut id="businessServiceOperation" expression="execution(* com.example.BusinessService.*(..))"/>
    <aop:advisor advice-ref="decoratorAdvice" pointcut-ref="businessServiceOperation"/>
</aop:config>

<bean id="businessService" class="com.example.SimpleBusinessService"/>
<bean id="decoratedBusinessService" class="com.example.Decorator">
    <constructor-arg ref="businessService"/>
</bean>

6. 定义一个通知(Advice)类:
@Component
public class DecoratorAdvice {
    
    private final BusinessService businessService;

    @Autowired
    public DecoratorAdvice(BusinessService businessService) {
        this.businessService = businessService;
    }

    @Around("@annotation(org.springframework.transaction.annotation.Transactional)")
    public Object aroundAdvice(ProceedingJoinPoint joinPoint) throws Throwable {
        System.out.println("Before performing the task.");
        Object result = joinPoint.proceed();
        System.out.println("After performing the task.");
        return result;
    }
}
在这个例子中,我们定义了一个名为SimpleBusinessService的简单业务服务,
并通过Decorator类来增强它的功能。然后我们使用Spring AOP来创建Decorator的代理,
这样当调用performTask方法时,它会先执行原始的SimpleBusinessService的performTask方法,
然后执行额外的功能。

九、策略模式

在Spring框架中,策略模式可以通过利用依赖注入和接口实现来实现。这种模式定义了一系列的算法,并将每个算法封装起来,使它们可以互换。策略的选择可以在运行时决定,而不需要修改使用策略的客户端代码。以下是如何在Spring中实现策略模式的步骤:

1. 定义一个策略接口:
public interface Strategy {
    void execute();
}

2. 实现策略接口:
public class ConcreteStrategyA implements Strategy {
    @Override
    public void execute() {
        // 实现算法A
    }
}

public class ConcreteStrategyB implements Strategy {
    @Override
    public void execute() {
        // 实现算法B
    }
}

3. 定义上下文类,用于持有策略接口的引用,并在运行时切换策略:
public class Context {
    private Strategy strategy;

    public Context(Strategy strategy) {
        this.strategy = strategy;
    }

    public void setStrategy(Strategy strategy) {
        this.strategy = strategy;
    }

    public void executeStrategy() {
        strategy.execute();
    }
}

4. 在Spring配置文件中配置策略的实现和上下文:
<!-- 定义策略Bean -->
<bean id="strategyA" class="com.example.ConcreteStrategyA"/>
<bean id="strategyB" class="com.example.ConcreteStrategyB"/>

<!-- 定义上下文Bean,并注入所需的策略 -->
<bean id="context" class="com.example.Context">
    <constructor-arg ref="strategyA"/>
</bean>

5. 使用策略:
public class Client {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
        Context ctx = context.getBean("context", Context.class);
        
        // 在运行时切换策略
        ctx.setStrategy(context.getBean("strategyB", Strategy.class));
        ctx.executeStrategy();
    }
}
在上述代码中,Strategy接口定义了一个execute方法,用于执行算法逻辑。ConcreteStrategyA和
ConcreteStrategyB是策略的具体实现。Context类负责维护对策略的引用,并提供方法来切换和执行策略。

十、建造者模式

在Spring框架中,建造者模式通常用于创建具有复杂内部状态的对象。这种模式通过将对象的构建过程与其表示分离,允许用户以逐步的方式构建对象。在Spring中,建造者模式可以通过多种方式实现,包括使用Spring的@Bean注解和Java配置类。

以下是一个简单的示例,展示如何在Spring中使用建造者模式来创建一个复杂对象:

1. 首先,定义一个复杂对象的类:
public class Product {
    private String partA;
    private String partB;
    private String partC;

    // 构造函数、getter和setter省略
}

2. 然后,创建一个建造者类来逐步构建这个对象:
public class ProductBuilder {
    private Product product = new Product();

    public ProductBuilder withPartA(String partA) {
        product.setPartA(partA);
        return this;
    }

    public ProductBuilder withPartB(String partB) {
        product.setPartB(partB);
        return this;
    }

    public ProductBuilder withPartC(String partC) {
        product.setPartC(partC);
        return this;
    }

    public Product build() {
        return product;
    }
}

3. 最后,在Spring配置中定义一个方法来创建ProductBuilder的实例,并使用它来构建Product对象:
@Configuration
public class AppConfig {
    
    @Bean
    public ProductBuilder productBuilder() {
        return new ProductBuilder();
    }

    @Bean
    public Product product(ProductBuilder builder) {
        return builder
                .withPartA("Part A")
                .withPartB("Part B")
                .withPartC("Part C")
                .build();
    }
}
在这个示例中,ProductBuilder类提供了一系列的方法来逐步构建Product对象。
每个方法都返回ProductBuilder的实例,以便链式调用。最终,build方法用于生成完整的Product对象。

相关推荐

  1. Spring--设计模式

    2024-03-19 17:36:03       20 阅读
  2. Spring设计模式之简单工厂模式

    2024-03-19 17:36:03       37 阅读
  3. Spring设计模式之单例模式

    2024-03-19 17:36:03       25 阅读
  4. Spring设计模式-实战篇之模板方法模式

    2024-03-19 17:36:03       19 阅读
  5. Spring设计模式-实战篇之策略模式 + 工厂模式

    2024-03-19 17:36:03       21 阅读
  6. Spring中使用的设计模式

    2024-03-19 17:36:03       28 阅读
  7. Spring⾥⽤到的设计模式

    2024-03-19 17:36:03       30 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-03-19 17:36:03       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-03-19 17:36:03       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-03-19 17:36:03       18 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-03-19 17:36:03       20 阅读

热门阅读

  1. UGUI源码分析与研究1-UGUI底层的实现原理

    2024-03-19 17:36:03       18 阅读
  2. 阿里巴巴中国站按关键字搜索工厂数据 API

    2024-03-19 17:36:03       18 阅读
  3. python代码截取任意页的pdf

    2024-03-19 17:36:03       21 阅读
  4. 数组的reduce 的使用和扁平化处理

    2024-03-19 17:36:03       16 阅读
  5. 在事务里发送普通消息引起的线上问题

    2024-03-19 17:36:03       24 阅读
  6. C# 通信断线重连问题说明与示例

    2024-03-19 17:36:03       20 阅读
  7. Springboot AOP

    2024-03-19 17:36:03       22 阅读
  8. 在MATLAB中进行并行计算和GPU加速?

    2024-03-19 17:36:03       24 阅读
  9. fedora RTL8821CE 无线网卡驱动安装

    2024-03-19 17:36:03       20 阅读