在Java中开放封闭原则
在本教程中,我们将在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报告。

