And*_*scu 8 oop refactoring god-object
我有一个名为Parameters的对象,它跨越包边界从方法到方法向下和向上抛出调用树.它有大约五十个状态变量.每种方法可能使用一个或两个变量来控制其输出.
我认为这是一个坏主意,因为我不能轻易看到方法需要运行什么,甚至如果模块Y的某些参数组合与我当前的模块完全无关,可能会发生什么.
有什么好的技术可以减少与这个神对象的耦合,或者理想地消除它?
public void ExporterExcelParFonds(ParametresExecution parametres)
{
ApplicationExcel appExcel = null;
LogTool.Instance.ExceptionSoulevee = false;
bool inclureReferences = parametres.inclureReferences;
bool inclureBornes = parametres.inclureBornes;
DateTime dateDebut = parametres.date;
DateTime dateFin = parametres.dateFin;
try
{
LogTool.Instance.AfficherMessage(Variables.msg_GenerationRapportPortefeuilleReference);
bool fichiersPreparesAvecSucces = PreparerFichiers(parametres, Sections.exportExcelParFonds);
if (!fichiersPreparesAvecSucces)
{
parametres.afficherRapportApresGeneration = false;
LogTool.Instance.ExceptionSoulevee = true;
}
else
{
Run Code Online (Sandbox Code Playgroud)
来电者会:
PortefeuillesReference pr = new PortefeuillesReference();
pr.ExporterExcelParFonds(parametres);
Run Code Online (Sandbox Code Playgroud)
首先,冒着陈述明显的风险:传递方法使用的参数,而不是神对象.
然而,这可能会导致某些方法需要大量参数,因为它们调用其他方法,这些方法依次调用其他方法,等等.这可能是把一切都放在上帝对象中的灵感.我将给出一个具有太多参数的这种方法的简化示例; 你必须想象"太多了"== 3这里:-)
public void PrintFilteredReport(
Data data, FilterCriteria criteria, ReportFormat format)
{
var filteredData = Filter(data, criteria);
PrintReport(filteredData, format);
}
Run Code Online (Sandbox Code Playgroud)
所以问题是,如何在不诉诸上帝对象的情况下减少参数数量?答案是摆脱程序编程并充分利用面向对象的设计.对象可以相互使用,而无需知道用于初始化其协作者的参数:
// dataFilter service object only needs to know the criteria
var dataFilter = new DataFilter(criteria);
// report printer service object only needs to know the format
var reportPrinter = new ReportPrinter(format);
// filteredReportPrinter service object is initialized with a
// dataFilter and a reportPrinter service, but it doesn't need
// to know which parameters those are using to do their job
var filteredReportPrinter = new FilteredReportPrinter(dataFilter, reportPrinter);
Run Code Online (Sandbox Code Playgroud)
现在FilteredReportPrinter.Print方法只能用一个参数实现:
public void Print(data)
{
var filteredData = this.dataFilter.Filter(data);
this.reportPrinter.Print(filteredData);
}
Run Code Online (Sandbox Code Playgroud)
顺便说一句,这种关注点和依赖注入的分离不仅仅是消除参数.如果您通过接口访问协作者对象,那么这将使您的类成为可能