好的,最近我用Java编写了一个“绘图应用程序”。类似于MS Windows Paint的小程序,显然(根据一些评估我的源代码的人)我在我的应用程序中没有正确使用类。不幸的是,我不知道会出现什么问题,但没有人有心情告诉我什么是错误的。
我有使用继承理念的“适当”类:
PaintObject
-ClosedObject
--RectangleShape
--OvalShape
-OpenObject
--PointShape
--LineShape
但我仍然不知道代码中可能出现什么问题,可能会导致认为类没有正确使用......
(在我看来)唯一可能出错的事情就是通过创建新对象来绘制,例如:new RectagleObject(...)
和new OvalShape(...)
而不是创建一个字段objectToBeDrawn
变量(可能是PaintObject
类型),然后在调用方法executeOperation
时为其指定适当的形状(显然与该特定形状的绘制一起)
以下是代码示例:
public void executeOperation(Graphics2D gr, int oper, boolean drawingMode){
if(oper==1){
new RectangleShape(startLocation, endLocation, borderColor, fillColor).draw(gr);
}
else if(oper==2){
new OvalShape(startLocation, endLocation, borderColor, fillColor).draw(gr);
}
....//more operations
}
任何人都知道在一般编程习惯方面可能出现什么问题(除非我'猜测'是正确的? - 如果是,请确认我的疑虑)。或者还有其他的东西?
(略过oper==1
的部分,因为我知道这些值应该定义为常量)
任何帮助都非常感激,我自己学习,很难猜出专业程序是如何设计的(并遵循他们的模式),因为我的经验是“有限的”(实际上没有)。
答案 0 :(得分:3)
如果您正在绘制光栅图像,是否需要跟踪用户绘制的内容?也许你的意思是PenTool
,RectangleTool
等对象?
现在,您似乎创建了持久并重绘以绘制特定形状的对象。您可以在适当的时候让工具对象在Image
上绘制一次(只是不要清除图形上下文)。选择工具时,只需将特定工具分配给某个activeTool
字段即可。
class DrawingTool {
public void draw(Graphics g) { }
}
class PenTool extends DrawingTool {
public void draw(Graphics g) {
// some drawing logic
}
}
class RectangleTool extends DrawingTool {
public void draw(Graphics g) {
// some other drawing logic
}
}
所以而不是
oper = 1;
你会写
activeTool = new PenTool(); // or activeTool = PenTool.GetInstance();
或类似的东西。现在,当你想绘制一些东西时,只需调用draw方法。正如我之前所说,你可以通过传递一个你永远不会清楚的Image
来做到这一点:
class DrawingCanvas {
Image image = createImage(GetWidth(), GetHeight());
DrawingTool activeTool;
// this is what gets invoked on every frame
public void paint(Graphics g){
g.drawImage(image, 0, 0, null);
}
}
// when you need to draw something
// (not on every frame, but something new)
activeTool.draw(image.getGraphics());
答案 1 :(得分:3)
if(oper==1){
//...
}
else if(oper==2){
//...
}
这是一种代码,正确使用面向对象的编程应该能够避免99%的时间。调查为什么你需要一个oper
整数。可能有一种模式可以修改以消除它的需要。例如,如果您当前正在为工具栏中的每个按钮分配一个整数值,则可以改为使按钮处理程序将当前OperationFactory
设置为生成与该按钮关联的类型的对象的那个。
答案 2 :(得分:1)
每个类型(特别是OvalShape和RectangleShape)都应该实现“executeOperation”方法。此方法应覆盖基类(闭合对象)中的“executeOperation”方法。
这将消除if(oper == 2)... else(oper == 2)的需要。它只会调用与对象类型相关的实现。
答案 3 :(得分:0)
从小片段中你可以更多地利用多态性。比如有一个定义executeOperation(Graphics2D gr,boolean drawingMode)方法的父抽象类/接口,然后为你支持的每个操作扩展/实现它(也许能够删除drawingmode但我看不到它做了什么。)可以可能也将graphics2D放入构造函数中。