OOP设计问题
OOP Design issues
我认为这是一个小问题,甚至可能是主观的,但它确实困扰着我。每当我创建由单元格网格组成的东西(主要是游戏)时。我倾向于对单元格和网格使用相同的吸气剂。为了解释清楚,这里有代码示例:
class Cell{
private int value1;
private boolean value2;
public Cell(int value1, boolean value2){
this.value1 = value1;
this.value2 = value2;
}
public int getValue1(){
return value1;
}
public boolean getValue2{
return value2;
}
}
这是我的网格 class:
class Grid{
private Cell[][] cells;
public Grid(int rows, int cols){
cells = new Cell[rows][cols];
// initialize
}
public int getCellValue1(int row, int col){
return cells[row][col].getValue1();
}
public boolean getCellValue2(int row, int col){
return cells[row][col].getValue2();
}
// setters, same idea
}
我不知道。我可能想太多了,这可能是一个愚蠢的问题,但是,有更好的方法吗?也许只有我一个人,但我觉得它有点笨拙,而且有很多额外的代码。这个设计好吗?
我会将 Edwin 的 Grid
class 更改为这样的界面:
public interface Grid {
public void setValue(String value, int row, int column);
public String getValue(int row, int column);
}
CellGrid
class 使用 Cell
的二维数组实现一个 Grid
:
class CellGrid implements Grid {
private Cell[][] cells;
public CellGrid(int rows, int cols){
cells = new Cell[rows][cols];
// initialize
}
// get a value using the implementation we chose
public String getValue(int row, int col) {
return cells[row][col].getValue();
}
}
你的 Cell
class 基本保持不变,只是我将 value1
的类型从 int
更改为 String
:
class Cell {
private String value;
// other fields can go here
public Cell(String value, ...){
this.value = value;
// ...
}
public String getValue(){
return value;
}
}
您可以使用以下代码访问特定的 属性 单元格:
grid.getValue(2, 2)
并不是说当您进行此调用时,您不需要了解 Grid
的任何实现。正如我在最初的回答中提到的,CellGrid
class 对其 Cell
的内部工作没有任何依赖。
您拥有的是 class 构造中的数据结构。
没有某些行为就不可能有 "OO"-Class。
网格示例至少有少量行为,因为您可以将元素的查找与其存储位置分离。例如,在 Tim 的 Grid
示例中,我可以将存储布局更改为使用 HashMap 实现,其中行和列值被输入到哈希函数中,并使用相同的哈希函数检索相同的元素.
在这种情况下,网格将具有存储和检索单元格的 "behavior";然而,这仍然泄露了太多的数据结构。在我的网格中,我只是拿走并返回数据
public class Grid {
public void setValue(String value, int row, int column) {
...
}
public String getValue(int row, int column) {
...
}
}
关键是在我的 "improved" 示例中,更多的实现细节对 class 的 "user"(程序员)隐藏了。适当的数据隐藏对于良好的面向对象编程至关重要;因为,它允许使用 class 的人开始将其视为 "black box",而了解其实现方式对于理解如何使用它并不重要。
当您可以使用某些东西而无需确切了解它的工作原理时,您就拥有了一个高度可用的组件。这是好的(低级)设计。
好的设计让生活更轻松。例如,您的烤面包机可能有一个 "start" 按钮、一个 "browning adjustment" 旋钮和一个电源指示灯。它真的不需要太多,如果你必须知道这些组件是如何在内部连接的,那么交换烤面包机将是一项更加困难的任务,因为你必须重新学习你的 "new toaster" 是如何构建的。
我认为这是很好的设计。对于基础class喜欢的项目中的单元格,你必须定义基本属性(变量)并实现功能。我不会打扰构造函数、getter 和 setter,因为 IDE 像 eclipse 可以帮助自动生成这些。右击-> source -> generate getters and setters。 (想想为什么IDE提供这些)
在网格中class,我的习惯是我通常不写getters和setters,因为与直接使用array[]相比,输入所需的函数名和参数可能不会节省你的时间[] 获取值,除了你想在简单的 getter 和 setter 中添加更多操作。
不管怎么样,都是不错的OOP设计。乏味但清晰且可读性强。
我认为这是一个小问题,甚至可能是主观的,但它确实困扰着我。每当我创建由单元格网格组成的东西(主要是游戏)时。我倾向于对单元格和网格使用相同的吸气剂。为了解释清楚,这里有代码示例:
class Cell{
private int value1;
private boolean value2;
public Cell(int value1, boolean value2){
this.value1 = value1;
this.value2 = value2;
}
public int getValue1(){
return value1;
}
public boolean getValue2{
return value2;
}
}
这是我的网格 class:
class Grid{
private Cell[][] cells;
public Grid(int rows, int cols){
cells = new Cell[rows][cols];
// initialize
}
public int getCellValue1(int row, int col){
return cells[row][col].getValue1();
}
public boolean getCellValue2(int row, int col){
return cells[row][col].getValue2();
}
// setters, same idea
}
我不知道。我可能想太多了,这可能是一个愚蠢的问题,但是,有更好的方法吗?也许只有我一个人,但我觉得它有点笨拙,而且有很多额外的代码。这个设计好吗?
我会将 Edwin 的 Grid
class 更改为这样的界面:
public interface Grid {
public void setValue(String value, int row, int column);
public String getValue(int row, int column);
}
CellGrid
class 使用 Cell
的二维数组实现一个 Grid
:
class CellGrid implements Grid {
private Cell[][] cells;
public CellGrid(int rows, int cols){
cells = new Cell[rows][cols];
// initialize
}
// get a value using the implementation we chose
public String getValue(int row, int col) {
return cells[row][col].getValue();
}
}
你的 Cell
class 基本保持不变,只是我将 value1
的类型从 int
更改为 String
:
class Cell {
private String value;
// other fields can go here
public Cell(String value, ...){
this.value = value;
// ...
}
public String getValue(){
return value;
}
}
您可以使用以下代码访问特定的 属性 单元格:
grid.getValue(2, 2)
并不是说当您进行此调用时,您不需要了解 Grid
的任何实现。正如我在最初的回答中提到的,CellGrid
class 对其 Cell
的内部工作没有任何依赖。
您拥有的是 class 构造中的数据结构。
没有某些行为就不可能有 "OO"-Class。
网格示例至少有少量行为,因为您可以将元素的查找与其存储位置分离。例如,在 Tim 的 Grid
示例中,我可以将存储布局更改为使用 HashMap 实现,其中行和列值被输入到哈希函数中,并使用相同的哈希函数检索相同的元素.
在这种情况下,网格将具有存储和检索单元格的 "behavior";然而,这仍然泄露了太多的数据结构。在我的网格中,我只是拿走并返回数据
public class Grid {
public void setValue(String value, int row, int column) {
...
}
public String getValue(int row, int column) {
...
}
}
关键是在我的 "improved" 示例中,更多的实现细节对 class 的 "user"(程序员)隐藏了。适当的数据隐藏对于良好的面向对象编程至关重要;因为,它允许使用 class 的人开始将其视为 "black box",而了解其实现方式对于理解如何使用它并不重要。
当您可以使用某些东西而无需确切了解它的工作原理时,您就拥有了一个高度可用的组件。这是好的(低级)设计。
好的设计让生活更轻松。例如,您的烤面包机可能有一个 "start" 按钮、一个 "browning adjustment" 旋钮和一个电源指示灯。它真的不需要太多,如果你必须知道这些组件是如何在内部连接的,那么交换烤面包机将是一项更加困难的任务,因为你必须重新学习你的 "new toaster" 是如何构建的。
我认为这是很好的设计。对于基础class喜欢的项目中的单元格,你必须定义基本属性(变量)并实现功能。我不会打扰构造函数、getter 和 setter,因为 IDE 像 eclipse 可以帮助自动生成这些。右击-> source -> generate getters and setters。 (想想为什么IDE提供这些)
在网格中class,我的习惯是我通常不写getters和setters,因为与直接使用array[]相比,输入所需的函数名和参数可能不会节省你的时间[] 获取值,除了你想在简单的 getter 和 setter 中添加更多操作。
不管怎么样,都是不错的OOP设计。乏味但清晰且可读性强。