Template-Methode

    Template-Methode


    Wenn Sie eine Person fragen müssen, welche Entwurfsmuster sie verwendet hat, nennen aus irgendeinem Grund nur wenige Personen das Muster der Vorlagenmethode. Dies ist wahrscheinlich auf eine Lücke in der Kenntnis der Nomenklatur von Mustern zurückzuführen, da ich mir persönlich kaum vorstellen kann, dass ein mehr oder weniger erfahrener Programmierer niemals ein so praktisches und nützliches Muster verwenden würde. Ich schlage vor, ihn genauer anzusehen.

    Also die Template-Methode. Es hat nichts mit C ++ - Vorlagen zu tun. Dieses Muster ist insofern bemerkenswert, als es sehr einfach, intuitiv und äußerst nützlich ist. Es gehört zur Kategorie der Verhaltensmuster und dient einem einfachen Zweck: der Neudefinition der Schritte eines bestimmten Algorithmus in einer Klassenfamilie, die von dem Basisalgorithmus abgeleitet sind, der die Struktur dieses Algorithmus selbst definiert.

    Angenommen, wir schreiben eine Crypt-Klasse, mit der eine bestimmte Textzeile verschlüsselt werden soll. Die Verschlüsselungsfunktion wird in der Klasse definiert:
    void encrypt() {
        // Установка начальных параметров
        setupRnd();
        setupAlgorithm();
        // Получаем строку
        std::string fContent = getString();
        // Применяем шифрование
        std::string enc = applyEncryption(fContent);
        // Сохраняем строку
        saveString(fContent);
        // Подчищаем следы работы алгоритма
        wipeSpace();
    }
    

    Mit der Pattern-Methode können wir den in der Funktion encrypt () dargestellten Algorithmus verwenden, um mit Zeichenfolgen zu arbeiten, die von verschiedenen Quellen empfangen wurden - von der Tastatur, vom Datenträger gelesen, über das Netzwerk empfangen. Gleichzeitig bleiben die Struktur des Algorithmus selbst und die unveränderlichen Schritte (Einstellen der Anfangsparameter, Bereinigen der Arbeitsspuren und, falls gewünscht, die Verwendung der Verschlüsselung) unverändert. Dies ermöglicht uns:
    1. Wiederverwendungscode, der sich für verschiedene Unterklassen nicht ändert;
    2. Definieren Sie das allgemeine Verhalten einer Unterklassenfamilie mithilfe von einmal definiertem Code.
    3. Zugriffsrechte differenzieren - Bei der Implementierung variabler Algorithmusschritte werden geschlossene virtuelle Funktionen verwendet. Dies stellt sicher, dass solche Operationen nur als Schritte eines modifizierbaren Algorithmus aufgerufen werden (oder vielmehr nicht von abgeleiteten Klassen an dafür ungeeigneten Stellen aufgerufen werden).

    Also ergänzen wir die Crypt-Klasse mit den notwendigen Mitgliedern:
    private:
        void setupRnd() {
            // Некая инициализация алгоритма случайных чисел
            std::cout << "setup rnd\n";
        };
        void setupAlgorithm() {
            // Начальные установки алгоритма шифрования
            std::cout << "setup algorithm\n";
        };
        void wipeSpace() {
            // Удаление следов работы
            std::cout << "wipe\n";
        };
        virtual std::string applyEncryption(const std::string& content) {
            // Шифрование
            std::string result = someStrongEncryption(content);
            return result;
        }
        virtual std::string getString() = 0;
        virtual void saveString(const std::string& content) = 0;
    

    Bitte beachten Sie, dass Funktionen privat sind. Dies ist eine absichtliche Einschränkung ihres Aufrufs, die Sie nicht daran hindert, sie in einer abgeleiteten Klasse zu überschreiben.
    Und tatsächlich eine abgeleitete Klasse - eine Verschlüsselungsdatei auf der Festplatte:
    class DiskFileCrypt : public Crypt {
    public:
        DiskFileCrypt(const std::string& fName)
            : fileName(fName) {};
    private:
        std::string fileName;
        virtual std::string getString() {
            std::cout << "get disk file named \"" << fileName << "\"\n";
            // Прочитать файл с диска и вернуть содержимое
            return fileContent;
        }
        virtual void saveString(const std::string& content) {
            std::cout << "save disk file named \"" << fileName << "\"\n";
            // Записать файл на диск
        }
    };
    

    Es ist bereits klar, dass, wenn Sie angerufen werden
    DiskFileCrypt d("foo.txt");
    d.encrypt();
    

    Der Algorithmus für die Funktion encrypt () wird ausgeführt, und in der Konsole wird Folgendes angezeigt: Der virtuelle Funktionsmechanismus im obigen Beispiel dient ausschließlich zum Anpassen des Verhaltens von Klassen. Indem Sie sie als rein virtuell definieren, können Sie Anforderungen für das Erben von Klassen festlegen. Wenn wir beispielsweise möchten, dass die Erben einen Verschlüsselungsalgorithmus definieren, sollten wir aus der applyEncryption-Klasse eine reine virtuelle Memberfunktion machen.
    setup rnd
    setup algorithm
    get disk file named "foo.txt"
    save disk file named "foo.txt"
    wipe


    Jetzt auch beliebt: