Uważam, że istnieją dwa powiązane zastosowania kanoniczne: formy i instancje.
A postaci kanonicznej oznacza, że wartości określonego typu środków mogą być opisane lub przedstawione na wiele sposobów, jeden z tych sposobów jest wybrana jako uprzywilejowanych postaci kanonicznej. (Forma ta jest kanonizowana , podobnie jak książki, które wprowadziły ją do Biblii, a inne nie są). Klasycznym przykładem formy kanonicznej są ścieżki w hierarchicznym systemie plików, gdzie do pojedynczego pliku można się odwoływać na wiele sposobów. :
myFile.txt # in current working dir
../conf/myFile.txt # relative to the CWD
/apps/tomcat/conf/myFile.txt # absolute path using symbolic links
/u1/local/apps/tomcat-5.5.1/conf/myFile.txt # absolute path with no symlinks
Klasyczna definicja kanonicznej reprezentacji tego pliku byłaby ostatnią ścieżką. W przypadku ścieżek lokalnych lub względnych nie można globalnie zidentyfikować zasobu bez informacji kontekstowych. Dzięki ścieżkom bezwzględnym można zidentyfikować zasób, ale nie można stwierdzić, czy dwie ścieżki odnoszą się do tej samej jednostki. Mając dwie lub więcej ścieżek przekonwertowanych na ich formy kanoniczne, możesz wykonać wszystkie powyższe czynności, a także określić, czy dwa zasoby są takie same, czy nie, jeśli jest to ważne dla Twojej aplikacji (rozwiąż problem z aliasowaniem ).
Należy zauważyć, że forma kanoniczna zasobu nie jest cechą samej tej konkretnej formy; może istnieć wiele możliwych form kanonicznych dla danego typu, takich jak ścieżki do plików (powiedzmy, przede wszystkim leksykograficznie możliwe ścieżki bezwzględne). Jeden formularz jest po prostu wybierany jako forma kanoniczna z konkretnego powodu aplikacji lub może dowolnie, aby wszyscy mówili tym samym językiem.
Wmuszanie obiektów do ich instancji kanonicznych jest tą samą podstawową ideą, ale zamiast określać jedną „najlepszą” reprezentację zasobu, arbitralnie wybiera jedną instancję klasy instancji o tej samej „treści” co odwołanie kanoniczne, a następnie konwertuje wszystkie odwołania do równoważnych obiektów, aby użyć jednej instancji kanonicznej.
Można to wykorzystać jako technikę optymalizacji czasu i przestrzeni. Jeśli w aplikacji istnieje wiele wystąpień równoważnych obiektów, to zmuszając je wszystkie do rozstrzygnięcia jako pojedynczej instancji kanonicznej określonej wartości, możesz wyeliminować wszystkie z wyjątkiem jednej wartości, oszczędzając miejsce i prawdopodobnie czas, ponieważ możesz teraz porównać te wartości z tożsamością odniesienia (==) w przeciwieństwie do równoważności obiektu ( equals()metoda).
Klasycznym przykładem optymalizacji wydajności za pomocą instancji kanonicznych jest zwijanie ciągów o tej samej zawartości. Wywołanie String.intern()dwóch ciągów o tej samej sekwencji znaków gwarantuje zwrócenie tego samego kanonicznego obiektu String dla tego tekstu. Jeśli przepuszczasz wszystkie swoje ciągi przez ten kanonizator, wiesz, że równoważne ciągi są w rzeczywistości identycznymi odwołaniami do obiektów, tj. Aliasami
Typy wyliczeń w Javie 5.0+ wymuszają na wszystkich wystąpieniach określonej wartości wyliczenia używanie tego samego wystąpienia kanonicznego w obrębie maszyny wirtualnej, nawet jeśli wartość jest serializowana i deserializowana. Dlatego możesz if (day == Days.SUNDAY)bezkarnie używać w Javie, jeśli Daysjest to typ wyliczeniowy. Robienie tego na własnych zajęciach jest z pewnością możliwe, ale należy zachować ostrożność. Przeczytaj Effective Java autorstwa Josha Blocha, aby uzyskać szczegółowe informacje i porady.