我一直在javaworld.com上阅读两篇文章(1)(2),关于所有类字段应该是私有的,getter/setter方法也同样糟糕.对象应该对其拥有的数据起作用,而不是允许访问它.
我目前正在为Connect Four进行大学任务.在设计程序时,玩游戏的代理商需要访问董事会的状态(因此他们可以决定要移动的内容).他们还需要将此移动传递给游戏,以便将其验证为合法移动.在决定移动内容时,将各个部分分组为具有起点和终点的威胁.
Board,Threat和Point对象实际上并没有做任何事情.它们只是存储可以以人类可读方式访问的相关数据.
在设计之初,我将板上的点表示为两个元素int数组,但是在创建点或引用它们的组件时会很烦人.
所以,班级:
public class Point {
public int x;
public int y;
public Point(int x, int y){
this.x = x;
this.y = y;
}
}
Run Code Online (Sandbox Code Playgroud)
我能想到的各方面都很完美.除了它打破了我学到的每一条规则.我犯了罪吗?
mer*_*ike 18
公共字段将对象的表示暴露给其调用者,即如果表示必须改变,则调用者也是如此.
通过封装表示,您可以强制调用者如何与其进行交互,并且可以更改该表示,而无需在公共API未更改的情况下修改调用者.在任何非平凡的程序中,封装都是实现合理可维护性所必需的.但是,虽然您需要胶囊,但它们的适当粒度可能比单个类大.例如,Iterator
从Collection
它操作的内部表示中封装一个是没有意义的.
有了这个,让我们看看你的例子:
public class Point {
public int x;
public int y;
public Point(int x, int y){
this.x = x;
this.y = y;
}
}
Run Code Online (Sandbox Code Playgroud)
该类的内部表示极不可能改变,因此通过将字段设为私有来隐藏表示的结构没有任何好处.但是,我会阻止调用者Point
在构造之后修改它:
public class Point {
public final int x;
public final int y;
public Point(int x, int y){
this.x = x;
this.y = y;
}
}
Run Code Online (Sandbox Code Playgroud)
这样一个实际上希望封装其状态的类可以在Point
不泄漏其内部表示的情况下返回它,并在其表示中使用给定的Point而不捕获它.这也非常适合一个点的数学概念,它没有身份或改变状态.
在设计程序时,玩游戏的代理商需要访问董事会的状态(因此他们可以决定要移动的内容).他们还需要将此移动传递给游戏,以便将其验证为合法移动.在决定移动内容时,将各个部分分组为具有起点和终点的威胁.
Board,Threat和Point对象实际上并没有做任何事情.它们只是存储可以以人类可读方式访问的相关数据.
现在这听起来像是一个浪费的封装机会:代理人真的不应该被允许任意修改董事会,但仅限于法律行动.为什么Game
在更新的国家居于课堂时,决定法律行动是什么Board
?如果Board
要验证移动本身,没有调用者,特别是没有代理,可能违反游戏规则:
public class Board {
// private fields with state
// public methods to query state
public void perform(Move move) throws IllegalMoveException;
}
Run Code Online (Sandbox Code Playgroud)
Jam*_*mes 12
将一个字段公开并不总是一件坏事,但是你严格限制自己,因为你将实现与使用它的类耦合起来.稍后你想要添加一个监听器,只要设置了X中的值,就会通知你.没有重构一切,你无法做到这一点.如果实现setX()并隐藏字段本身,则只需更改setX()的实现即可通知您已对使用此方法的类进行了更改而未对其进行更改.
这是c#优于Java的一个优点.你可以宣布一个有公共领域的类,然后改变你的想法使用带有getter和setter的隐藏字段; 但是调用者的语法是一样的
public class Point
{
public int X;
}
Run Code Online (Sandbox Code Playgroud)
变
public class Point
{
int m_x;
public int X {get {return m_x;} set {m_x = value;}
}
Run Code Online (Sandbox Code Playgroud)
但来电者总是如此
Point p;
p.X = 12;
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
14027 次 |
最近记录: |