目录
享元设计模式最佳实践
享元模式(Flyweight Pattern)是一种结构型设计模式,它通过共享细粒度的对象来减少内存使用。在Java中,享元模式通常用于减少创建大量类似对象的开销,这些对象在某些方面是相同的。
以下是一个使用享元模式的示例:
//先,我们定义一个享元接口和实现类:
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