Frage

Was ist der Unterschied zwischen dem Schreiben von Unterfunktionen und dem Einfügen aller Funktionen in eine Datei im Vergleich zum Schreiben von Paketen?Ist objektorientiert in Bezug auf Perl besser als prozedural?

Grundsätzlich nach Beispielen für Szenarien suchen, in denen OO besser als prozedural ist.

Danke!

War es hilfreich?

Lösung

Um nur zu verdeutlichen, ist der Unterschied zwischen prozeduralem und OO nicht der gleiche wie der Unterschied zwischen dem Einfügen des gesamten Codes in eine Datei und dem Einfügen in separate Module. Sie können separate Module haben, die voll von Funktionen sind, die Sie prozedural aufrufen.

Wenn die Verwendung von Modulen, OO oder Prozedur, von Vorteil ist, wenn der Code wiederverwendet werden soll oder wenn es sich nur um eine große Codebasis handelt. Wenn Sie ein CMS mit 10 verschiedenen CGI-Skripten haben, die alle mehrere der gleichen Aufgaben ausführen, z. B. das Überprüfen einer Benutzersitzung, ist es sinnvoll, diesen Code in ein separates Modul zu stellen, anstatt ihn in jedem CGI neu zu schreiben. Wenn es sich um eine 20-Zeilen-Funktion handelt, die für dieses Skript spezifisch ist, belassen Sie sie in derselben Datei.

Ob Sie sich für OO oder ein Verfahren entscheiden, hängt davon ab, was Sie tun. Die meisten Leute werden heutzutage die meiste Zeit OO bevorzugen. Ich stimme ihnen zu, da ich der Meinung bin, dass es Ihnen hilft, logisch über Ihren Code nachzudenken und die Dinge auf eine vernünftige Weise zu gruppieren, die später einfach zu verwalten und zu aktualisieren ist.

Andere Tipps

Ich möchte so viel Code wie möglich in Module einfügen. Das Schöne an Modulen ist, dass Sie die Testwerkzeuge von Perl (beweisen und testen :: mehr) verwenden können, um Unit-Tests einfach zu schreiben und zu verwalten. Wenn sich also fast der gesamte Code in Modulen befindet, kann fast der gesamte Code getestet werden.

Wenn ich ein Skript schreibe, möchte ich einen Thin Wrapper haben, der Konfigurations- und Befehlszeilenoptionen in meinem Skript analysiert (wahrscheinlich mithilfe von Modulen wie Config :: Any oder Getopt :: Long). Das Skript enthält auch eine Unterroutine usage. Ich füge dann eine main-Subroutine hinzu. main ist sehr einfach:

sub main {
    my $cfg = shift;

    my @collected_data;

    for my $file ( @{ $cfg->{files} ) {
        eval {
            my $fh = get_handle_from_file($file);

            my $xyz_data = parse_xyz_data( $fh );

            push @collected_data, extract_data( $xyz_data, $cfg->{filter} );

            1;
        } or do {
            my $e = $@;
            $e = "an unknown error occurred" unless defined $e;

            warn "Error parsing '$file': $e\n";
        };        
    }

    my %summary_data = summarize_data( @collected_data );

    write_summary( $cfg->{summary_target} );

    return;
}

Nahezu alle unterstützenden Unterprogramme würden in einem oder mehreren Modulen ausgeführt.

OOP ist eine gute Möglichkeit, Daten und Verhalten zuzuordnen. Dies kann den Code lesbarer machen und Unordnung reduzieren.

 $foo->eat_something( $sandwich )

ist leichter zu verstehen als:

 eat_something( $sandwich, $likes_salty, $likes_sour, $likes_sweet, $likes_spicy );

Der ganze zusätzliche Mist ist in praktischen $foo-Objektattributen gebündelt und läuft weiter, ohne den Unteraufruf zu überladen.

Natürlich können Sie Folgendes tun:

eat_something( $foo, $sandwich )

Wobei $ foo nur ein gewöhnlicher Hash von Geschmackspräferenzen ist. Dies ist sowieso im Wesentlichen das, was Perl OO tut. Der Invocant (Objekt- oder Klassenname) wird als erstes Argument an jede Methode übergeben. Sie verlieren bequeme Namespace-, Vererbungs- und dynamische Methodenaufrufe. Von den drei Kosten werden die praktischen Namensräume am meisten vermisst. IMO, Vererbung wird überbewertet und sollte nur selten verwendet werden. Dynamische Methodenaufrufe können aus den gleichen Gründen nützlich sein, aus denen Versandtabellen nützlich sind.

In OO Perl gibt es nichts, was Sie in prozeduralem Perl nicht tun können. Aber OO macht bestimmte Dinge sehr bequem.

Lassen Sie mich zum Schluss mein mythisches Skript im OO-Stil umschreiben (ich werde das OO etwas über Bord gehen, nur zur Veranschaulichung):

sub main { mein $ cfg= shift;

    my $cd = Data::Collection->new();

    for my $file ( $cfg->files ) {
        eval {

            # skip the step of creating a handle first.  The parsing object
            # can take a file and get a handle or could be passed a handle.               

            my $xyz_parser = File::XYZ::Parse->new( file => $file );

            # The parser returns an XYZ::Data object

            my $xyz_data = $xyz_parser->parse;

            $cd->add_data( $xyz_data->extract_data( $cfg->filter );

            1;
        } or do {
            my $e = $@;
            $e = "an unknown error occurred" unless defined $e;

            warn "Error parsing '$file': $e\n";
        };        
    }

    # Skip the step of separate summarization, since the cd object can check if
    # the summary has been done, and if not generate and cache it as needed.

    $cd->write_summary( $cfg->summary_target );

    return;
}

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top