在Java中开放封闭原则

时间:2020-02-23 14:35:29  来源:igfitidea点击:

在本教程中,我们将在java.open内学习开放的封闭设计原理是封闭原则是一个坚实的原则之一。

开放的封闭设计原则决定了"软件实体(类,模块,函数等)应打开扩展,但关闭修改"。
该定义由Bertrand Meyer提供。

一旦我们写了这个程序并测试了它,它就不应该再次修改,但它应该打开扩展。
如果我们修改已经测试了,可能会导致大量的另外努力测试它,也可能有机会用于引入新错误。

策略设计模式是开放封闭设计原理的另一个例子。
服务类可以使用各种策略根据要求执行某些任务,因此我们将保留服务类关闭但同时,通过引入将实现战略接口的新策略开放。
在运行时,根据需要,我们可以使用任何新策略调用服务类。

让我们在一个简单的例子的帮助下了解。
我们需要根据输入类型创建两种类型(CSV和XML)的报告。
请注意,应提供将来添加新的报告类型。

创建名为"reporttype.java"的枚举,如下所示。

package org.igi.theitroad;
public enum ReportingType {
	CSV,XML;
}

创建服务类名为ReportingService,如下所示:

package org.igi.theitroad;
 
public class ReportingService {
 
	public void generateReportBasedOnType(ReportingType reportingType)
	{
		System.out.println("===================================");
		System.out.println("Generating report based on Type");
		System.out.println("===================================");
		
		if("CSV".equalsIgnoreCase(reportingType.toString()))
		{
			generateCSVReport();
		}
		else if("XML".equalsIgnoreCase(reportingType.toString()))
		{
			generateXMLReport();
		}
	}
	
	private void generateCSVReport()
	{
		System.out.println("Generate CSV Report");
	}
	
	private void generateXMLReport()
	{
		System.out.println("Generate XML Report");
	}
}

创建一个名为"generatereportmain.java"的主类,该类将称为ReportingService来生成报表。

package org.igi.theitroad;
 
public class GenerateReportMain {
 
	public static void main(String[] args) {
		ReportingService rs=new ReportingService();
		
		//Generate CSV file
		rs.generateReportBasedOnType(ReportingType.CSV);
		
		System.out.println();
		
		//Generate XML file
		rs.generateReportBasedOnType(ReportingType.XML);
		
	}
 
}

输出:

===================================
Generating report based on Type
===================================
Generate CSV Report
===================================
Generating report based on Type
===================================
Generate XML Report

正如我们所看到的,这是一个简单的代码,正好工作。
我们已经测试了代码,并发现我们能够根据类型生成报表。
现在,我们需要创建一个更长的报告类型:Excel.if我们注意,如果我们需要更改如下:1)我们需要在Enum ReportingType中进行更改。

package org.igi.theitroad;
public enum ReportingType {
	CSV,XML,EXCEL;
}

2)我们需要在已测试的ReportingService类中进行更改。

package org.igi.theitroad;
 
public class ReportingService {
 
	public void generateReportBasedOnType(ReportingType reportingType)
	{
		System.out.println("===================================");
		System.out.println("Generating report based on Type");
		System.out.println("===================================");
		
		if("CSV".equalsIgnoreCase(reportingType.toString()))
		{
			generateCSVReport();
		}
		else if("XML".equalsIgnoreCase(reportingType.toString()))
		{
			generateXMLReport();
		}
		else if("Excel".equalsIgnoreCase(reportingType.toString()))
		{
			generateExcelReport();
		}
	}
	
	private void generateCSVReport()
	{
		System.out.println("Generate CSV Report");
	}
	
	private void generateXMLReport()
	{
		System.out.println("Generate XML Report");
	}
	
	private void generateExcelReport() {
		System.out.println("Generate Excel Report");
	}
}

现在,我们可以生成如下的Excel报告。

package org.igi.theitroad;
 
public class GenerateReportMain {
 
