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.