某文字编辑软件需提供如下功能:在文本编辑窗口中包含一个可编辑文本区和3个文本信息统计区。用户可以在可编辑文本区对文本进行缩辑操作,第一个文本信息统计区用于显示可编辑文本区中出现的单词总数量和字符总数量,第二个文本信息统计区用于显示可编辑文本区中出现的单词(去重后按照字典序排序),第三个文本信息统计区用于按照出频次降序显示可编辑文本区中出现的单词以及每个单词出现的次数(例如 hello,5)。现采用观察者模式设计该功能。绘制对应的类图并编程模拟实现
时间: 2024-01-22 14:17:41 浏览: 383
14_【文本编辑器】三、文本编辑功能1
以下是该软件的观察者模式类图:
![观察者模式类图](observer_pattern.png)
其中,Subject 是被观察者接口,定义了注册、注销和通知观察者的方法。ConcreteSubject 是具体的被观察者类,实现了 Subject 接口,并维护了一个观察者列表。TextEditor 是具体的可编辑文本类,实现了可编辑文本区的相关操作,并且是一个具体的被观察者。Observer 是观察者接口,定义了更新的方法。WordCounter、WordSorter 和 WordFrequencyCounter 是具体的观察者类,实现了 Observer 接口,分别负责计算单词总数和字符总数、按照字典序排序单词、以及统计单词出现频次并按照降序排列。
以下是对应的代码实现:
```java
import java.util.*;
// 被观察者接口
interface Subject {
void registerObserver(Observer observer);
void removeObserver(Observer observer);
void notifyObservers();
}
// 具体的被观察者类:可编辑文本类
class TextEditor implements Subject {
private String text; // 可编辑文本区的文本内容
private List<Observer> observers; // 观察者列表
public TextEditor(String text) {
this.text = text;
this.observers = new ArrayList<>();
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
notifyObservers(); // 当文本内容改变时,通知所有观察者更新
}
@Override
public void registerObserver(Observer observer) {
observers.add(observer);
}
@Override
public void removeObserver(Observer observer) {
observers.remove(observer);
}
@Override
public void notifyObservers() {
for (Observer observer : observers) {
observer.update(this);
}
}
}
// 观察者接口
interface Observer {
void update(Subject subject);
}
// 具体的观察者类:单词总数和字符总数统计器
class WordCounter implements Observer {
private int wordCount; // 单词总数
private int charCount; // 字符总数
public WordCounter() {
this.wordCount = 0;
this.charCount = 0;
}
public int getWordCount() {
return wordCount;
}
public int getCharCount() {
return charCount;
}
@Override
public void update(Subject subject) {
TextEditor textEditor = (TextEditor) subject;
String text = textEditor.getText();
if (text == null || text.isEmpty()) {
wordCount = 0;
charCount = 0;
return;
}
String[] words = text.split("\\s+");
wordCount = words.length;
charCount = text.replaceAll("\\s+", "").length();
}
}
// 具体的观察者类:单词字典序排序器
class WordSorter implements Observer {
private Set<String> wordSet; // 去重后的单词集合
public WordSorter() {
this.wordSet = new TreeSet<>();
}
public Set<String> getWordSet() {
return wordSet;
}
@Override
public void update(Subject subject) {
TextEditor textEditor = (TextEditor) subject;
String text = textEditor.getText();
if (text == null || text.isEmpty()) {
wordSet.clear();
return;
}
String[] words = text.split("\\s+");
wordSet = new TreeSet<>(Arrays.asList(words));
}
}
// 具体的观察者类:单词出现频次统计器
class WordFrequencyCounter implements Observer {
private Map<String, Integer> wordFrequencyMap; // 单词出现频次映射
public WordFrequencyCounter() {
this.wordFrequencyMap = new HashMap<>();
}
public Map<String, Integer> getWordFrequencyMap() {
return wordFrequencyMap;
}
@Override
public void update(Subject subject) {
TextEditor textEditor = (TextEditor) subject;
String text = textEditor.getText();
if (text == null || text.isEmpty()) {
wordFrequencyMap.clear();
return;
}
String[] words = text.split("\\s+");
wordFrequencyMap = new HashMap<>();
for (String word : words) {
wordFrequencyMap.put(word, wordFrequencyMap.getOrDefault(word, 0) + 1);
}
wordFrequencyMap = sortByValue(wordFrequencyMap);
}
// 按照值(出现次数)降序排列 Map
private static <K, V extends Comparable<? super V>> Map<K, V> sortByValue(Map<K, V> map) {
List<Map.Entry<K, V>> list = new ArrayList<>(map.entrySet());
Collections.sort(list, (o1, o2) -> o2.getValue().compareTo(o1.getValue()));
Map<K, V> result = new LinkedHashMap<>();
for (Map.Entry<K, V> entry : list) {
result.put(entry.getKey(), entry.getValue());
}
return result;
}
}
public class TextEditorApp {
public static void main(String[] args) {
TextEditor textEditor = new TextEditor("");
WordCounter wordCounter = new WordCounter();
WordSorter wordSorter = new WordSorter();
WordFrequencyCounter wordFrequencyCounter = new WordFrequencyCounter();
textEditor.registerObserver(wordCounter);
textEditor.registerObserver(wordSorter);
textEditor.registerObserver(wordFrequencyCounter);
// 初始状态下所有计数器的结果应该都是 0
System.out.println("Word count: " + wordCounter.getWordCount());
System.out.println("Char count: " + wordCounter.getCharCount());
System.out.println("Word set: " + wordSorter.getWordSet());
System.out.println("Word frequency map: " + wordFrequencyCounter.getWordFrequencyMap());
textEditor.setText("The quick brown fox jumps over the lazy dog.");
// 设置文本后,所有计数器的结果应该发生变化
System.out.println("Word count: " + wordCounter.getWordCount());
System.out.println("Char count: " + wordCounter.getCharCount());
System.out.println("Word set: " + wordSorter.getWordSet());
System.out.println("Word frequency map: " + wordFrequencyCounter.getWordFrequencyMap());
}
}
```
阅读全文