栏目分类:
子分类:
返回
终身学习网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
终身学习网 > IT > 软件开发 > 后端开发 > .Net

设计模式-享元模式

.Net 更新时间:发布时间: 百科书网 趣学号
1、概念
FlyWeight是”轻量级“的意思,指的是拳击比赛中选手体重最轻的等级。顾名思义,该设计模式的作用是为了让对象变”轻“。

对象在计算机中是虚拟存在的东西,它的”重“和”轻“并非指实际的重量,而是它们”所使用的内存大小“,使用内存多的就是”重对象“,使用内存少的就是”轻“对象。

在Java中,可以通过以下语句生成Something类的实例。 new Something()

为了能够在计算机中保存该对象那个,需要分配给其足够的内存空间,当程序中需要大量对象的时候,如果都使用new关键字来分配内存,将会消耗大量内存空间。

关于FlyWeight模式,就是”通过尽量共享实例来避免new出实例“。

2、示例程序

在示例程序中,有一个将普通字符组合成”大型字符“的类,它的实例就是重实例,如下图:以文本形式保存了大型字符‘0’~‘9’的字体数据。

下表展示了该示例程序中所使用的类:

  • BigCharFactory 表示生成和共用BigChar类的实例的类
  • BigChar 表示大型字符的类
  • BigString 表示多个BigChar组成的“大型字符串”的类
  • main 测试程序行为的类

BigChar类是表示大型字符的类,需要将其保存在内存中,然后使用print方法输出大型字符。大型字符会消耗大量的内存,因此我们要去考虑如何共享BigChar类的实例。

BigCharFatory类会根据需要生成BigChar类的实例,不过如果发现之前已经生成了某个大型字符的BigChar类的实例,则会直接利用该实例,而不会在生成新实例。生成的实例全部会保存在cache字段中。此外

为了能够快速查找之前是否已经生成某个大型字符所对应的实例,我们使用了HashMap类。

BigString类是用于多个BigChar组成的“大型字符串”。

Main类是用于测试程序行为的类。

下图表示示例程序的类图:

BigChar.java

package main.flyweight.bigchar;
 
import java.util.HashMap;
 
public class BigChar {
    public char charName;
    public String value;
 
 
    BigChar(char charName) {
        this.charName = charName;
        this.value = map.get("" + charName);
    }
 
    public void print() {
        System.out.println(value);
    }
 
 
    public static HashMap map = new HashMap<>();
    static {
        map.put("0", "....######......n" +
                "..##......##....n" +
                "..##......##....n" +
                "..##......##....n" +
                "..##......##....n" +
                "..##......##....n" +
                "....######......n" +
                "................");
        map.put("1", "......##........n" +
                "..######........n" +
                "......##........n" +
                "......##........n" +
                "......##........n" +
                "......##........n" +
                "..##########....n" +
                "................n");
        map.put("2", "....######......n" +
                "..##......##....n" +
                "..........##....n" +
                "......####......n" +
                "....##..........n" +
                "..##............n" +
                "..##########....n" +
                "................n");
        map.put("3", "....######......n" +
                "..##......##....n" +
                "..........##....n" +
                "......####......n" +
                "..........##....n" +
                "..##......##....n" +
                "....######......n" +
                "................n");
        map.put("4", "........##......n" +
                "......####......n" +
                "....##..##......n" +
                "..##....##......n" +
                "..##########....n" +
                "........##......n" +
                "......######....n" +
                "................n");
        map.put("5", "..##########....n" +
                "..##............n" +
                "..##............n" +
                "..########......n" +
                "..........##....n" +
                "..##......##....n" +
                "....######......n" +
                "................n");
        map.put("6", "....######......n" +
                "..##......##....n" +
                "..##............n" +
                "..########......n" +
                "..##......##....n" +
                "..##......##....n" +
                "....######......n" +
                "................n");
        map.put("7", "..##########....n" +
                "..##......##....n" +
                "..........##....n" +
                "........##......n" +
                "......##........n" +
                "......##........n" +
                "......##........n" +
                "................n");
        map.put("8", "....######......n" +
                "..##......##....n" +
                "..##......##....n" +
                "....######......n" +
                "..##......##....n" +
                "..##......##....n" +
                "....######......n" +
                "................n");
        map.put("9", "....######......n" +
                "..##......##....n" +
                "..##......##....n" +
                "....########....n" +
                "..........##....n" +
                "..##......##....n" +
                "....######......n" +
                "................n");
    }
}

