精华内容
下载资源
问答
  • 享元模式不同于一般的设计模式,它主要用来优化程序的性能,它最适合解决大量类似的对象而产生的性能问题。享元模式通过分析应用程序的对象,将其解析为内在数据和外在数据,减少对象的数量,从而提高应用程序的性能...
  • 主要介绍了Java设计模式之共享模式/享元模式(Flyweight模式)介绍,本文讲解了为什么使用共享模式/享元模式、如何使用共享模式/享元模式、Flyweight模式在XML等数据源中应用等内容,需要的朋友可以参考下
  • 设计模式之享元模式 设计模式之享元模式 设计模式之享元模式
  • 享元模式的概念 在面向对象软件设计中,利用公共对象不仅能节省资源还能提高性能。共享的对象只能提供某些内在的信息,而不能用来识别对象。专门用于设计可共享对象的一种设计模式叫做享元模式(Flyweight pattern)...
  • 通过两个例子的对比来凸显享元模式的特点:享元模式是一个为了提高性能(空间复杂度)的设计模式,享元模式可以避免大量非常相似类的开销。 第一实例,没有使用享元模式,计算所花费的时间和空间使用程度。 要求为:有...
  • 享元模式主要是对其数据、方法共享分离,将数据和方法分成内部数据、内部方法和外部数据、外部方法。内部方法与内部数据指的是相似或共有的数据和方法,所以将其提取出来减少开销。 var Flyweight = function() { ...
  • 主要介绍了C++设计模式之享元模式,本文讲解了什么是享元模式享元模式代码实例、享元模式的优点等内容,需要的朋友可以参考下
  • 主要为大家详细介绍了C++设计模式之享元模式Flyweight,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
  • 主要介绍了深入理解JavaScript系列(37):设计模式之享元模式详解,享元模式(Flyweight),运行共享技术有效地支持大量细粒度的对象,避免大量拥有相同内容的小类的开销(如耗费内存),使大家共享一个类(元类),需要的...
  • 主要介绍了Java设计模式之享元模式,结合实例形式详细分析了享元模式的概念、功能、定义及使用方法,需要的朋友可以参考下
  • 主要为大家介绍了JavaScript设计模式中的享元模式,对JavaScript设计模式感兴趣的小伙伴们可以参考一下
  • 享元模式运用共享技术有效地支持大量细粒度对象的复用。系统只使用少量的对象,而这些对象都很相似,状态变化很小,可以实现对象的多次复用。
  • Composite:(1)、意图:将对象组合成树形结构以表示“部分--整体”的层次结构。Composite使得用户对单个对象和组合对象的使用具有一致性。(2)、适用性:A、你想表示对象的部分--整体层次结构;B、你希望用户忽略组合...
  • 主要介绍了C++设计模式编程的Flyweight享元模式结构,享元模式在实现过程中主要是要为共享对象提供一个存放的"仓库"(对象池),需要的朋友可以参考下
  • 主要介绍了JavaScript设计模式之享元模式,结合实例形式较为详细的分析了javascript享元模式相关概念、原理、用法及操作注意事项,需要的朋友可以参考下
  • 主要介绍了Python设计模式之享元模式原理与用法,结合实例形式较为详细的分析了享元模式的相关概念、原理、定义及使用方法,需要的朋友可以参考下
  • 主要帮助大家轻松掌握JavaScript享元模式,告诉大家想什么是js享元模式,感兴趣的小伙伴们可以参考一下
  • 主要介绍了Java基于享元模式实现五子棋游戏功能,较为详细的分析了享元模式的概念、功能并结合实例形式详细分析了Java使用享元模式实现五子棋游戏的具体操作步骤与相关注意事项,需要的朋友可以参考下
  • 享元模式分析并实现一个具体案例。在一家咖啡店中客户每买一杯咖啡,咖啡制做系统就相应地创建该杯咖啡的配料表,并将其发送给店内的咖啡制做机,咖啡制做机接收到系统发送的配料表后便开始制造客户所买的咖啡。...
  • 本文试图通过一个简单的字符处理的例子,运用重构的手段,一步步带你走进Flyweight模式,在这个过程中我们一同思考、探索、权衡,通过比较而得出好的实现方式,而不是给你最终的一个完美解决方案。面向对象的思想很...
  • 设计模式之享元模式

    2018-07-08 22:27:47
    享元模式,根据《设计模式之禅》,自己写的实例,可以参考一下
  • 享元模式

    2020-10-12 17:01:08
    享元模式 享元模式Flyweight Pattern主要用于减少创建对象的数量,以减少内存占用和提高性能,其提供了减少对象数量从而改善应用所需的对象结构的方式,享元模式尝试重用现有的同类对象,如果未找到匹配的对象,则...

    享元模式

    享元模式Flyweight Pattern主要用于减少创建对象的数量,以减少内存占用和提高性能,其提供了减少对象数量从而改善应用所需的对象结构的方式,享元模式尝试重用现有的同类对象,如果未找到匹配的对象,则创建新对象。享元模式运用共享技术有效地支持大量细粒度对象的复用,系统只使用少量的对象,而这些对象都很相似,状态变化很小,可以实现对象的多次复用,由于享元模式要求能够共享的对象必须是细粒度对象,因此它又称为轻量级模式,其是一种对象结构型模式。

    描述

    面向对象技术可以很好地解决一些灵活性或可扩展性问题,但在很多情况下需要在系统中增加类和对象的个数,当对象数量太多时,将导致运行代价过高,带来性能下降等问题。享元模式正是为解决这一类问题而诞生的,享元模式通过共享技术实现相同或相似对象的重用。在享元模式中可以共享的相同内容称为内部状态IntrinsicState,而那些需要外部环境来设置的不能共享的内容称为外部状态Extrinsic State,由于区分了内部状态和外部状态,因此可以通过设置不同的外部状态使得相同的对象可以具有一些不同的特征,而相同的内部状态是可以共享的。在享元模式中通常会出现工厂模式,需要创建一个享元工厂来负责维护一个享元池Flyweight Pool用于存储具有相同内部状态的享元对象。在享元模式中共享的是享元对象的内部状态,外部状态需要通过环境来设置。在实际使用中,能够共享的内部状态是有限的,因此享元对象一般都设计为较小的对象,它所包含的内部状态较少,这种对象也称为细粒度对象,享元模式的目的就是使用共享技术来实现大量细粒度对象的复用。

    模式结构

    • Flyweight: 抽象享元类。
    • ConcreteFlyweight: 具体享元类。
    • UnsharedConcreteFlyweight: 非共享具体享元类。
    • FlyweightFactory: 享元工厂类。

    优点

    • 享元模式的优点在于它可以极大减少内存中对象的数量,使得相同对象或相似对象在内存中只保存一份。
    • 享元模式的外部状态相对独立,而且不会影响其内部状态,从而使得享元对象可以在不同的环境中被共享。

    缺点

    • 享元模式使得系统更加复杂,需要分离出内部状态和外部状态,这使得程序的逻辑复杂化。
    • 为了使对象可以共享,享元模式需要将享元对象的状态外部化,而读取外部状态使得运行时间变长。

    适用环境

    • 一个系统有大量相同或者相似的对象,由于这类对象的大量使用,造成内存的大量耗费。
    • 对象的大部分状态都可以外部化,可以将这些外部状态传入对象中。
    • 使用享元模式需要维护一个存储享元对象的享元池,而这需要耗费资源,因此应当在多次重复使用享元对象时才值得使用享元模式。

    实现

    class Tea { // 茶产品类 实例为被共用的对象
        constructor(preference){
            this.preference = preference;
        }
    }
    
    class TeaMaker { // 作为茶工厂以创建茶的实例 即享元工厂来负责维护一个享元池
        constructor(){
            this.availableTea = {};
        }
    
        make(preference) {
            this.availableTea[preference] = this.availableTea[preference] || (new Tea());
            return this.availableTea[preference];
        }
    }
    
    (function TeaShop(){
        const shop = new TeaMaker();
        var lessSugar1 = shop.make("less sugar");
        var moreMilk1 = shop.make("more milk");
        var withoutSugar1 = shop.make("without sugar");
        var lessSugar2 = shop.make("less sugar");
        var moreMilk2 = shop.make("more milk");
        var withoutSugar3 = shop.make("without sugar");
        console.log(lessSugar1 === lessSugar2); // true
        console.log(moreMilk1 === moreMilk2); // true
        console.log(withoutSugar1 === withoutSugar3); // true
    })();
    

    每日一题

    https://github.com/WindrunnerMax/EveryDay
    

    参考

    https://www.runoob.com/design-pattern/flyweight-pattern.html
    https://github.com/sohamkamani/javascript-design-patterns-for-humans#-flyweight
    https://design-patterns.readthedocs.io/zh_CN/latest/structural_patterns/flyweight.html
    
    展开全文
  • 设计模式:原型模式与享元模式

    千次阅读 2020-01-28 17:29:53
    一、原型模式 原型模式是通过给出一个原型对象来指明所创建的对象的类型,然后使用自身实现的克隆接口来复制这个原型对象,该模式就是用这种方式来创建出更多同类型的对象 原型模式是在内存二进制流的拷贝,要被直接...

    一、原型模式

    原型模式是通过给出一个原型对象来指明所创建的对象的类型,然后使用自身实现的克隆接口来复制这个原型对象,该模式就是用这种方式来创建出更多同类型的对象

    原型模式是在内存二进制流的拷贝,要被直接new一个对象性能好很多,特别是要在一个循环体内产生大量的对象时,原型模式可以更好地体现其优点

    1、实现原型模式

    //实现Cloneable接口的原型抽象类Prototype
    public class Prototype implements Cloneable {
        //重写clone()方法
        @Override
        protected Object clone() {
            Prototype prototype = null;
            try {
                prototype = (Prototype) super.clone();
            } catch (CloneNotSupportedException e) {
                e.printStackTrace();
            }
            return prototype;
        }
    }
    
    public class ConcretePrototype extends Prototype{
        public void show (){
            System.out.println("原型模型实现类");
        }
    }
    
    public class Client {
        public static void main(String[] args) {
            ConcretePrototype cp = new ConcretePrototype();
            for (int i = 0; i < 10; ++i) {
                ConcretePrototype cloneCp = (ConcretePrototype) cp.clone();
                cloneCp.show();
            }
        }
    }
    

    要实现一个原型类,需要具备三个条件

    • 实现Cloneable接口:Cloneable接口与序列化接口的作用类似,它只是告诉虚拟机可以安全地在实现了这个接口的类上使用clone()方法。在JVM中,只有实现了Cloneable接口的类才可以被拷贝,否则会抛出CloneNotSupportedException异常
    • 重写Object类中的clone()方法:在Java中,所有类的父类都是Object类,而Object类中有一个clone()方法,作用是返回对象的一个拷贝
    • 在重写的clone()方法中调用super.clone():默认情况下,类不具备复制对象的能力,需要调用super.clone()来实现

    2、原型模式的注意事项

    1)、构造函数不会被执行

    由于Object类的clone()方法的原理是从堆内存中以二进制流的方式进行拷贝,重新分配一个内存块,所以对象拷贝时构造函数不会被执行

    //实现Cloneable接口的原型抽象类Prototype
    public class Prototype implements Cloneable {
        public Prototype(){
            System.out.println("Prototype的构造函数执行了...");
        }
    
        //重写clone()方法
        @Override
        protected Object clone() {
            Prototype prototype = null;
            try {
                prototype = (Prototype) super.clone();
            } catch (CloneNotSupportedException e) {
                e.printStackTrace();
            }
            return prototype;
        }
    }
    
    public class ConcretePrototype extends Prototype{
        public ConcretePrototype(){
            System.out.println("ConcretePrototype的构造函数执行了...");
        }
    
        public void show (){
            System.out.println("原型模型实现类");
        }
    }
    
    public class Client {
        public static void main(String[] args) {
            ConcretePrototype cp = new ConcretePrototype();
            ConcretePrototype cloneCp = (ConcretePrototype) cp.clone();
        }
    }
    

    执行结果如下:

    Prototype的构造函数执行了...
    ConcretePrototype的构造函数执行了...
    

    2)、浅拷贝和深拷贝

    Object类提供的clone()方法只是拷贝本对象,其对象内部的数组、引用对象等都不拷贝,还是指向原生对象的内部元素地址,这种拷贝就叫做浅拷贝

    public class Prototype implements Cloneable {
        private List<String> list = new ArrayList<>();
    
        @Override
        protected Object clone() {
            Prototype prototype = null;
            try {
                prototype = (Prototype) super.clone();
            } catch (CloneNotSupportedException e) {
                e.printStackTrace();
            }
            return prototype;
        }
    
        public void setValue(String value) {
            this.list.add(value);
        }
    
        public List<String> getValue() {
            return this.list;
        }
    }
    
    public class Client {
        public static void main(String[] args) {
            Prototype prototype=new Prototype();
            prototype.setValue("张三");
            Prototype clonePrototype = (Prototype) prototype.clone();
            clonePrototype.setValue("李四");
            System.out.println(prototype.getValue());
        }
    }
    

    执行结果如下:

    [张三, 李四]
    

    深拷贝就是基于浅拷贝来递归实现具体的每个对象

    public class Prototype implements Cloneable {
        private ArrayList<String> list = new ArrayList<>();
    
        @Override
        protected Object clone() {
            Prototype prototype = null;
            try {
                prototype = (Prototype) super.clone();
                //ArrayList实现了Cloneable接口,List没有实现
                this.list = (ArrayList) this.list.clone();
            } catch (CloneNotSupportedException e) {
                e.printStackTrace();
            }
            return prototype;
        }
    
        public void setValue(String value) {
            this.list.add(value);
        }
    
        public List<String> getValue() {
            return this.list;
        }
    }
    

    执行结果如下:

    [张三]
    

    3、适用场景

    在一些重复创建对象的场景下,可以使用原型模式来提高对象的创建性能。例如,在循环体内创建对象时,就可以考虑用clone的方式来实现

    二、享元模式

    享元模式是运用共享技术有效地最大限度地复用细粒度对象的一种模式。该模式中,以对象的信息状态划分,可以分为内部数据和外部数据。内部数据是对象可以共享出来的信息,这些信息不会随着系统的运行而改变;外部数据则是在不同运行时被标记了不同的值

    享元模式一般可以分为三个角色,分别为 Flyweight(抽象享元类)、ConcreteFlyweight(具体享元类)和 FlyweightFactory(享元工厂类)。抽象享元类通常是一个接口或抽象类,向外界提供享元对象的内部数据或外部数据;具体享元类是指具体实现内部数据共享的类;享元工厂类则是主要用于创建和管理享元对象的工厂类

    1、实现享元模式

    //抽象享元类
    public interface Flyweight {
        //对外状态对象
        void operation(String name);
    
        //对内对象
        String getType();
    }
    
    //具体享元类
    public class ConcreteFlyweight implements Flyweight {
        private String type;
    
        public ConcreteFlyweight(String type) {
            this.type = type;
        }
    
        @Override
        public void operation(String name) {
            System.out.printf("[类型(内在状态)] - [%s] - [名字(外在状态)] - [%s]\n", type, name);
        }
    
        @Override
        public String getType() {
            return type;
        }
    }
    
    //享元工厂类
    public class FlyweightFactory {
        private static final Map<String, Flyweight> FLYWEIGHT_MAP = new HashMap<>();//享元池,用来存储享元对象
    
        public static Flyweight getFlyweight(String type) {
            if (FLYWEIGHT_MAP.containsKey(type)) {//如果在享元池中存在对象,则直接获取
                return FLYWEIGHT_MAP.get(type);
            } else {//在响应池不存在,则新创建对象,并放入到享元池
                ConcreteFlyweight flyweight = new ConcreteFlyweight(type);
                FLYWEIGHT_MAP.put(type, flyweight);
                return flyweight;
            }
        }
    }
    
    public class Client {
    
        public static void main(String[] args) {
            Flyweight fw0 = FlyweightFactory.getFlyweight("a");
            Flyweight fw1 = FlyweightFactory.getFlyweight("b");
            Flyweight fw2 = FlyweightFactory.getFlyweight("a");
            Flyweight fw3 = FlyweightFactory.getFlyweight("b");
            fw1.operation("abc");
            System.out.printf("[结果(对象对比)] - [%s]\n", fw0 == fw2);
            System.out.printf("[结果(内在状态)] - [%s]\n", fw1.getType());
        }
    }
    

    执行结果如下:

    [类型(内在状态)] - [b] - [名字(外在状态)] - [abc]
    [结果(对象对比)] - [true]
    [结果(内在状态)] - [b]
    

    如果对象已经存在于享元池中,则不会再创建该对象了,而是共用享元池中内部数据一致的对象。这样就减少了对象的创建,同时也节省了同样内部数据的对象所占用的内存空间

    2、适用场景

    享元模式在实际开发中的应用也非常广泛。例如Java的String字符串,在一些字符串常量中,会共享常量池中字符串对象,从而减少重复创建相同值对象,占用内存空间。代码如下:

            String s1 = "hello";
            String s2 = "hello";
            System.out.println(s1 == s2);//true
    

    还有,在日常开发中的应用。例如,线程池就是享元模式的一种实现;将商品存储在应用服务的缓存中,那么每当用户获取商品信息时,则不需要每次都从redis缓存或者数据库中获取商品信息,并在内存中重复创建商品信息了

    单例模式和享元模式都是为了避免重复创建对象,你知道这两者的区别在哪儿吗?

    首先,这两种设计模式的实现方式是不同的。我们使用单例模式是避免每次调用一个类实例时,都要重复实例化该实例,目的是在类本身获取实例化对象的唯一性;而享元模式则是通过一个共享容器来实现一系列对象的共享

    其次,两者在使用场景上也是有区别的。单例模式更多的是强调减少实例化提升性能,因此它一般是使用在一些需要频繁创建和销毁实例化对象,或创建和销毁实例化对象非常消耗资源的类中

    例如,连接池和线程池中的连接就是使用单例模式实现的,数据库操作是非常频繁的,每次操作都需要创建和销毁连接,如果使用单例,可以节省不断新建和关闭数据库连接所引起的性能消耗。而享元模式更多的是强调共享相同对象或对象属性,以此节约内存使用空间

    除了区别,这两种设计模式也有共性,单例模式可以避免重复创建对象,节约内存空间,享元模式也可以避免一个类的重复实例化。总之,两者很相似,但侧重点不一样,假如碰到一些要在两种设计模式中做选择的场景,我们就可以根据侧重点来选择

    参考:

    极客时间专栏《Java性能调优实战》

    《设计模式之禅》

    展开全文
  • 享元模式的分析以及实际应用 1.前言 4 1.1 课题的研究背景 4 1.2 课题主要研究目标 4 2.相关技术简介 4 2.1Java简介 4 3. 享元模式介绍 5 3.1举例分析 5 3.2基本介绍 5 3.3享元模式的具体角色 5 4. 享元模式之借书...
  • 享元模式.md

    2019-08-18 18:21:30
    这是一个设计模式,原型模式(Prototype Pattern)是用于创建重复的对象,同时又能保证性能。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 49,923
精华内容 19,969
关键字:

享元模式