设计模式——多例模式(23种之外)

打印 上一主题 下一主题

主题 547|帖子 547|积分 1641

多例模式(Multiton Pattern)是一种特别的设计模式,它属于创建型模式。与单例模式(Singleton Pattern)相比,多例模式答应一个类有多个实例,但是实例的数目是有限制的,并且这些实例在全局范围内是共享的。这种模式适用于当系统中有且仅有几个对象实例被频繁利用,且这些对象的创建和烧毁开销较大时。
  在我的SpringBoot项目中遇到的一个题目,最后利用多例模式解决了。题目是我需要通过传入参数实例化一个对象,希望如果出入的参数相同那么得到的实例应该是一样的,如果参数差异则实例化的参数是差异的。这个题目我一开始想到了单例模式和工厂模式结合来解决,在工厂中判断参数是否已经存在从而创建单例实例,背面越想越觉得自己搞复杂了,固然可以解决这个题目,最效果然发现还有一种多例模式可以完善解决这个题目。那么,下面就开始演示如何利用多例模式:
需要实例化的User类

  1. public class User {
  2.     String id;
  3.     public User(String id) {
  4.         this.id = id;
  5.     }
  6.     public String getId() {
  7.         return id;
  8.     }
  9.     public void setId(String id) {
  10.         this.id = id;
  11.     }
  12.     @Override
  13.     public String toString() {
  14.         return "User{" +
  15.                 "id='" + id + '\'' +
  16.                 '}';
  17.     }
  18. }
复制代码
直接获取对象的缺点

我们正常的实例化其实是不满足条件的,比方如下代码:
  1. public class MainTest {
  2.     public static void main(String[] args) {
  3.         User user1 = new User("123");
  4.         User user2 = new User("123");
  5.         
  6.         System.out.println(user1.hashCode());
  7.         System.out.println(user2.hashCode());
  8.         System.out.println(user1 == user2);
  9.     }
  10. }
复制代码
输出效果

   128893786
1732398722
false
  显然,这样new出来的两个对象不是同一个,但是在这种情况下,我们希望通过参数构造的对象只要参数相同就能拿到同一个对象,雷同单例模式,而差异参数则创建新的对象。这种情况就非常适合多例模式,下面先容多例模式解决这个题目。
多例模式

多例模式的特点



  • 实例数目有限:与单例模式差异,多例模式答应创建多个实例,但实例的数目是有限的。
  • 全局访问:全部实例都是全局可访问的,通常通过一个全局的访问点来获取实例。
  • 实例唯一性:在答应的范围内,每个实例都是唯一的。
下面是线程安全的实现,这里我们利用一个工厂类来管理我们的User,只要是相同的id就肯定可以或许获得相同的User,差异的id拿到的User差异。代码如下:
  1. public class UserMultitonFactory {
  2.     private static final ConcurrentHashMap<String, User> userMap = new ConcurrentHashMap<>();
  3.     private UserMultitonFactory(){} // 私有构造方法防止new实例化
  4.     public static User getInstance(String id) {
  5.         // 使用computeIfAbsent方法确保线程安全的实例创建
  6.         return userMap.computeIfAbsent(id,k -> new User(k)); // 这个k就是id
  7.     }
  8.     public static void destroyInstance(String id){
  9.         userMap.remove(id);
  10.     }
  11. }
复制代码
测试

  1. public class MainTest {
  2.     public static void main(String[] args) {
  3.         User user1 = UserMultitonFactory.getInstance("123");
  4.         User user2 = UserMultitonFactory.getInstance("123");
  5.         User user3 = UserMultitonFactory.getInstance("001");
  6.         System.out.println(user1.hashCode());
  7.         System.out.println(user2.hashCode());
  8.         System.out.println(user3.hashCode());
  9.     }
  10. }
复制代码
效果

   1108411398
1108411398
1394438858
  这里我们是利用一个工厂类来管理User的创建,当然也可以让User自己成为一个多例模式类,代码如下:
  1. public class UserMultiton {
  2.     String id;
  3.     private static final ConcurrentHashMap<String, UserMultiton> userMap = new ConcurrentHashMap<>();
  4.     private UserMultiton(String id) { // 禁止外部创建该类
  5.         this.id = id;
  6.     }
  7.     public static UserMultiton getInstance(String id){
  8.         // 使用computeIfAbsent方法确保线程安全的实例创建
  9.         return userMap.computeIfAbsent(id,k -> new UserMultiton(k)); // 这个k就是id
  10.     }
  11.     public static void destroyInstance(String id){
  12.         userMap.remove(id);
  13.     }
  14.     public String getId() {
  15.         return id;
  16.     }
  17.     public void setId(String id) {
  18.         this.id = id;
  19.     }
  20.     @Override
  21.     public String toString() {
  22.         return "User{" +
  23.                 "id='" + id + '\'' +
  24.                 '}';
  25.     }
  26. }
复制代码
应用场景

多例模式是一种创建型设计模式,其应用场景重要在于管理可重复利用的资源,如线程池、数据库连接池等。这些场景中,多例模式可以或许复用已有实例,克制重复创建对象,从而进步系统性能并克制浪费系统资源。
缺点

多例模式的缺点包括:


  • 难以扩展:多例模式的实例数目是固定的,难以动态地增长或淘汰实例数目。
  • 难以测试:由于多例模式的实例数目是固定的,难以对每个实例举行单独的测试。
  • 破坏封装性:多例模式需要全局访问实例,这破坏了封装性,使得代码难以维护和扩展。
  • 代码复杂度高:多例模式的实现需要考虑线程安全、序列化等题目,因此代码复杂度较高。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

万有斥力

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表