Analiza przykładowego kodu. Prośba o pomoc.

0

Próbuję wykonać zadanie podobne do poniższego. Wklejam okrojony kod i kieruję prośbę o pomoc w nakierowaniu myślenia.

Mój problem to:

  1. Lista w klasie TaskView jest dla typu IComponentNode (to jest interface) ? Czy chodzi o to żeby utworzyć klasę implementującą ten interface i wtedy lista w klasie TaskView ma być listą dla obiektów tej nowej klasy?
  2. I tak samo metody findComponent(String code) zwracają typ IComponentNode, a czy metody nie powinny zwracać typu obiektu klasy dla interface IComponentNode ?
  3. Do tego nie wiem jak ma mi pomóc Interface IcompositeComponentNode.
    Zadanie to:
    Analiza poniższego kodu i zaimplementowanie metod findComponent, findComponentByRenderer, countComponents w klasie TaskView. Proszę uwzględnić w analizie i implementacji interfejs ICompositeComponentNode.
interface ITaskView {
  // zwraca komponent o podanym kodzie lub null
  IComponentNode findComponent(String code);
  // zwraca komponent o podanym rendererze lub null
  IComponentNode findComponentByRenderer(String renderer);
  //zwraca liczbę komponentów
  int countComponents();
}
public class TaskView implements ITaskView {
  private List<IComponentNode> components;
}
interface IComponentNode {
  String getCode();
  String getRenderer();
}
interface ICompositeComponentNode extends IComponentNode {
  List<IComponentNode> getComponents();
}
0

Udało Ci się rozwiązać problem? Też dostałem to zadanie na rozmowie i miałem tą samą zagwozdkę, o co im tam do kurki wodnej chodzi :). Finalnie odpuściłem i napisałem im, że jednak mój poziom wiedzy w Javie jest wciąż za niski, by nie marnować zarówno ich, jak i swojego czasu.
Aktualnie miesiąc po intensywnej nauce Javy(głównie Swing i podstawy Springa) wciąż nie wiem, jak to zrobić :D.

0

Lista w klasie TaskView jest dla typu IComponentNode (to jest interface) ?

Fakt, że jest zdefiniowany jako interface IComponentNode wskazywałby, że jest to interface.

Czy chodzi o to żeby utworzyć klasę implementującą ten interface i wtedy lista w klasie TaskView ma być listą dla obiektów tej nowej klasy?

Nie, nie trzeba tworzyć takiej klasy.

Po to właśnie jest interfejs, by podstawienie konkretnej klasy pozostawało kwestią otwartą.

Równie dobrze mógłbym napisać bibliotekę, w której zdefiniowałbym sobie pewien interfejs, a jego implementację pozostawił komukolwiek, kto będzie korzystać z tej biblioteki w przyszłości.

I tak samo metody findComponent(String code) zwracają typ IComponentNode, a czy metody nie powinny zwracać typu obiektu klasy dla interface IComponentNode ?

Nie. To znaczy oczywiście, będą zwracać jakieś obiekty, ale nie obchodzi nas jakie.

Interfejs jako typ zwrotny oznacza tyle, że obiekty te mają być zgodne z podanym interfejsem. I to jest jedyne oczekiwanie jakie wobec nich mamy. Interfejs to kontrakt, którego mają dotrzymać. I tyle.

Do tego nie wiem jak ma mi pomóc Interface IcompositeComponentNode.

On nie pomaga, tylko zwiększa stopień komplikacji zadania. Reprezentuje on węzły, które mają dzieci (wśród których też mogą być ICompositeComponentNode).

Jego istnienie oznacza, że masz do czynienia z (potencjalnie) strukturą drzewiastą, a nie tylko łańcuchem / sekwencją / nitką.

Analiza poniższego kodu i zaimplementowanie metod findComponent, findComponentByRenderer, countComponents w klasie TaskView. Proszę uwzględnić w analizie i implementacji interfejs ICompositeComponentNode.

Implementujesz metody z ITaskView i trawersujesz w nich pole components, szukając węzła (obiektu), który ze swojej metody getCode lub getRenderer zwróci wartość taką, jaka jest szukana.