	public static void main(String[] args) {
		ReportingService rs=new ReportingService();
		
		//Generate CSV file
		rs.generateReportBasedOnType(ReportingType.CSV);
		
		System.out.println();
		
		//Generate XML file
		rs.generateReportBasedOnType(ReportingType.XML);
		
		System.out.println();
		
		//Generate Excel file
		rs.generateReportBasedOnType(ReportingType.EXCEL);		
	}
}

输出:

===================================
Generating report based on Type
===================================
Generate CSV Report
===================================
Generating report based on Type
===================================
Generate XML Report
===================================
Generating report based on Type
===================================
Generate Excel Report

正如我们所看到的,我们必须在许多我们已经测试的地方修改,我们需要再次重新测试所有函数。

开放的封闭设计原则

让我们看看开放的封闭设计原则如何能够解决问题。
创建ReportingService.java如下。

package org.igi.theitroad;
 
public class ReportingService {
 
	public void generateReportBasedOnStrategy(ReportingStrategy reportingStrategy)
	{
		System.out.println("===================================");
		System.out.println("Generating report based on Strategy");
		System.out.println("===================================");
		
		reportingStrategy.generateReport();
		System.out.println();
	}
}

创建一个名为ReportingStrategy的接口,如下所示。

package org.igi.theitroad;
 
public interface ReportingStrategy {
	 void generateReport();
}

创建一个名为"csvreportingstreate.java"的类,用于生成CSV报告

package org.igi.theitroad;
 
public class CSVReportingStrategy implements ReportingStrategy {
 
	@Override
	public void generateReport() {
		System.out.println("Generate CSV Report");
	}
}

创建一个名为"xmlreportingstreate.java"的类,用于生成XML报告

package org.igi.theitroad;
 
public class XMLReportingStrategy implements ReportingStrategy {
 
	@Override
	public void generateReport() {
		System.out.println("Generate XML Report");
	}
}

让我们现在创建一个主类WenerateReportMain.java。

package org.igi.theitroad;
 
public class GenerateReportMain {
 
	public static void main(String[] args) {
		ReportingService rs=new ReportingService();
 
		//Generate CSV report
		ReportingStrategy csvReportingStrategy=new CSVReportingStrategy();
		rs.generateReportBasedOnStrategy(csvReportingStrategy);
 
		//Generate XML report
		ReportingStrategy xmlReportingStrategy=new XMLReportingStrategy();
		rs.generateReportBasedOnStrategy(xmlReportingStrategy);
	}
}

输出:

===================================
Generating report based on Type
===================================
Generate CSV Report
===================================
Generating report based on Type
===================================
Generate XML Report

假设我们想生成Excel报告。
我们需要创建以下更改:创建另一个名为"ExcelReportingstrate.java"的类。

package org.igi.theitroad;
 
public class ExcelReportingStrategy implements ReportingStrategy {
 
	@Override
	public void generateReport() {
		System.out.println("Generate Excel Report");
	}
}

更改WenerateReportMain.java以添加调用代码。

package org.igi.theitroad;
 
public class GenerateReportMain {
 
	public static void main(String[] args) {
		ReportingService rs=new ReportingService();
 
		//Generate CSV report
		ReportingStrategy csvReportingStrategy=new CSVReportingStrategy();
		rs.generateReportBasedOnStrategy(csvReportingStrategy);
 
		//Generate XML report
		ReportingStrategy xmlReportingStrategy=new XMLReportingStrategy();
		rs.generateReportBasedOnStrategy(xmlReportingStrategy);
 
		//Generate Excel report
		ReportingStrategy ExcelReportingStrategy=new ExcelReportingStrategy();
		rs.generateReportBasedOnStrategy(ExcelReportingStrategy);
 
	}
}

输出:

===================================
Generating report based on Strategy
===================================
Generate CSV Report
===================================
Generating report based on Strategy
===================================
Generate XML Report
===================================
Generating report based on Strategy
===================================
Generate Excel Report

正如我们所看到的,我们没有制作已经测试的任何更改报告服务。
我们只是添加了新的"ExcelReportingStrategy",它使我们能够生成Excel报告。