设计模式最佳实践代码总结 - 结构型设计模式篇 - 享元设计模式最佳实践

享元设计模式最佳实践

享元模式(Flyweight Pattern)是一种结构型设计模式,它通过共享细粒度的对象来减少内存使用。在Java中,享元模式通常用于减少创建大量类似对象的开销,这些对象在某些方面是相同的。

«interface»
Flyweight
+operation(extrinsicState: any)
ConcreteFlyweight
+operation(extrinsicState: any)
FlyweightFactory
+getFlyweight(key: string)

以下是一个使用享元模式的示例:

//先,我们定义一个享元接口和实现类:
public interface Message {
    void sendMessage(String msg);
}

public class EmailMessage implements Message {
    private String subject;
    private String body;

    public EmailMessage(String subject, String body) {
        this.subject = subject;
        this.body = body;
    }

    @Override
    public void sendMessage(String msg) {
        System.out.println("Sending email with subject: " + subject + " and body: " + body + " to: " + msg);
    }
}

// 然后,我们创建一个工厂类来管理享元对象:
import java.util.HashMap;
import java.util.Map;

public class MessageFactory {
    private static final Map<String, Message> messageMap = new HashMap<>();

    public static Message getMessage(String subject, String body) {
        String key = subject + body; // 假设subject和body组合是唯一的
        if (!messageMap.containsKey(key)) {
            messageMap.put(key, new EmailMessage(subject, body));
        }
        return messageMap.get(key);
    }
}

//现在,我们可以在代码中使用这个工厂来获取享元对象:
public class MessageClient {
    public void sendMessage(String to, String subject, String body) {
        Message message = MessageFactory.getMessage(subject, body);
        message.sendMessage(to);
    }
}

spring中实践

1. 定义享元接口

首先,我们定义一个简单的享元接口Flyweight,它包含一个方法operation,该方法接受一个外在状态参数。

Java复制新建文件采纳public interface Flyweight {
    void operation(String extrinsicState);
}

2. 实现具体的享元类

接下来,我们实现ConcreteFlyweight类,它包含享元的内在状态,并提供了一个静态内部工厂类来管理享元实例。

Java复制新建文件采纳import org.springframework.stereotype.Component;

import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

@Component
public class ConcreteFlyweight implements Flyweight {
    private final String intrinsicState;

    // 私有构造函数,防止外部实例化
    private ConcreteFlyweight(String intrinsicState) {
        this.intrinsicState = intrinsicState;
    }

    // 静态内部工厂类,用于管理享元实例
    public static class Factory {
        private static final ConcurrentMap<String, ConcreteFlyweight> flyweights = new ConcurrentHashMap<>();

        // 获取享元实例的方法
        public static ConcreteFlyweight getInstance(String intrinsicState) {
            return flyweights.computeIfAbsent(intrinsicState, key -> new ConcreteFlyweight(key));
        }
    }

    @Override
    public void operation(String extrinsicState) {
        // 使用内在状态和外在状态执行操作
        System.out.println("Intrinsic State: " + intrinsicState + ", Extrinsic State: " + extrinsicState);
    }
}

注意,虽然我们在ConcreteFlyweight类上使用了@Component注解,但在本例中,我们实际上并不会通过Spring容器来管理这些享元实例,而是会通过工厂类来管理。因此,@Component注解在这里只是为了展示如何在Spring环境中组织代码,实际使用时可以移除。

3. 创建享元工厂(可选)

虽然我们在ConcreteFlyweight类中已经包含了工厂方法,但为了更好地遵循单一职责原则,我们可以将其提取到一个单独的工厂类中。然而,在这个简化的示例中,我们选择在享元类内部实现工厂方法。

4. 使用享元的服务类

现在,我们创建一个服务类FlyweightService,它将使用享元工厂来获取享元实例,并执行操作。

Java复制新建文件采纳import org.springframework.stereotype.Service;

@Service
public class FlyweightService {

    // 使用享元工厂获取实例并执行操作
    public void executeOperations() {
        ConcreteFlyweight flyweight1 = ConcreteFlyweight.Factory.getInstance("StateA");
        flyweight1.operation("Operation with StateA");

        ConcreteFlyweight flyweight2 = ConcreteFlyweight.Factory.getInstance("StateB");
        flyweight2.operation("Operation with StateB");

        // 由于内在状态相同,flyweight3和flyweight1应该是同一个实例
        ConcreteFlyweight flyweight3 = ConcreteFlyweight.Factory.getInstance("StateA");
        flyweight3.operation("Another operation with StateA");
    }
}

5. 配置Spring Boot应用

最后,我们创建一个Spring Boot应用来运行这个服务。

Java复制新建文件采纳import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class FlyweightDemoApplication implements CommandLineRunner {

    @Autowired
    private FlyweightService flyweightService;

    public static void main(String[] args) {
        SpringApplication.run(FlyweightDemoApplication.class, args);
    }

    @Override
    public void run(String... args) throws Exception {
        flyweightService.executeOperations();
    }
}

6. 运行应用

现在,你可以运行FlyweightDemoApplication类,它将启动Spring Boot应用,并执行FlyweightService中的操作。你应该会在控制台中看到输出,展示了享元模式如何共享具有相同内在状态的实例。

请注意,虽然我们在示例中使用了Spring框架的注解和组件扫描,但享元实例的管理实际上是通过工厂类来完成的,而不是通过Spring容器。这是因为享元模式的核心在于对象的共享和细粒度的控制,这通常超出了Spring

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

一个双鱼座的测开

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

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

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

打赏作者

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

抵扣说明:

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

余额充值