描述

  • 享元模式(Flyweight Pattern),运用共享技术有效地支持大量细粒度对象的复用。系统只使用少量的对象,而这些对象都很相似,状态变化很小,可以实现对象的多次复用。对象结构型
  • 在享元模式中可以共享的相同内容称为内部状态(IntrinsicState),而那些需要外部环境来设置的不能共享的内容称为外部状态(Extrinsic State),由于区分了内部状态和外部状态,因此可以通过设置不同的外部状态使得相同的对象可以具有一些不同的特征,而相同的内部状态是可以共享的。
  • 在享元模式中通常会出现工厂模式,需要创建一个享元工厂来负责维护一个享元池(Flyweight Pool)用于存储具有相同内部状态的享元对象。

image.png

主要角色

  • 享元模式包含如下角色:
  • Flyweight: 抽象享元类 Connection
  • ConcreteFlyweight: 具体享元类 ConnectionImpl(user,pwd,url)
  • UnsharedConcreteFlyweight: 非共享具体享元类ConnectionImpl(state)
  • FlyweightFactory: 享元工厂类;简单工厂,产品就一个Connection

代码实现

  1. @Data
  2. public abstract class AbstractFlyweight {
  3. public boolean isRunning = true;
  4. abstract void service();
  5. abstract void end();
  6. }
  1. @Data
  2. public class User extends AbstractFlyweight{
  3. private String name;
  4. private String age;
  5. @Override
  6. void service() {
  7. this.isRunning = false;
  8. System.out.println("服务开始");
  9. }
  10. @Override
  11. void end() {
  12. this.isRunning = true;
  13. System.out.println("服务结束");
  14. }
  15. }
  1. public class ZuDao {
  2. private static Map<String,User> powerSupply = new ConcurrentHashMap<>();
  3. static {
  4. User user = new User();
  5. User user1 = new User();
  6. powerSupply.put("user",user);
  7. powerSupply.put("user1",user1);
  8. }
  9. public static User getUser(String name){
  10. User user = powerSupply.get(name);
  11. //查看当前对象是否可用
  12. if(user == null ){
  13. for (User value : powerSupply.values()) {
  14. if(value.isRunning()){
  15. return value;
  16. }
  17. }
  18. }
  19. if(user !=null && user.isRunning()){
  20. return user;
  21. }
  22. return null;
  23. }
  24. }
  1. public class test {
  2. public static void main(String[] args) {
  3. User user = ZuDao.getUser("");
  4. user.service();
  5. User user1 = ZuDao.getUser("");
  6. user1.service();
  7. User user2 = ZuDao.getUser("");
  8. user2.service();
  9. }
  10. }
  11. //测试结果
  12. 服务开始
  13. 服务开始
  14. Exception in thread "main" java.lang.NullPointerException
  15. at com.lshady.flyweight.test.main(test.java:14)

使用场景

什么场景用到?

  • 典型的代表:数据库连接池
  • 所有的池化技术
  • 享元和原型模式有什么区别?享元是预先准备好的对象进行复用,原型没法确定预先有哪些
  • ……