实验内容:
楚锋软件公司欲基于Java 语言开发一套图表库,该图表库可以为应用系统提供各种不同外观的图表,例如柱状图、饼状图、折线图等。楚锋软件公司图表库设计人员希望为应用系统开发人员提供一套灵活易用的图表库,而且可以较为方便地对图表库进行扩展,以便能够在将来增加一些新类型的图表。
楚锋软件公司图表库设计人员提出了一个初始设计方案,将所有图表的实现代码封装在一个Chart类中,其框架代码如下:
客户端代码通过调用 Chart 类的构造函数来创建图表对象,根据参数 type 的不同可以得到不同类型的图表,然后再调用 display() 方法来显示相应的图表。
不难看出,Chart 类是一个“巨大的”类,在该类的设计中存在以下几个问题:
(1)在 Chart 类中包含很多“if···else..”代码块,整个类的代码相当冗长,代码越长,阅读难度、维护难度和测试难度也越大;而且大量条件语句的存在还将影响系统的性能,程序在执行过程中需要做大量的条件判断。
(2)Chart 类的职责过重,它负责初始化和显示所有的图表对象,将各种图表对象的初始化代码和显示代码集中在一个类中实现,违反了单一职责原则,不利于类的重用和维护,而且将大量的对象初始化代码都写在构造函数中将导致构造函数非常庞大,对象在创建时需要进行条件判断,降低了对象创建的效率。
(3)当需要增加新类型的图表时,必须修改 Chart 类的源代码违反了开闭原则。
(4)客户端只能通过 new 关键字来直接创建 Chart 对象,Chart 类与客户端类合度较高,对象的创建和使用无法分离。
(5)客户端在创建 Chart 对象之前可能还需要进行大量初始化设置,例如设置柱状图的颜色、高度等,如果在 Chart 类的构造函数中没有提供一个默认设置,那就只能由客户端来完成初始设置,这些代码在每次创建 Chart 对象时都会出现,导致代码的重复。
面对上面的设计,请使用简单工厂模式对上面的代码进行重构。请给出设计类图,以及对应的 Java 代码(包括客户端的调用代码)
实验解析:
(1)UML类图
(2)Java代码:
public interface Chart {public void display();
}public class HistogramChart implements Chart {public HistogramChart(){System.out.println("创建柱状图。");}public void display(){System.out.println("显示柱状图!");}
}public class PieChart implements Chart {public PieChart(){System.out.println("创建饼状图。");}public void display(){System.out.println("显示饼状图!");}
}public class LineChart implements Chart {public LineChart(){System.out.println("创建折线图。");}public void display(){System.out.println("显示折线图!");}
}public class ChartFactory {//静态工厂方法public static Chart createChart(String args){Chart chart = null;if (args.equalsIgnoreCase("histogram")){chart = new HistogramChart();System.out.println("初始化设置柱状图!");}else if (args.equalsIgnoreCase("pie")){chart = new PieChart();System.out.println("初始化设置饼状图!");}else if (args.equalsIgnoreCase("line")){chart = new LineChart();System.out.println("初始化设置折线图!");}return chart;}
}public class Client {public static void main(String[] args) {Chart chart=ChartFactory.createChart("histogram");chart.display();}
}