Come e cosa esporre una classe Tree AVL per un corretto test?

3

Non so quali metodi dovrebbero essere pubblici, perché ho i metodi di test che richiedono un nodo e un nodo è qualcosa di cui nessuno deve sapere.

public static class Node<K, V> //nested static class of AVLTree
public class AVLTree<K extends Comparable, V>
   public void insert(K k, V v)
   private Node insert(Node root, K k, V v)
   private Node rightRotate(Node n)
   private Node balanceFactor(Node n)

Quando si tratta di test, in realtà devo creare un root come oggetto node e creare un albero senza il metodo insert perché insert è solo per AVL trees e non nodes .

Lo stesso problema si applica agli altri metodi di test seguenti:

boolean isAVL(AVLTree.Node n) 
boolean isBST(AVLTree.Node n)
void rightRotate(AVLTree.Node n)
boolean isBalanceFactorGood(AVLTree.Node n)
    
posta Oleg 05.07.2017 - 08:17
fonte

1 risposta

3

Nella mia esperienza, è utile separare le operazioni di basso livello dall'API pubblica della classe.

L'API pubblica ha nomi di metodi convenienti e fornisce l'incapsulamento. Ad esempio, è possibile consentire l'iterazione e la ricerca di chiavi, ma impedire l'accesso diretto alla struttura e al layout dell'albero. I client dovrebbero essere in grado di utilizzare la struttura dati senza sapere che è implementata come un albero AVL. I test unitari dell'API verificano che l'albero funzioni come previsto, senza accertarsi che le operazioni specifiche dell'AVL funzionino correttamente.

Il livello di basso livello implementa le operazioni specifiche di AVL. La maggior parte dei client non dovrebbe utilizzare direttamente questo livello, ma solo tramite l'API pubblica. Questo livello non fornisce alcun incapsulamento della struttura AVL, quindi è necessario utilizzarlo correttamente. Va bene se questo livello usa la programmazione procedurale invece del design OOP. Sebbene questo layer non venga utilizzato da altri client, dovrebbe essere pubblico in modo che i test unitari possano verificare l'implementazione. I test unitari a questo livello possono far valere dettagli sulla struttura ad albero, ad es. che le rotazioni funzionino come previsto.

Si noti che l'API pubblica non deve ereditare dal livello inferiore: si desidera solo utilizzare l'implementazione, non ereditare l'interfaccia.

Progetto di esempio:

// implementation details

public class Node<K, V> {
  ...
}

public class AVLDetails {
  public static <K, V> void insert(Node<K, V> root, Node<K, V> n) { ... }
  public static <K, V> void rotateRight(Node<K, V> n) { ... }
  public static <K, V> void rotateLeft(Node<K, V> n) { ... }
  ...
}

// public API

public class Tree<K, V> {
  private Node<K, V> root;
  ...
  public void put(K key, V value) {
    AVLDetails.insert(root, new Node<>(key, value));
  }
}
    
risposta data 05.07.2017 - 13:57
fonte

Leggi altre domande sui tag