Шаблон проектирования навесного веса в Java, какова цель? - PullRequest
0 голосов
/ 08 января 2019

У меня есть следующий код:

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);
    }
}

и тест:

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

Мой вопрос таков: какова цель использования шаблона «мухи» таким образом?

1 Ответ

0 голосов
/ 08 января 2019

Шаблон Flyweight - это шаблон многократного использования, который уменьшает объем памяти программы путем повторного использования идентичных объектов. Это обычно для объектов значений , которые представляют простые значения, такие как слова, поскольку слова с одинаковыми символами идентичны. Например, предположим, что у нас есть следующее предложение (пока игнорируйте заглавные буквы):

the doorman held the door for the guest

Это предложение содержит 39 символов, что означает, что если бы мы создали String из этого предложения, нам нужно было бы сохранить 39 символов (игнорируйте поле length, используемое сейчас реализацией Java String). Если мы посмотрим на предложение, есть 3 случая the, которые идентичны друг другу. Есть также 7 пробелов, которые идентичны друг другу. Если бы мы маркировали строку, мы получили бы следующие слова:

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

Если мы возьмем только уникальные значения в этом списке, мы получим:

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

Используя эти уникальные слова, мы могли бы создать предложение, сопоставив индексы слова в предложении с уникальными словами:

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

Чтобы восстановить предложение, мы просто сопоставили бы приведенные выше индексы со списком уникальных слов, добавив пробел между каждым из слов.

В примере, который вы предоставили, похоже, что алгоритм некорректен (он не экономит место, так как хранит как слова, так и токены). Было бы похоже более правильное решение (одно из многих):

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());
    }
}

Запуск этого приводит к следующему выводу:

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

Я оставил вам возможность реализовать метод toString.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...