设计模式记实-工厂模式:灵活而强大的对象创建方式

在软件设计中,对象的创建和管理是一个关键问题。工厂模式是一种设计模式,旨在将对象的创建与使用分离,提供一种灵活而强大的对象创建方式。本文将深入介绍工厂模式的概念、分类以及在实际开发中的应用,同时结合实际代码示例和工厂模式的应用案例,让我们更好地理解这个强大的设计模式。

工厂模式概述

工厂模式是一种创建型设计模式,它通过将对象的创建抽象化,使客户端代码不直接依赖于具体的类实例化过程。通过工厂模式,我们可以实现对象的解耦和复用,提高代码的可维护性和扩展性。

简单工厂模式

简单工厂模式是工厂模式的一种最简单形式,通过一个工厂类来负责创建各种不同类型的对象。我们将深入探讨简单工厂模式的实现方式、优缺点以及适用场景。

class SimpleFactory {
    public Product createProduct(String type) {
        if ("A".equals(type)) {
            return new ConcreteProductA();
        } else if ("B".equals(type)) {
            return new ConcreteProductB();
        } else {
            throw new IllegalArgumentException("Unknown product type");
        }
    }
}

工厂方法模式

工厂方法模式是工厂模式的扩展,它将具体对象的创建交给子类来实现。通过工厂方法模式,我们可以实现更好的可扩展性,使得新增类型的对象创建不影响现有代码。

interface Factory {
    Product createProduct();
}

class ConcreteFactoryA implements Factory {
    public Product createProduct() {
        return new ConcreteProductA();
    }
}

class ConcreteFactoryB implements Factory {
    public Product createProduct() {
        return new ConcreteProductB();
    }
}

抽象工厂模式

抽象工厂模式是一种更高层次的工厂模式,它允许我们创建一系列相关或相互依赖的对象。抽象工厂模式将一组对象的创建封装在一个工厂接口中,不同的工厂实现可以创建不同的产品族。

interface AbstractFactory {
    ProductA createProductA();
    ProductB createProductB();
}

class ConcreteFactory1 implements AbstractFactory {
    public ProductA createProductA() {
        return new ConcreteProductA1();
    }
    public ProductB createProductB() {
        return new ConcreteProductB1();
    }
}

class ConcreteFactory2 implements AbstractFactory {
    public ProductA createProductA() {
        return new ConcreteProductA2();
    }
    public ProductB createProductB() {
        return new ConcreteProductB2();
    }
}

工厂模式在Spring中的应用

开源框架Spring广泛地应用了工厂模式。通过IoC容器和Bean工厂,Spring允许我们通过配置来管理对象的创建和依赖关系。

@Component
class SpringService {
    // By the way,   Spring 容器本身就是一个超级工厂,其顶级接口BeanFactory 通过 getBean 方法可以创建各种各样不同的实例
    private final Factory factory;

    @Autowired
    public SpringService(Factory factory) {
        this.factory = factory;
    }

    // 使用factory创建对象
    public Product createProduct() {
        return factory.createProduct();
    }
}

实际应用案例:工厂模式在Web开发中的应用

我们将以一个实际的Web开发场景为例,展示如何使用工厂模式来创建不同类型的支付方式。

interface Payment {
    void pay();
}

class Alipay implements Payment {
    public void pay() {
        System.out.println("Using Alipay for payment");
    }
}

class WeChatPay implements Payment {
    public void pay() {
        System.out.println("Using WeChat Pay for payment");
    }
}

class PaymentFactory {
    public Payment createPayment(String type) {
        if ("Alipay".equals(type)) {
            return new Alipay();
        } else if ("WeChatPay".equals(type)) {
            return new WeChatPay();
        } else {
            throw new IllegalArgumentException("Unknown payment type");
        }
    }
}

在工厂模式中的进一步应用

