2012-07-02 22 views
8

Niedawno napisałem bibliotekę klas, która zawiera obiekty, które modelują określone typy plików. Na przykład, nie jest abstrakcyjnym Document klasy, z klas pochodnych PdfDocument (beton) oraz OfficeDocument (streszczenie, pochodzące z konkretnych klas, takich jak WordDocument i ExcelDocument) itpKto powinien być odpowiedzialny za wybór odpowiedniej klasy pochodnej?

Obecnie klienci sposób utworzyć nowy obiekt jest poprzez wybranie Odpowiednia klasa pochodna i przekazanie jej tablicy bajtów. Tak na przykład, jeśli mam tablicę bajtów o PdfDocument i Worddocument, chciałbym zrobić coś takiego:

var wordDocument = new WordDocument(wordDocumentByteArray); 
var pdfDocument = new PdfDocument(pdfDocumentByteArray); 

Czy to dopuszczalne projektu, że klient musi wiedzieć, co pochodzi klasę w użyciu? Czy też lepiej byłoby ukryć wszystkie oprócz abstrakcyjnej klasy Document i używając czegoś takiego jak abstrakcyjny wzorzec fabryczny, aby zwrócić poprawny typ pochodny? np .:

var wordDocument = DocumentFactory.GetDocument(wordDocumentByteArray, "docx"); 
// pass file extension so we know what the file is 

Należy zauważyć, że typy pochodzące nie dodać dodatkowe właściwości/metod do klasy abstrakcyjnej, po prostu wdrożyć metody abstrakcyjne na różne sposoby.

+0

Zdecydowanie druga opcja. Pozwala na znacznie łatwiejszą rozbudowę w przyszłości i oznacza, że ​​ludzie spędzają mniej czasu na aktualizowaniu deklaracji klasy, gdy dodawane są nowe, bardziej odpowiednie typy. –

+0

Czy klasa "Dokument" ma wszystko, co użytkownik końcowy kiedykolwiek będzie musiał zrobić z danym "Dokumentem", czy od czasu do czasu (lub często) będzie potrzebować dostępu do funkcji specyficznej dla bardziej pochodnego typu? – Servy

+0

@Servy Tak, klasa 'Dokument' ma jedną publiczną metodę abstrakcyjną. Wszystkie klasy pochodne składają się wyłącznie z chronionych i prywatnych metod pomocniczych (wraz z nadpisaną metodą publiczną) wyłącznie w celu implementacji jednej publicznej metody. – Andrew

Odpowiedz

9

Drugie podejście jest znacznie lepsze niż pierwsze, ponieważ ukrywa fakt istnienia dokumentów Word i Pdf od użytkowników biblioteki. Jest to szczególnie ważne, gdy zdecydujesz się dodać więcej typów dokumentów - np. Rtf, Html i tak dalej: użytkownicy otrzymaliby korzyści z nowo dodanych typów bez konieczności przekompilowywania ich kodu. W rzeczywistości nawet nie zauważyliby, że coś zmieniliście: jeśli zrobicie to dobrze, ich kod będzie "działał" z dokumentami typu, o których istnieniu nie wiedzieli.

P.S. Jeśli możesz zeskanować tablicę bajtów i dowiedzieć się od niej poprawnego typu, twój interfejs API może "zdobyć punkty za styl", eliminując drugi parametr.

+0

Dzięki. Na pewno zajrzę do sprawdzenia, czy mogę określić typ z tablicy bajtów, jedynym powodem, dla którego dodałem rozszerzenie w moim przykładzie było to, że z bardzo krótkich badań wynikało, że może nie być pewnej metody określania pliku typ z reprezentacji binarnej za każdym razem. – Andrew

3

Jeśli typy wyprowadzone nie dodają żadnych właściwości/metod i masz techniczną możliwość określenia typu, jakiego należy użyć dla danego bajtu [], to nawet nie upubliczniam klas pochodnych. powierzchnia rzeczy, które konsument będzie musiał przeanalizować podczas nauki w bibliotece. Wystarczy mieć statyczną metodę fabryczną, taką jak public static Document OpenDocument(byte[] data) w klasie Dokument.

+0

Dzięki. Pójdę z metodą fabryki zamiast z abstrakcyjną fabryką (co wydaje się przesadą dla tego, co muszę osiągnąć). – Andrew

+0

* "Jeśli typy wyprowadzone nie dodają żadnych właściwości/metod" * To całkiem duże "jeśli". Istnieje wiele rzeczy, które można by zrobić przy użyciu znanego typu pliku, którego nie można zrobić przy pomocy ogólnego "dokumentu". – Servy

+0

@Servy Zgadzam się, ale do celów mojej biblioteki, której nie wskazałem w pytaniu, wszystko, co robi, to wprowadzić pewne modyfikacje danych binarnych.Funkcjonalność jest dość specyficzna, więc w tym przypadku myślę, że założenie jest ok (jedyną potrzebą dla klas pochodnych jest przede wszystkim to, że zmiany i ich implementacja różnią się w zależności od typu pliku). – Andrew