BigCharFactory.java

package main.flyweight.bigchar;
 
import java.util.HashMap;
 
public class BigCharFactory {
 
    private volatile HashMap cache = new HashMap<>();
 
    private static BigCharFactory Singleton = new BigCharFactory();
 
    private BigCharFactory() {
    }
 
    public static BigCharFactory getBigCharFactory() {
        return Singleton;
    }
 
    public BigChar getBigChar(char value) {
        if (cache.containsKey("" + value)) {
            return cache.get("" + value);
        } else {
           synchronized (Singleton) {
               if (cache.containsKey("" + value)) {
                   return cache.get("" + value);
               } else {
                   BigChar bigChar = new BigChar(value);
                   cache.put("" + value, bigChar);
                   return bigChar;
               }
            }
        }
    }
}

BigString.java

package main.flyweight;
 
import main.flyweight.bigchar.BigChar;
import main.flyweight.bigchar.BigCharFactory;
 
public class BigString {
 
    public String value;
 
    private BigChar[] detail;
 
    public BigString(String value) {
        this.value = value;
        this.detail = new BigChar[value.length()];
        BigCharFactory factory = BigCharFactory.getBigCharFactory();
        for (int i = 0; i < value.length(); i++) {
            this.detail[i] =  factory.getBigChar(value.charAt(i));
        }
    }
 
    public void print(){
        for (int i = 0; i < detail.length; i++) {
            detail[i].print();
        }
    }
 
 
}

main.java

package main.flyweight;
 
public class Main {
 
    public static void main(String[] args) {
        BigString bigString1 = new BigString("117643");
        bigString1.print();
        System.out.println();
 
        BigString bigString2 = new BigString("5200");
        bigString2.print();
        System.out.println();
 
        BigString bigString3 = new BigString("52000");
        bigString3.print();
        System.out.println();
 
        BigString bigString = new BigString("2500");
    }
}

字符串“1212123”对应的BigString类实例的样子:

3、享元模式中的角色

FlyWeight(轻量级):按照通常方式编写程序会导致程序变重,所以如果能够共享实例会比较耗,而FlyWeight角色表示的就是那些实例会被共享的类,在示例程序中,由BigChar类来扮演此角色。

FlyWeightFactory(轻量级工厂):FlyWeightFactory角色是生成FlyWeight角色的工厂。在工厂中生成FlyWeight角色可以实现共享实例。在示例程序中,由BigCharFactory类扮演此角色。

Client(请求者):Client角色使用FlyWeightFactory角色来生成FlyWeight角色。在示例程序中,由BigString来扮演此角色。

4、拓展

FlyWeight模式的主题是“共享”,那么在共享实例的时候应当注意什么?

区分Intrinsic State信息和Extrinsic State信息

应该共享的信息被称作Intrinsic信息,Intrinsic 的意思是“本质的、固有的”。在我们示例的程序中,BigChar的字体数据不论在BigString中的哪个地方都不会改变。因此BigChar表示的信息就是Intrinsic信息。

不应该共享的信息被称作Extrinsic信息。Extrinsic的意思是“外在的,非本质的”。在示例程序中,BigChar的实例在BigString中的第几个字符这种信息会根据BigString重中的位置变化而变化,所以不应该在BigChar中保存这个信息,它属于Extrinsic信息。

转载请注明:文章转载自 www.051e.com
本文地址:http://www.051e.com/it/985296.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 ©2023-2025 051e.com

ICP备案号:京ICP备12030808号