适合报表系统的设计模式



在方法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 最佳实践?

由于我的强烈意见是你的问题主要是关于 OOP 的,我将用 C# 做一个例子(因为我最精通(。

这个想法是使用构建器和访问者模式的组合来处理报告。

首先,我定义了如下所示的报表类(非常原始(:

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

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

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

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中实现它。

最新更新