适用于报告系统的设计模式

时间:2017-07-13 12:59:52

标签: java oop design-patterns

在方法main中,我有String page,其中包含一些大文本,以及此类代码:

List<String> wordsList = getWordsList(page);
System.out.println("Total number of words is: " + wordsList.size());

Map<String, Long> wordsSortedMap = getWordsSortedMap(wordsList);
wordsSortedMap.forEach((k, v) -> System.out.println(v + "\t" + k));

如您所见,我只使用util方法getWordsListgetWordsSortedMap来构建所需数据并将其打印到控制台。

我希望更改程序可以扩展,以便能够在不更改现有代码的情况下添加新类型的报告。

例如,输入数据始终是此page变量。例如,main可以是这样的:

ReportsExecutor.printReportOne(page);
ReportsExecutor.printReportTwo(page);

或者这个:

ReportOne reportOne = new ReportOne(page);
ReportTwo reportTwo = new ReportTwo(page);
reportOne.execute();
reportTwo.execute();

因此,要添加新的报告类型,我只需实现新的方法或类等。

对于这种情况,是否有合适的设计模式或任何OOP最佳实践?

1 个答案:

答案 0 :(得分:1)

由于我强烈的观点是你的问题主要是关于OOP,我将在C#中做一个例子(因为我最精通)。

我们的想法是使用Builder和Visitor模式的组合来处理报告。

首先,我已经定义了Report类,如下所示(非常原始):

public interface IReport
{
    void Print();
}

public class Report : IReport
{
    private readonly IList<string> lines;

    public Report()
    {
        lines = new List<string>();
    }

    public void AddLine(string line)
    {
        lines.Add(line);
    }
    public void Print()
    {
        foreach (var l in lines) Console.Out.WriteLine(l);
    }
}

然后我定义了构建器的接口:

public interface IReportBuilder
{
    void Execute();
    IReport Product { get; }
}

和符合我们需求的访客:

public interface IWordVisitor
{
    void VisitWord(string word);
}

页面统计信息的实现如下:

public class PageStatisticVisitor : IWordVisitor
{
    private readonly IDictionary<string, long> stats;

    public PageStatisticVisitor()
    {
        stats = new Dictionary<string, long>();
    }

    public IDictionary<string, long> Stats { get { return stats; } }

    public void VisitWord(string word)
    {
        long currentStat;
        if (stats.TryGetValue(word, out currentStat)) currentStat++;
        else currentStat = 1;
        stats[word] = currentStat;
    }
}

(只计算文本中相同的单词)。

我将页面内容封装到现在访问者的Page类中:

 public class Page
{
    private string pageContent;
    public Page(string content)
    {
        pageContent = content;
    }

    public void Accept(IWordVisitor visitor)
    {
        foreach (var w in pageContent.Split())
        {
            visitor.VisitWord(w);
        }
    }
}

单词统计报告构建器:

public class WordStatisticsBuilder : IReportBuilder
{
    private Report report;
    private Page page;

    public WordStatisticsBuilder(Page page)
    {
        report = new Report();
        this.page = page;
    }

    public void Execute()
    {
        var psv = new PageStatisticVisitor();
        page.Accept(psv);            
        foreach (var s in psv.Stats)
        {
            report.AddLine(string.Format("{0} : {1}", s.Key, s.Value));
        }
    }

    public IReport Product
    {
        get { return report; }
    }
}

用法:

var page = new Page(
                "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.");

        var statistics = new WordStatisticsBuilder(page);
        statistics.Execute();

        statistics.Product.Print();

我希望你有一个想法并且可以在JAva中实现它。

相关问题