Refactoring List astrazione - C

1

Di seguito è riportato il disegno List di astrazione,

Listèun'astrazionegenericachecontienequalsiasitipo.

Diseguitoèriportatalastrutturadelladirectorydelcodice.Attualmentelatabelladeisimboli(ST)eilfileapifileIOutilizzaListabstraction.

./Code$.:fileIOlistSTtinyTaletype.hfrequencyCounter.cfrequencyCounter.exe./fileIO:file.hfileReading.c./list:arrayImpl.cconfig.cvirtualImplLayer.clinkedListImpl.clist.hlistHandler.hlistInterface.h./ST:implWithArray.cST.h

Diseguitoèriportatoilcodicepertinente(damigliorare),

list.h

#ifndefLIST_H/*Headerguard*/#defineLIST_H#include"type.h"

  typedef struct List List;


 typedef int (*compareTo)(const void *, const void *);
 typedef bool (*isLess)(const void *, const void *);
 typedef bool (*isEqual)(const void *, const void *);

#endif

listHandler.h

/***********listHandler.h ***********/
#ifndef LISTHANDLER_H
#define LISTHANDLER_H

#include"list/list.h"
typedef struct {

         bool(*canHandle)(char*);
        List*(*createList)(void);
         void(*freeList)(List*);
         void(*swim)(List*, int, isLess);
         void(*sink)(List*, int, isLess);
        void*(*listDeleteMaxElement)(List*, isLess);
        void*(*sortedListDeleteMaxElement)(List*);
          int(*listGetSize)(List*);
  const void*(*listGetItem)(List*, const int);
        List*(*sortedListInsertItem)(List*, void*, compareTo);
         void(*listInsertItem)(List*, void*);
        void*(*listDeleteItem)(List*, int);
        void*(*listDeleteLastItem)(List*);
        void*(*listDeleteFirstItem)(List*);
         int(*linearSearch)(const void*, List*, size_t, compareTo);
        void*(*binarySearch)(const void*, List*, size_t, compareTo);
         void(*insertionSort)(List*, size_t, isLess);
         void(*mergeSort)(List*, size_t, isLess);
         void(*swap)(List*, int, int);

}ListHandler;

/*
  "config.c" lookup below 2 global symbols created in impl handlers,
   before linking time, so "extern" keyword
*/
extern ListHandler arrayImplHandler;
extern ListHandler linkedListImplHandler;

/*
  "viml.c" lookup below global symbol created in "config.c",
   before linking time, so "extern" keyword
*/
extern ListHandler *listHandlers[];

/* Prototypes for definitions in viml.c - start ********/
        List* vCreateList(char *);
         void vFreeList(List*, char *);
         void vSwim(List*, int, isLess, char *);
         void vSink(List*, int, isLess, char *);
        void* vListDeleteMaxElement(List*, isLess, char *);
        void* vSortedListDeleteMaxElement(List*, char *);
          int vListGetSize(List*, char *);
  const void* vListGetItem(List*, const int, char *);
        List* vSortedListInsertItem(List*, void*, compareTo, char *);
         void vListInsertItem(List*, void*, char *);
        void* vListDeleteItem(List*, int, char *);
        void* vListDeleteLastItem(List*, char *);
        void* vListDeleteFirstItem(List*, char *);
          int vLinearSearch(const void*, List*, size_t, compareTo, char *);
        void* vBinarySearch(const void*, List*, size_t, compareTo, char *);
         void vInsertionSort(List*, size_t, isLess, char *);
         void vMergeSort(List*, size_t, isLess, char *);
         void vSwap(List*, int, int, char *);
/*****End ***********************************************/

#endif

listInterface.h

#include"list/listHandler.h"

#ifndef LISTINTERFACE_H
#define LISTINTERFACE_H

/*********** User Interface - start *****************/
#define createList()                   vCreateList(argv[1])
#define freeList(a)                    vFreeList(a, argv[1])
#define swim(a, b, c)                  vSwim(a, b, c, argv[1])
#define sink(a, b, c)                  vSink(a, b, c, argv[1])
#define deleteMax(a, b)                vListDeleteMaxElement(a, b, argv[1])
#define sortDeleteMax(a)               vSortedListDeleteMaxElement(a, argv[1])
#define getSize(a)                     vListGetSize(a, argv[1])
#define getItem(a, b)                  vListGetItem(a, b, argv[1])
#define sortInsertItem(a, b, c)        vSortedListInsertItem(a, argv[1])
#define insertItem(a, b)               vListInsertItem(a, b, argv[1])
#define deleteItem(a, b)               vListDeleteItem(a, b, argv[1])
#define deleteLastItem(a)              vListDeleteLastItem(a, argv[1])
#define deleteFirstItem(a)             vListDeleteFirstItem(a, argv[1])
#define lSearch(a, b, c, d)            vLinearSearch(a, b, c, d, argv[1])
#define bSearch(a, b ,c, d)            vBinarySearch(a, b, c, d, argv[1])
#define callInsertionSort(a, b, c)     vInsertionSort(a, b, c, argv[1])
#define callMergeSort(a, b, c)         vMergeSort(a, b, c, argv[1])
#define swap(a, b, c)                  vSwap(a, b, c, argv[1])

/*********** User Interface - end *****************/
#endif

dove, listInterface.h è un'interfaccia per un utente di List di astrazione.

Tutti i prefissi api wth ( v ) sono definiti in virtualImplLayer.c .

Ma,

1)

listInterface.h non è un codice leggibile per l'utente, perché non possiede List typedef che è effettivamente disponibile in list.h e indirettamente incluso tramite listHandler.h .

2) listInterface.h non è facile da usare perché l'utente (ad esempio fileReading.c ) deve passare l'argomento argv a List api pubblico. Public api è dato in listInterface.h . L'utente deve eseguire l'applicazione passando argv[1] come,

$ ./userapp.exe ARRAY

o

$ ./userapp.exe LINKEDLIST

Domanda:

Può listInterface.h diventare più leggibile & facile da usare?

    
posta overexchange 07.01.2017 - 06:45
fonte

1 risposta

3

Ci sono diversi modi per rendere listInterface.h più facile da usare. Uno dei modi più semplici è combinare list.h e listInterface.h in un unico file e spostare anche le dichiarazioni delle funzioni vXXX.

Come secondo refactoring, dovresti rimuovere il selettore di implementazione ("ARRAY" o "LINKEDLIST") da tutte le funzioni dell'interfaccia. Se si desidera avere una selezione run-time dell'implementazione, è necessario disporre di una singola funzione per selezionare l'implementazione da utilizzare per l'intero programma oppure specificarla solo sulla funzione createList come argomento esplicito. < br> In questo modo, gli utenti dell'astrazione dell'elenco non possono creare accidentalmente un elenco collegato e quindi richiamare l'implementazione dell'array su di esso.
Avere l'argomento esplicitamente, e non implicitamente come argv[1] , rende chiaro che qui c'è una scelta e dà la possibilità di basare la scelta su qualcosa di diverso dal primo argomento del programma.

    
risposta data 07.01.2017 - 11:06
fonte

Leggi altre domande sui tag