简体   繁体   English

java中的享元设计模式,目的是什么?

[英]Flyweight design pattern in java, what is the purpose?

I have the following code:我有以下代码:

public class Sentence {

    private String [] words;
    private Map<Integer, WordToken> tokens = new HashMap<>();

    public Sentence(String plainText) {
        words = plainText.split(" ");
    }

    public WordToken getWord(int index) {
        WordToken wt = new WordToken();
        tokens.put(index, wt);
        return tokens.get(index);
    }

    @Override
    public String toString() {
        List<String> ws = new ArrayList<>();
        for (int i = 0; i < words.length; ++i) {
            String w = words[i];
            if (tokens.containsKey(i) && tokens.get(i).capitalize) {
                w = w.toUpperCase();
            }
            ws.add(w);
        }
        return String.join(" ", ws);
    }
}

and test:并测试:

@Test
public void test() {
    Sentence s = new Sentence("alpha beta gamma");
    s.getWord(1).capitalize = true;
    assertEquals("alpha BETA gamma", s.toString());
}

My question is: what is the purpose of use flyweight pattern in that way?我的问题是:以这种方式使用享元模式的目的是什么?

The Flyweight Pattern is a re-use pattern that reduces the memory footprint of a program by re-using identical objects. Flyweight 模式是一种重用模式,它通过重用相同的对象来减少程序的内存占用。 This is common with value objects , which represent simple values, such as words, since words with the same characters are identical.这对于表示简单值(例如单词)的值对象很常见,因为具有相同字符的单词是相同的。 For example, suppose we have the following sentence (ignore capitalization for now):例如,假设我们有以下句子(暂时忽略大小写):

the doorman held the door for the guest

This sentence has 39 characters, which means that if we created a String from this sentence, we would need to store 39 characters (ignore the length field used by the Java String implementation for now).这句话有 39 个字符,这意味着如果我们从这句话创建一个String ,我们将需要存储 39 个字符(暂时忽略 Java String实现使用的length字段)。 If we look at the sentence, there are 3 instances of the , which are identical to one another.如果我们看一下这句话,也有3个实例the ,它们彼此相同。 There are also 7 spaces, which are identical to one another.还有7个空格,它们彼此相同。 If we tokenized the string, we would obtain the following words:如果我们对字符串进行标记,我们将获得以下单词:

["the", "doorman", "held", "the", "door", "for", "the", "guest"]

If we take only the unique values in this list, we obtain:如果我们只取这个列表中的唯一值,我们得到:

["the", "doorman", "held", "door", "for", "guest"]

Using these unique words, we could create the sentence by mapping the indexes of the word in the sentence to the unique words:使用这些独特的词,我们可以通过将句子中的词的索引映射到独特的词来创建句子:

[0, 1, 2, 0, 3, 4, 0, 5]

To reconstruct the sentence, we would simple map the indices above to the list of unique words, adding a space between each of the words.为了重建句子,我们将上面的索引简单地映射到唯一词的列表,在每个词之间添加一个空格。

In the case of the example you provided, it appears that the algorithm is incorrect (it does not save any space, since it stores both the words and the tokens).在您提供的示例中,该算法似乎不正确(它不节省任何空间,因为它同时存储了单词和标记)。 A more correct solution (one of many) would resemble):更正确的解决方案(众多解决方案之一)类似于):

public class Sentence {

    private final List<Integer> wordMap = new ArrayList<>();
    private final List<String> words = new ArrayList<>();

    public Sentence(String sentence) {
        for (String word: sentence.split(" ")) {
            addIfNotExists(word);
            wordMap.add(words.indexOf(word));
        }
    }

    private void addIfNotExists(String word) {

        if (!words.contains(word)) {
            words.add(word);
        }
    }

    public List<Integer> getWordMap() {
        return wordMap;
    }

    public List<String> getWords() {
        return words;
    }

    public static void main(String[] args) {
        Sentence s = new Sentence("the doorman held the door for the guest");
        System.out.println(s.getWordMap());
        System.out.println(s.getWords());
    }
}

Running this results in the following output:运行此结果会产生以下输出:

[0, 1, 2, 0, 3, 4, 0, 5]
[the, doorman, held, door, for, guest]

I left it to you to implement the toString method.我把它留给你来实现toString方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM