如何理解Java设计模式的享元模式

发布时间:2021-11-08 10:28:59 作者:iii
来源:亿速云 阅读:146

本篇内容介绍了“如何理解Java设计模式的享元模式”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

一、引言

大家都知道单例模式,通过一个全局变量来避免重复创建对象而产生的消耗,若系统存在大量的相似对象时,又该如何处理?参照单例模式,可通过对象池缓存可共享的对象,避免创建多对象,尽可能减少内存的使用,提升性能,防止内存溢出。

在软件开发过程,如果我们需要重复使用某个对象的时候,如果我们重复地使用new创建这个对象的话,这样我们在内存就需要多次地去申请内存空间了,这样可能会出现内存使用越来越多的情况,这样的问题是非常严重,然而享元模式可以解决这个问题,下面具体看看享元模式是如何去解决这个问题的。

二、什么是享元模式

定义:共享元对象,运用共享技术有效地支持大量细粒度对象的复用。如果在一个系统中存在多个相同的对象,那么只需要共享一份对象的拷贝,而不必为每一次使用创建新的对象。

享元模式是为数不多的、只为提升系统性能而生的设计模式,主要作用就是复用大对象(重量级对象),以节省内存空间和对象创建时间。

面向对象可以非常方便的解决一些扩展性的问题,但是在这个过程中系统务必会产生一些类或者对象,如果系统中存在对象的个数过多时,将会导致系统的性能下降。对于这样的问题解决最简单直接的办法就是减少系统中对象的个数。享元模式提供了一种解决方案,使用共享技术实现相同或者相似对象的重用。也就是说实现相同或者相似对象的代码共享。

所谓享元模式就是运行共享技术有效地支持大量细粒度对象的复用。系统使用少量对象,而且这些都比较相似,状态变化小,可以实现对象的多次复用。

共享模式是支持大量细粒度对象的复用,所以享元模式要求能够共享的对象必须是细粒度对象。

首先了解两个概念:内部状态、外部状态。

内部状态:在享元对象内部不随外界环境改变而改变的共享部分。

外部状态:随着环境的改变而改变,不能够共享的状态就是外部状态。

由于享元模式区分了内部状态和外部状态,所以我们可以通过设置不同的外部状态使得相同的对象可以具备一些不同的特性,而内部状态设置为相同部分。

在我们的程序设计过程中,我们可能会需要大量的细粒度对象来表示对象,如果这些对象除了几个参数不同外其他部分都相同,这个时候我们就可以利用享元模式来大大减少应用程序当中的对象。

如何利用享元模式呢?这里我们只需要将他们少部分的不同的部分当做参数移动到类实例的外部,然后在方法调用的时候将他们传递过来就可以了。这里也就说明了一点:内部状态存储于享元对象内部,而外部状态则应该由客户端来考虑。

三、享元模式的结构

如何理解Java设计模式的享元模式

1.Flyweight: 享元接口,所有具体享元类的超类或接口,通过该接口Flyweight可以接受并作用于外部状态。通过该接口可以传入外部的状态,在享元对象的方法处理中可能会使用这些外部的数据。

2.ConcreteFlyweight: 具体的享元实现对象,指定内部状态,必须是共享的,需要封装Flyweight的内部状态。

3.UnshareConcreteFlyweight: 非共享的享元实现对象,并不是所有的Flyweight实现对象都需要共享。非共享的享元实现对象通常是对享元对象的组合对象。

4.FlyweightFactoty: 享元工厂类,主要用来创建并管理共享的享元对象,并对外提供访问共享享元的接口。当用户请求一个Flyweight时,FlyweightFactory就会提供一个已经创建的Flyweight对象或者新建一个(如果不存在)。

5.Client: 享元客户端,主要的工作就是维持一个对Flyweight的引用,计算或存储享元的外部状态,当然这里可访问共享和不共享的Flyweight对象。

享元模式的核心在于享元工厂类,享元工厂类的作用在于提供一个用于存储享元对象的享元池,用户需要对象时,首先从享元池中获取,如果享元池中不存在,则创建一个新的享元对象返回给用户,并在享元池中保存该新增对象。

四、享元模式和单例模式的异同

享元模式可以再次创建对象 也可以取缓存对象

单例模式则是严格控制单个进程中只有一个实例对象

享元模式可以通过自己实现对外部的单例 也可以在需要的使用创建更多的对象

单例模式是自身控制 需要增加不属于该对象本身的逻辑

两者都可以实现节省对象创建的时间 ThreadPool 线程池 与数据库连接池 都有使用享元模式

五、享元模式的优缺点

优点:

缺点:

六、享元模式的使用场景

七、享元模式的实现

public abstract class abStudent
    {
        public string Name;
        public string schName;
        public string Sex;
        public abStudent()
        {
            schName = "吉林大学";
            Sex = "男";
        }
        public override string ToString()
        {
            return string.Format("我叫{0},性别{1},在读学校{2}", Name, Sex, schName);
        }
    }
public class Student:abStudent
    {
        public Student(string name)
        {
            Name = name;
        }
    }
public class School
    {
        private Dictionary<int, Student> StudentList;
        public School()
        {
            StudentList = new Dictionary<int, Student>();
            StudentList.Add(1, new Student("张三"));
            StudentList.Add(2, new Student("李四"));
        }
        public Student GetStudent(int num)
        {
            return StudentList[num] as Student;
        }
    }
class Program
    {
        static void Main(string[] args)
        {
            School school = new School();
            Student student = school.GetStudent(1);
            Console.WriteLine(student.ToString());
            student = school.GetStudent(2);
            Console.WriteLine(student.ToString());
            Console.ReadKey();
        }
    }

“如何理解Java设计模式的享元模式”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注亿速云网站,小编将为大家输出更多高质量的实用文章!

推荐阅读:
  1. Java设计模式之享元模式实例详解
  2. 好程序员分享java设计模式之享元模式

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

java

上一篇:kolla-ansible如何部署openstack的ocata

下一篇:物理机房与云服务器的区别

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》