# -*- coding: utf-8 -*-

'''
设计说明
策略模式：定义 Tokenizer 接口，允许不同分词策略（如中文分词、英文分词）。
工厂模式：TokenizerFactory 创建分词器，隔离具体实现。
解耦：数据读取（DataReader）、词频统计（WordCounter）、结果输出（ResultPrinter）分离，各自独立。
可扩展：支持添加新分词策略或输出格式。

解耦：
DataReader 只负责读取文件，与分词和统计无关。
WordCounter 依赖抽象的 Tokenizer，不关心具体分词实现。
ResultPrinter 只处理输出，格式可扩展（如输出到文件）。

策略模式：
Tokenizer 接口允许切换分词策略（如添加英文分词器）。
ChineseTokenizer 是具体实现，易于替换。

工厂模式：
TokenizerFactory 封装分词器创建逻辑，调用方无需知道具体类。

简洁性：代码结构清晰，模块职责单一。

扩展性：
可添加新分词器（如英文 EnglishTokenizer）。
可扩展 ResultPrinter 支持不同输出格式。

实践：可尝试添加英文分词器或新输出格式（如 CSV）。
'''

import os
import jieba
from collections import Counter
from abc import ABC, abstractmethod
from typing import List, Dict

# 策略接口：分词器
class Tokenizer(ABC):
    @abstractmethod
    def tokenize(self, text: str) -> List[str]:
        pass

# 具体策略：中文分词（使用 jieba）
class ChineseTokenizer(Tokenizer):
    def tokenize(self, text: str) -> List[str]:
        return [word for word in jieba.cut(text) if word.strip()]

# 工厂：创建分词器
class TokenizerFactory:
    @staticmethod
    def create_tokenizer(language: str = "chinese") -> Tokenizer:
        if language == "chinese":
            return ChineseTokenizer()
        raise ValueError(f"Unsupported language: {language}")

# 数据读取模块
class DataReader:
    def __init__(self, directory: str):
        self.directory = directory

    def read_texts(self) -> List[str]:
        texts = []
        for filename in os.listdir(self.directory):
            if filename.endswith(".txt"):
                with open(os.path.join(self.directory, filename), "r", encoding="utf-8") as f:
                    texts.append(f.read())
        return texts

# 词频统计模块
class WordCounter:
    def __init__(self, tokenizer: Tokenizer):
        self.tokenizer = tokenizer

    def count_words(self, texts: List[str]) -> Dict[str, int]:
        word_counts = Counter()
        for text in texts:
            words = self.tokenizer.tokenize(text)
            word_counts.update(words)
        return dict(word_counts)

# 结果输出模块
class ResultPrinter:
    @staticmethod
    def print_top_words(word_counts: Dict[str, int], top_n: int = 10):
        top_words = sorted(word_counts.items(), key=lambda x: x[1], reverse=True)[:top_n]
        for word, count in top_words:
            print(f"{word}: {count}")

# 主程序
def main():
    # 配置
    data_dir = "data"
    top_n = 10

    # 创建组件
    reader = DataReader(data_dir)
    tokenizer = TokenizerFactory.create_tokenizer("chinese")
    counter = WordCounter(tokenizer)
    printer = ResultPrinter()

    # 执行流程
    texts = reader.read_texts()
    word_counts = counter.count_words(texts)
    printer.print_top_words(word_counts, top_n)

if __name__ == "__main__":
    main()