Trick polega na tym, że ponieważ przeszukujemy strukturę drzewiastą, w przypadku napotkania węzła zgodnego z typem ICompositeComponentNode, trzeba rekurencyjnie przeszukać sam ten węzeł (czyli jego dzieci, i dzieci jego dzieci). Czyli klasyczne przechodzenie drzewa.

0

na jakie stanowisko jest to zadanie?

0
Uczynny Młot napisał(a):

na jakie stanowisko jest to zadanie?

Junior Java Developer w jednym z warszawskich korpo, jako wstępne rekrutacyjne zadanie.

0

shit :/

0

Ze swojej strony dodam, że Pani z hrów przekazała, że panowie technicy układający to pytanie powiedzieli: " Zadanie rekrutacyjne jest bardzo łatwe ".

0

No ale to zadanie jest przeciez zupelnie trywialne i sprowadza sie to kilku (!) linijek kodu. Jesli ktos nie potrafi tego napisac to trudno mi sobie wyobrazic zeby mogl napisac cokolwiek sensownego w pracy.
countComponents() -> Dodajemy do IComponentNode metode getChildrenCount, ktora dla zwyklego noda zwraca 1 a dla ICompositeComponentNode iteruje po jego dzieciach i sumuje wyniki getChildrenCount() dla kazdego z tych dzieci.
find*() -> tutaj obie metody sa analogiczne, wiec mozna pokusic sie nawet o napisanie jednej ktora przyjmuje jako argument jakis Predykat, ale samo zachowanie metody znow jest trywialne. Dodajmy sobie do IComponentNode metode Optional<IComopenentNode> getIfMatchesCondition(Predicate<Boolean> predicate). Dla zwyklego noda metoda ewaluuje predykat (czyli np. porownuje przekazany code z wartoscia getCode() dla tego noda) i zwraca Optional.of(this) jesli pasuja lub Optional.empty() jesli predykat nie jest spelniony. Dla ICompositeComponentNode ta metoda iteruje przez getComponents() i robi getIfMatchesCondition dla kazdego dziecka do czasu az trafi sie jakis pierwszy pasujacy.

Sumarycznie to zadanie to jest raptem kilka linijek kodu.

Powinno to wygladac mniej wiecej tak:

interface ITaskView {
  IComponentNode findComponent(String code);

  IComponentNode findComponentByRenderer(String renderer);

  int countComponents();
}

class TaskView implements ITaskView {
  private List<IComponentNode> components;

  @Override
  public IComponentNode findComponent(String code) {
    return findByPredicate(component->component.getCode().equals(code));
  }

  @Override
  public IComponentNode findComponentByRenderer(String renderer) {
    return findByPredicate(component->component.getRenderer().equals(renderer));
  }

  private IComponentNode findByPredicate(Predicate<IComponentNode> predicate){
    return components.stream()
        .map(child->child.getMatchingObject(predicate))
        .filter(Optional::isPresent)
        .map(Optional::get)
        .findFirst()
        .orElse(null);
  }

  @Override
  public int countComponents() {
    return components
        .stream()
        .mapToInt(IComponentNode::getChildrenCount)
        .sum();
  }
}

interface IComponentNode {
  String getCode();

  String getRenderer();

  default int getChildrenCount(){
    return 1;
  }

  default Optional<IComponentNode> getMatchingObject(Predicate<IComponentNode> predicate){
    if(predicate.test(this)){
      return Optional.of(this);
    }
    return Optional.empty();
  }
}

interface ICompositeComponentNode extends IComponentNode {
  List<IComponentNode> getComponents();

  @Override
  default int getChildrenCount() {
    return getComponents()
        .stream()
        .mapToInt(IComponentNode::getChildrenCount)
        .sum();
  }
}

Zastanawia mnie troche ktore miejsce w tym zadaniu sprawilo wam takie wielkie problemy. Przeciez tam nie ma nic poza petlami for i ifami.

1 użytkowników online, w tym zalogowanych: 0, gości: 1