除了对象的创建,工厂模式还可以在其他方面进行应用,比如我主导的开源框架 Remote  当中就应用了工厂模式,就像上文所展示那样,其不仅仅应用的单例模式还应用的工厂模式,其工厂方法能够创建出单例对象出来。

 
@AllArgsConstructor(access = AccessLevel.PRIVATE)
public class RemoteLifeCycleHandlerFactory {
    private static final Logger log = LoggerFactory.getLogger(RemoteLifeCycleHandlerFactory.class);
    // RemoteLifeCycleHandlerFactory 采用饿汉式的单例模式,类加载的时候就实例化
    public static final RemoteLifeCycleHandlerFactory FACTORY = new RemoteLifeCycleHandlerFactory();
    // 饿汉式地提供一个实例容器用于保存需要的实例
    private static final Map<Class<? extends RemoteLifeCycle.LifeCycleHandler<?>>, RemoteLifeCycle.LifeCycleHandler<?>> INSTANCE_CACHE = new ConcurrentHashMap<>();
  
    // 根据类型获取单例实例
    // 单例的工厂方法
    // 通过传入要创建的实例对象类型,获取或者创建单例的实例对象
    // 类似与 Sring 的 BeanFactory#getBean(Class<?> beanClass);
    public RemoteLifeCycle.LifeCycleHandler<?> singletonHandler(Class<? extends RemoteLifeCycle.LifeCycleHandler<?>> clazz){
        RemoteLifeCycle.LifeCycleHandler<?> handler = INSTANCE_CACHE.get(clazz);
        // 如果存在实例则直接返回
        if (Objects.nonNull(handler))
            return handler;
        // 锁定资源
        synchronized (INSTANCE_CACHE){
            handler = INSTANCE_CACHE.get(clazz);
            // 双重检查,是否存在实例, 如果存在则直接返回
            if (Objects.nonNull(handler))
                return handler;
            // 创建实例
            Constructor<?> constructor = Arrays.stream(clazz.getConstructors()).filter(item -> item.getParameterCount() == 0).findFirst().orElseThrow(() -> new RuntimeException("RemoteLifeCycleHandler [" + clazz.getName() + "] can not found default constructor..."));
            try {
                if (Modifier.PUBLIC != constructor.getModifiers())
                    throw new IllegalArgumentException("Default Constructor of Class<" + clazz.getName() + "> must be public");
 
                handler = (RemoteLifeCycle.LifeCycleHandler<?>) constructor.newInstance();
            } catch (InvocationTargetException | InstantiationException | IllegalAccessException e) {
                // 添加错误日志
                log.warn("Cannot construct instance for class: {}, Exception: {}", clazz.getName(),e.getMessage(),e);
            }
            // 将实例放入缓存,并返回实例
            INSTANCE_CACHE.put(clazz, handler);
            return handler;
        }
    }
}

singletonHandler 方法:这是工厂模式的核心方法。它接受一个 Class 对象作为参数,然后尝试从缓存中获取该类对应的实例,如果实例不存在,则使用反射创建实例。这种方法确保每个类只有一个实例,并且在需要的时候进行创建,从而提供了对象的单例管理。

总的来说,这段代码利用工厂模式将对象的创建和管理进行了封装。它通过缓存已创建的实例,避免了重复创建实例,从而提高了性能。此外,工厂还提供了添加处理器和生命周期的方法,使得管理更加灵活。通过单例模式,它确保了每个处理器类的实例唯一性,并且在需要时进行延迟创建。

请注意,虽然这段代码使用了工厂模式的思想,但其中的实现略显复杂,涉及到了反射和线程安全的考虑。如果您在实际项目中使用类似的模式,建议进行充分的测试和验证,确保其正确性和性能。

总结与展望

工厂模式是一种非常有用的设计模式,它可以帮助我们更灵活地管理对象的创建过程。通过深入的介绍和实际示例,我们更好地理解了工厂模式的概念、应用和好处。通过学习工厂模式,我们可以提高代码的可维护性、可扩展性和复用性。在实际项目中,选择合适的工厂模式可以极大地简化代码,提高开发效率。希望通过这篇文章,您能够对工厂模式有更深刻的认识。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Asial Jim

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值