Создание круговых общих ссылок

Я пишу приложение, чтобы сделать некоторые распределенные вычисления в одноранговой сети. В определении сети я имею два, классифицируют P2PNetwork и P2PClient. Я хочу, чтобы они были универсальны и тем самым имели определения:

P2PNetwork<T extends P2PClient<? extends P2PNetwork<T>>>

P2PClient<T extends P2PNetwork<? extends T>>

с P2PClient, определяющим метод setNetwork (Сеть T). То, что я надеюсь описать с этим кодом:

  1. P2PNetwork составлен клиентов определенного типа
  2. P2PClient может только принадлежать сети, клиенты которой состоят из того же типа как этот клиент (циклическая ссылка)

Это кажется корректным мне, но если я пытаюсь создать неуниверсальную версию такой как

MyP2PClient<MyP2PNetwork<? extends MyP2PClient>> myClient;

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

  1. Универсальная циклическая ссылка даже возможна (я ничего никогда не видел явно запрещение ее)?
  2. Является вышеупомянутым универсальным определением корректное определение таких круговых отношений?
  3. Если это допустимо, действительно ли это - "корректный" способ описать такие отношения (т.е. есть ли другое действительное определение, которое стилистически предпочтено)?
  4. Как я правильно определил бы неуниверсальный экземпляр Клиента и сервера, учитывая надлежащее универсальное определение?
17
задан Josh Lee 6 May 2011 в 17:02
поделиться

2 ответа

Круговые общие ссылки действительно возможны. Java Generics and Collections включает несколько примеров. В вашем случае такой образец будет выглядеть так:

public interface P2PNetwork<N extends P2PNetwork<N, C>,
                            C extends P2PClient<N, C>> {
  void addClient(C client);
}

public interface P2PClient<N extends P2PNetwork<N, C>,
                            C extends P2PClient<N, C>> {
  void setNetwork(N network);
}

class TorrentNetwork implements P2PNetwork<TorrentNetwork, TorrentClient> {
  @Override
  public void addClient(TorrentClient client) {
    ...
  }
}

class TorrentClient implements P2PClient<TorrentNetwork, TorrentClient> {
  @Override
  public void setNetwork(TorrentNetwork network) {
    ...
  }
}

...

TorrentNetwork network = new TorrentNetwork();
TorrentClient client = new TorrentClient();

network.addClient(client);
25
ответ дан 30 November 2019 в 12:50
поделиться

Нам может помочь ответить вам, если вы дополнительно определили, что означает «определенный тип», то есть каковы различия между различными «типами» P2P-сетей.

Но вместо того, чтобы выразить зависимость / круговую взаимосвязь в терминах друг друга, было бы проще выразить, введя третий класс, P2PType :

public class P2PNetwork<T extends P2PType> {
    ...
}
public class P2PClient<T extends P2PType> {
    ...
    public void setNetwork(P2PNetwork<T> network) { ... }
}

Я мог что-то упустить, но я думаю это позволит компилятору обеспечить, чтобы P2PClients были частью P2PNetworks одного и того же универсального типа.

Однако этот подход может развалиться, если «тип» не является чем-то, что можно выразить как объектно-ориентированный, т.е. если P2PType не является чем-то, что имеет методы, полиморфные поведение и т. д.

3
ответ дан 30 November 2019 в 12:50
поделиться
Другие вопросы по тегам:

Похожие вопросы: