2013-07-25 3 views
-2

У меня вопрос о том, как избежать побочных эффектов на объектах Java. Предположим, у меня есть экземпляр myObject от MyObject. Я хотел бы обработать myobject через цепочку методов/команд и на каждом уровне команды, я хочу обогатить myObject с тем, что вычислил метод/команда.Лучшая практика, чтобы избежать побочных эффектов

Вот класс, который MyObject является экземпляром:

public class MyObject { 
    private int resultOfCommand1; 
    private int resultOfCommand2; 
    private int resultOfCommand3; 
    private int resultOfCommand4; 
    .... 
    .... 
} 

Вот методы/команды, которые MyObject должен быть обработан посредством:

private MyObject command1(MyObject myObject) { 
    return myObject.setRresultOfCommand1(1); 
} 
private MyObject command2(MyObject myObject) { 
    return myObject.setRresultOfCommand2(2); 
} 
private MyObject command3(MyObject myObject) { 
    return myObject.setRresultOfCommand3(3); 
} 
private MyObject command4(MyObject myObject) { 
    return myObject.setRresultOfCommand4(4); 
} 

Таким образом, конструкция показано выше, имеет побочные эффекты, и я хотел бы избежать такой вещи.

Может ли кто-нибудь сказать мне лучший способ избежать побочных эффектов? Лучше ли всегда делать копию объекта, который был передан в качестве параметра (в данном случае myObject), внести изменения в копию и затем вернуть ее? Есть ли лучший способ гарантировать многопоточность?

Любая помощь будет оценена по достоинству. Horace

+1

То, что вы сделали, просто выглядит сложнейшими геттерами и сеттерами ... и после этого, когда вы упоминаете темы ... используйте синхронизированный – chancea

+0

Вы задумали создать схему трубопровода? Передайте объект через массив классов команд с каждым изменением объекта. Только если в каждой из обработанных команд нет мяса, он становится слишком фрагментированным. С положительной стороны команды, которые нужно выполнить, могут быть легко изменены. Посмотрите на реализацию этого шаблона в netty, http://docs.jboss.org/netty/3.2/api/org/jboss/netty/channel/ChannelPipeline.html. – Raji

ответ

2

Если вы хотите избежать побочных эффектов, методы, которые устанавливают значение, не должны изменять экземпляр, вместо этого они возвращают новый экземпляр (копию). Внутри этого метода вы используете конструктор для установки всех (окончательных) значений.

Пример:

class C { 
    private final int x; 
    private final int y; 

    public C(int _x) { 
     super(); 
     this.x = _x; 
     this.y = -1; 
    } 

    public C(int _x, int _y) { 
     super(); 
     this.x = _x; 
     this.y = _y; 
    } 

    public C setY(int _y) { 
     return new C(this.x, _y); 
    } 
} 

Чтобы предотвратить побочные эффекты, просто объявить поля, как final. Если все поля равны final, значения (в случае примитивных типов) и ссылки на объекты неизменяемы. В случае ссылки на объект этот объект должен быть неизменным и для достижения «полной неизменности».

Таким образом, вы не изменяете копию, но вы создаете копию копию с новыми значениями.

Теперь безопасно передавать неизменяемый экземпляр; он не может измениться, поэтому он потокобезопасен.

Смежные вопросы