Quando le sottoclassi sono ridondanti?

3

Sto lavorando a un progetto ML che coinvolgerà malware e voglio rappresentare i file statistici utilizzati per addestrare il classificatore tramite oggetti StatsFile. Tuttavia, mi chiedo se dovrei usare un IStatsFile e una sottoclasse come tali:

IStatsFile
TrainingMWStatsFile
TrainingBWStatsFile
TestingMWStatsFile
TestingBWStatsFile

Ora i file MW e BW ei file di test e di addestramento non hanno alcuna differenza fondamentale tranne il modo in cui vengono utilizzati dal sistema. Quindi fondamentalmente tutti questi ereditano solo i metodi dalla classe base e non contengono codice aggiuntivo.

Questo è eccessivo? Sarebbe meglio avere uno StatsFile che contenesse queste informazioni in variabili? cioè:.

statsfile.training = True
statsfile.MW = true

Il mio istinto è dire che il secondo modo è migliore. Ma mi piace davvero essere in grado di fare quanto segue:

if type(statsfile) is not MWStatsFile:

vs

if statsfile.MW == false

Pensieri sulle migliori pratiche qui?

    
posta user123959 10.09.2015 - 18:51
fonte

1 risposta

3

In realtà, in entrambi i casi è meglio.

Penso che il vero problema non abbia origine nella gerarchia delle classi IStatsFile. Il codice che contiene le dichiarazioni if che testano gli oggetti del file delle statistiche per quale tipo sono sono da biasimare per questo. Hai un file di statistiche, ma molte cose diverse che puoi fare con esso. Il Pattern di strategia può aiutarti qui.

Da Wikipedia :

In computer programming, the strategy pattern (also known as the policy pattern) is a software design pattern that enables an algorithm's behavior to be selected at runtime.

...

For instance, a class that performs validation on incoming data may use a strategy pattern to select a validation algorithm based on the type of data, the source of the data, user choice, or other discriminating factors. These factors are not known for each case until run-time, and may require radically different validation to be performed. The validation strategies, encapsulated separately from the validating object, may be used by other validating objects in different areas of the system (or even different systems) without code duplication.

Un altro, probabilmente più comune, utilizzo del Pattern strategico è la formattazione dei messaggi di registro. Considera i messaggi di log con queste informazioni:

  • Livello log: INFO
  • Messaggio: "The quick brown fox"
  • Data: "2015-09-10 01:05 PM EDT"

Esistono formati numerici in cui è possibile registrare queste informazioni in un file:

INFO 2015-09-10 01:05 PM EDT: The quick brown fox

[INFO, 2015-09-10 01:05 PM EDT] The quick brown fox

INFO (2015-09-10 01:05 PM EDT) The quick brown fox

E la lista continua. Il modello di strategia può essere utilizzato per fornire la classe del logger con una strategia di formattazione, quindi la modifica del formato dei file di registro non richiede la modifica della classe del logger stesso. Fornisci un oggetto di strategia formato diverso.

Un esempio di codice rapido è in negozio. Le interfacce sono un buon punto di partenza per il modello di strategia, in quanto astrae l'implementazione della strategia, che è l'intero punto del modello strategico:

public interface LogFormatStrategy {
    String formatLogMessage(String level, String message, LocalDateTime date);
}

(Nota, sto usando Java per questo esempio)

L'interfaccia LogFormatStrategy è semplice. Specifica solo un singolo metodo per fare ciò che deve fare.

Ora possiamo creare tutti i log formatter che vogliamo:

// [INFO, YYYY-MM-DD HH:MM:SS] The quick brown fox
public class SquareBracesLogFormatStrategy implements LogFormatStrategy {
    public String formatLogMessage(String level, String message, LocalDateTime date) {
        return "[" + level.toUpperCase() + ", " + date + "] " + message;
    }
}

// INFO (YYYY-MM-DD HH:MM:SS) The quick brown fox
public class ParenthesisLogFormatStrategy implements LogFormatStrategy {
    public String formatLogMessage(String level, String message, LocalDateTime date) {
        return level.toUpperCase() + " (" + date + ") " + message;
    }
}

// INFO YYYY-MM-DD HH:MM:SS The quick brown fox
public class SimpleLogFormatStrategy implements LogFormatStrategy {
    public String formatLogMessage(String level, String message, LocalDateTime date) {
        return level.toUpperCase() + " " + date + " " + message;
    }
}

E una classe di Logger rapida e per lo più incompleta per utilizzare le strategie di formato:

public class Logger {
    private LogFormatStrategy formatter;

    public Logger(LogFormatStrategy formatter) {
        setFormatter(formatter);
    }

    public void info(message) {
        String logMessage formatter.formatLogMessage("INFO", message, LocalDateTime.now());

        // write logMessage to a file
    }

    public void setFormatter(LogFormatStrategy formatter) {
        this.formatter = formatter;
    }
}

Ora possiamo accedere a diversi formati con lo stesso oggetto logger o dare a due differenti oggetti logger strategie di formato differenti.

Logger logger = new Logger(new SimpleLogFormatStrategy());

// INFO YYYY-MM-DD HH:MM:SS The quick brown fox
logger.info("The quick brown fox");

logger.setFormatter(new SquareBracesLogFormatStrategy());

// [INFO, YYYY-MM-DD HH:MM:SS] The quick brown fox
logger.info("The quick brown fox");

Questo modello di progettazione allevierebbe, se non eliminerà, la necessità di sottoclassi.

    
risposta data 10.09.2015 - 19:40
fonte

Leggi altre domande sui tag