Прежде всего.
Вам не нужно избавляться от всего своего статического кода только потому, что это сделает его лучше на «бумаге».
Вы действительно должны понимать, в чем разница между кодом экземпляра (не статичным) и кодом класса (статическим)
статический код (методы / атрибуты класса)используется, когда методы / атрибуты не нуждаются в экземпляре класса для работы.Очень хорошим примером является метод рисования изображения: Image.draw()
экземпляр методы / атрибуты полезны для сохранения состояния данного объекта, который должен храниться отдельно отданные в других объектах.
Например, если в вашей игре есть класс Player
, и у вас есть два экземпляра player1
и player2
, имеет смысл каждый из них иметь свой собственный счет:
public class Player {
private int score;
private String name;
etc.....
}
Player one = new Player("Player 1");
display( one.score );
Player two = new Player("Player 2");
display( two.score );
Вместо того, чтобы создавать артефакты для сохранения очков каждого игрока (например, помещать их в массивы, где каждый индекс является атрибутом, делать этот массив статическими и т. Д. И т. Д.)
Во-вторых
Вы можетеуменьшите конструкции, которые вы упомянули object1.atr2.other.next.etc
, назначив объектам соответствующие атрибуты и выполнив инкапсуляцию правильным образом.
Если объект b
должен получить доступ к N-му элементу другого a
, вполне вероятно, что указанный атрибут принадлежит объекту b
вместо a
или, возможно, этому объекту a
должен предоставить метод, чтобы избежать разоблачения его внутренних органов.
Это даже облегчает чтение кода:
т.е.
public void draw(Graphics2D) {
if( this.game.needsDrawing() ) {
this.game.draw();
}
}
вместо:
public void draw(Graphics2D) {
if (this.game.time() > this.timer) {
this.game.image.draw(this.tiles[this.game.animation.get("tileAnim")], x, y, null)
}
}
Опять же, это зависит от ситуации, могут быть сценарии, когда вам не нужен экземпляр (опять же, как утилита draw ()метод изображения)
Наконец.
Методы экземпляра позволяют вам использовать полиморфизм, а методы класса - нет (по крайней мере, в Java и других статически типизированных языках).
Таким образом, вы можете воспользоваться преимуществами делегирования во время выполнения и полиморфизма, если вашкод является кодом экземпляра.Возьмите, например, шаблон State , вы не можете использовать его, если весь ваш код статичен, но вы можете использовать код экземпляра:
class Game {
GameState state = GameState.getInitialState( this );
void run() {
while( state.alive ) {
do X Y Z
state.updateState();
}
}
}
class GameState {
Game context;
static GameState getInitialState( Game g ) {
return new StartGameState(g);
}
void updateState();
}
class StartGameState {
void updateState() {
if( this.context.someCondition() ) {
this.context.state = new MidGameState();
}
}
}
class MidGameState {
void updateState() {
if( this.context.someOtherCondition() ) {
this.context.state = new EndGameState();
}
}
}
class EndGameState {
void updateState() {
Game over...
}
}
И снова, только если это имеет смыслс точки зрения ориентации объекта, как у объекта есть атрибуты, данные которых требуются?Если нет, то может быть полезно сохранить этот раздел кода статичным.
Все эти понятия (инкапсуляция, полиморфизм, абстракция, наследование и т. Д.) Являются самой природой технологии ОО и охватываются ООА / D , хотя они могут показаться синтаксическим сахаром (и большей частьювремена, когда они есть) ваш опыт скажет вам, когда у вас должно быть что-то вроде class code и когда как instance code.