在常见的编程结构中,我已经看到了例如。
class Showframe
{
psvm(String args[])
{
Artframe artframe = new Artframe(new Drawing());
//some commands
}
}
class Artframe extends JFrame
{
Drawing drawing;
public Artframe(Drawing drawing)
{ this.drawing = drawing; }
//some commands
}
class Drawing
{
//some things over here
}
我想知道我们为什么要这样做? 为什么不呢
绘图类同上
在 ShowFrame 中
而不是 :Artframe artframe = new Artframe(new Drawing());
我们写:
艺术框架艺术框架 = 新艺术框架();
并将 Artframe 类的构造函数更改为:
绘图 = 新绘图();
我的意思是我们为什么不这样做??这有什么问题,为什么它被认为是糟糕的编程实践?
让我们单独看一下你的Artframe
类:
public Artframe(Drawing drawing)
{ this.drawing = drawing; }
和
public Artframe()
{ this.drawing = new Drawing(); }
实际上具有不同的语义。
第一个使用您将从客户端传递的任何现有绘图创建一个新的艺术框架。第二个创建一个新的艺术框架,其中包含一个新的(空的?)绘图。
第二个不一定(但仍然可能)糟糕的设计,如果这些语义是你的要求并且符合"更大的图景"。
在大多数情况下,由于几个原因,第一个将是更好的设计(我会对您的整体架构进行一些猜测):
- 职责分离/单一责任/高凝聚力:
Artframe
类的工作是制定Drawing
。这应该是它唯一的工作。决定要框框的图纸已经是第二项工作。 - 可重用性:您无法将框架用于现有图形。
- 松耦合:您通常会使用接口来设计它。这使您可以轻松使用不同的实现。第二个版本硬连线("耦合")到特定实现。
假设您要创建打印任何名称的问候语的简单类:
public class Greeting {
private final String name;
public Greetings(String name) {
this.name = name;
}
public void printHello() {
System.out.println("Hello " + name + "!");
}
}
当你通过String s = "World"
时,结果将是"Hello World!"
。这样,您可以更改Greeting
类的行为。如果类Greeting
如下所示:
public class Greeting {
public void printHello() {
System.out.println("Hello java!");
}
}
没有任何选择如何更改此问候语。
这同样适用于类Artframe
和Drawing
。Artframe
只显示您提供的内容。请注意,以下代码片段无法编译,因为它们使用不存在的图形上下文、方法......
interface Drawing {
void paintTo(Canvas c);
}
class Artframe extends JFrame {
Drawing drawing;
public Artframe(Drawing drawing) {
this.drawing = drawing;
}
protected void paint(Canvas c) {
drawing.paintTo(c);
}
}
绘图可以通过多种方式实现,例如,一个实现绘制到图形上下文圆,另一个绘制矩形,....
public CircleDrawing implements Drawing {
Point centerPoint = new Point(0,0);
int radius = 5;
int strokeWidth = 1;
public void paintTo(Canvas c) {
c.drawCircle(centerPoint, radius, strokeWidth);
}
}
public RectangleDrawing implements Drawing {
Point topLeft = new Point(0,0);
Dimension dim = new Dimension(100, 50);
int strokeWidth = 1;
public void paintTo(Canvas c) {
c.drawRect(topLeft , dim, strokeWidth);
}
}
要在Artframe
中显示圆圈,您只需传递CircleDrawing
实例:
new Artframe(new CircleDrawing());
如果需要显示矩形,则:
new Artframe(new RectangleDrawing());
同样,如果你的Artframe
类没有Drawing
依赖关系,即使用的绘图将被硬编码到Artframe
中,那么你将无法改变它的行为 - 显示将始终是相同的Drawing
:
class Artframe extends JFrame {
Drawing drawing = new RectangleDrawing();
protected void paint(Canvas c) {
drawing.paintTo(c);
}
}