Java, передать основной класс дочернему классу, плохой стиль кодирования? - PullRequest
3 голосов
/ 17 ноября 2010

Пожалуйста, имейте это в виду, поскольку я все еще изучаю Java.

Пример ниже читает из класса с именем Parent, который создает собственный экземпляр для метода main.Затем он заставляет этот экземпляр выполнять все виды вычислений.

Затем он запускает поток с именем Child, передавая экземпляр Parent в качестве ссылки на Child.

Child просто сидит там, наблюдая за вещами, и иногда запускает публичные методы на Parent.

Это работает.Вопрос в том, это бедный стиль ?Есть ли более способ мышления Java для выполнения такой работы?

public class Parent {

    // main function that fires up the program
    public static void main() {

        // creates an instance of himself
        // and fires go that does all sorts of fuzzy calculus
        Parent parent = new Parent();
        parent.go();

        // creates a new thread of child and starts it
        Child child = new Child(parent);
        child.start();
    }

    private void go() {
        // all sort of initializations
    }

    public void getDataFromChild(int data) {
        // will get data from running child thread
    }
}



public class Child extends Thread {
    private Parent parent;

    // child constructor grabs Parent instance into "o"
    public Child(Parent o) {
        parent = o;
    }

    // this class main loop
    public void run() {
        while(1==1) {
            doSomething();
            try {
                sleep(1000);
            }
            catch(Exception e) { }
        }
    }

    private void doSomething() {
        parent.getDataFromChild(1);
    }

}

Спасибо.

Ответы [ 7 ]

5 голосов
/ 17 ноября 2010

Тема подклассов считается плохим стилем. Лучше реализовать Runnable, а затем передать runnable в поток (хммм ... вполне аналогично тому, как вы выполняете передачу Parent / Child!).

Runnable r = new Child(parent);
new Thread(r).start();

В противном случае ваш код Child.java выглядит нормально для меня.

Для реализации Runnable вам просто нужно предоставить метод run ():

public class Child implements Runnable {
  private Parent parent;

  public Child(Parent parent) { this.parent = parent; }

  public void run() {
    // what the thread does goes in here...
  }
2 голосов
/ 17 ноября 2010

Вопрос в том, это плохой стиль? Есть ли другой способ мышления Java для выполнения такой работы?

Передача «дочернему» объекту ссылки на его «родителя» не является ни хорошим, ни плохим стилем. Это просто программирование.

В реальном приложении (а не в искусственном примере) вы могли бы решить, было ли это хорошо design .

1 голос
/ 17 ноября 2010

Я не вижу в этом ничего плохого, за исключением того, что класс Child должен реализовывать Runnable. Пока вы документируете отношения между Parent и Child, все выглядит хорошо.

1 голос
/ 17 ноября 2010

В дополнение к Джулиусу Дэвису 'у меня есть еще одна проблема, связанная с кодом:

    Child child = new Child(parent);

А именно, почему является дочерним элементом в его собственной цепочке, а что будет делать дочерний элемент с родителем?

Если родитель действительно так тривиален, как кажется, тогда дочерний поток не нужен. С другой стороны, если родительский процесс выполняет больше работы после запуска дочернего потока, у вас возникают проблемы с синхронизацией, с которыми вам нужно разобраться. И вы должны разобраться с ними. Закон Мерфи гласит, что любые проблемы с потоками, которые могут произойти, будут . (Corallary: Есть больше возможных проблем с потоками, чем вы знаете, даже если вы эксперт по закону Мерфи.)

РЕДАКТИРОВАТЬ : ОК, дочерний поток вызывает parent.getDataFromChild. Что этот метод делает с данными? (Вносит ли он какие-либо изменения в объекты, к которым также осуществляется доступ из основного потока?) Поскольку он вызывается из дочернего потока, вам необходимо проверить как родительский, так и дочерний классы на предмет возможных состояний гонки.

0 голосов
/ 17 ноября 2010

То, что я прочитал из вашего кода, является циклической зависимостью, которая плоха.

Вы можете использовать интерфейсы для удаления зависимости.

0 голосов
/ 17 ноября 2010

Относительно того, что вы написали, для Child лучше быть Runnable, который работает в потоке

http://www.javabeginner.com/learn-java/java-threads-tutorial

тогда в отношении вопроса о том, является ли это хорошим способом, ответ таков: это зависит от того, что вы хотите сделать LOL

Вы можете посмотреть на несколько вещей:

  • Перехват различных исключений, таких как

InterruptedException

  • чтение синхронизированного для предотвращения одновременного доступа / модификации.

  • вместо сна вы можете проверить класс / дизайн шаблона наблюдателя, чтобы контролировать, когда ваши потоки будут выполнять там тесты

Наконец, я хотел бы познакомить вас с чудесным миром потокового приложения на Java: D

Редактировать: как указал Дэйв Л, вам нужно обратить внимание на то, чтобы очистить то, на что вы ссылаетесь, иначе вы получите зомби в своей программе

0 голосов
/ 17 ноября 2010

Вы захотите переопределить метод finalize для родителя, чтобы очистить Child, если на них ссылаются в другом месте.В противном случае это кажется вполне приемлемым для меня.

...