Java: альтернатива передаче "this" в качестве аргумента конструктора для ссылки на объект creating


Я провел некоторое время, думая о различных решениях, которые я выбрал, поскольку я читал вокруг (я еще не очень опытен с Java), что использование этого для аргумента конструктора обычно не является хорошей практикой.

Я пытаюсь создать экземпляр нескольких объектов класса JobGroupMod, и для каждого JobGroupMod я должен создать определенное число объектов JobMod, которые должны иметь возможность ссылаться на объекты JobGroupMod, в которых они были порождены.

Для достижения этой цели я передаю "это" конструктору JobMod, но даже если он работает, это не похоже на правильное проектирование.

public class JobGroupMod implements JobGroup {

    public JobGroupMod(Node n,Set<Job> clusterJobs){
        JobMod j=new JobMod(n,this);
    }
}

А теперь класс JobMod:

public class JobMod implements Job {
     public JobMod(Node n, JobGroup jg){
         setJobGroup(jg);
     }
}
Мой вопрос заключается в том, есть ли лучший способ решить эту проблему, или мое решение является предлагаемым способом?
3 9

3 ответа:

Вы должны попробовать использовать метод статической фабрики (эффективная ссылка Java ).

Таким образом, вы избегаете передачи this в вызове конструктора, что крайне неразумно, мягко говоря.
пример кода:

public class JobGroupMod implements JobGroup {

    public static JobGroupMod createModeMod(Node n, Set<Job> clusterJobs) {
        JobGroup jg = new JobGroupMod();
        JobMod j = new JobMod(n, jg);
        return jg;
    }
}

Пока это остается единственной вещью, которую вы делаете в конструкторе JobGroupMod, является довольно безопасным, пока вы понимаете последствия. В реальном мире существует много Java-кода, который делает это. Это все еще не то, что вы действительно хотите делать, особенно когда вы начинаете говорить о многопоточности и параллелизме.

Опасность заключается в переходе к чему-то другому до того, как объект будет полностью сконструирован. Если конструктор должен был бросить исключение после того, как вы сделали это и не полностью сконструированный, вы можете иметь неприятную проблему. Если бы другой поток получил доступ к объекту, который вы передали this до того, как он был полностью сконструирован, у вас возникла бы неприятная проблема.

То, что вы часто найдете в Java, - это люди, использующие фабричный шаблон, чтобы избежать этого, метод типа "init" или инъекцию зависимостей.

Вообще никакой магии нет. Вы можете либо передать параметр через конструктор, либо инициализировать его позже, используя метод setter/init и т. д.

Если ваш класс JobMod нуждается в ссылке на JobGroupMod и не имеет ничего общего с ним, передайте его с помощью конструктора. Если иногда он может стоять без него, создайте Метод init() или сеттер, который может инициализировать эту ссылку.

Кстати, иногда вам приходится создавать как параметризованный конструктор, так и конструктор по умолчанию: во-первых, для регулярного программного использования, во-вторых, если вы использование XML, JSON или другой сериализации, которая проще для классов типа bean. В этом случае, по крайней мере, создайте javadoc, который объясняет, что конструктор по умолчанию не должен использоваться напрямую.