I agree that it is totally okay if a class has only one method, but recently I have read many blogs saying this is bad OOP and rather procedural coding.
Se una classe ha un solo metodo , di solito è Execute()
o qualcosa di equivalente. La domanda che devi porci è: che cosa stai incapsulando usando una classe, se hai un solo metodo? Ecco perché quei blog dicono che potresti volerlo ripensare.
So my first idea really was to move all those methods into the solution class, but then I thought this would certainly violate the single responsibility principle and also make the class Solution become quite large
Una "responsabilità" è semplicemente una "area di competenza". Le classi sono specializzate in qualcosa. Potrebbero fare più di una cosa con quel qualcosa. Spetta a te capire dove è questo equilibrio. Bob Martin afferma che una responsabilità è una "ragione per cambiare" e che le classi dovrebbero avere una sola ragione per cambiare, ergo una sola responsabilità.
Did I misunderstand the authors of these blog posts?
Sì, l'hai fatto.
Il punto Le convenzioni di codifica ti fanno male è che stiamo affogando nei principi architettonici, e in gran parte non è necessario.
Certo, puoi gettare oggetti GOF e SOLID e FactoryFactoryFactory tutto il giorno. Il tuo castello di carte sarà bello, ma quanto effettivamente funziona?
Oppure puoi scrivere un po 'di codice e fare qualcosa.
L'ho visto in prima persona, in più di un'occasione. Eserciti di sviluppatori che fanno tutto bene, seguendo tutti i più recenti principi architettonici, ma scrivendo software che è assolutamente inflessibile, difficile da ragionare e che richiede l'utilizzo di risme di codice per evolversi.
Nel frattempo, un piccolo team agile sta scrivendo una nuova interfaccia utente per un sistema che utilizza un framework all'avanguardia che, sebbene probabilmente rompa tutti i tipi delle regole architettoniche, consente flessibilità nella progettazione, fa leva su una tonnellata di lavoro fatto da altri, semplifica drasticamente la codifica e riduce il time to market. Può fare tutte queste cose perché è pragmatico, non dogmatico.
Steve Yegge lo illustra meglio di me nel suo "Regno di "Nouns" article :
For the lack of a nail,
throw new HorseshoeNailNotFoundException("no nails!");
For the lack of a horseshoe,
EquestrianDoctor.getLocalInstance().getHorseDispatcher().shoot();
For the lack of a horse,
RidersGuild.getRiderNotificationSubscriberList().getBroadcaster().run(
new BroadcastMessage(StableFactory.getNullHorseInstance()));
For the lack of a rider,
MessageDeliverySubsystem.getLogger().logDeliveryFailure(
MessageFactory.getAbstractMessageInstance(
new MessageMedium(MessageType.VERBAL),
new MessageTransport(MessageTransportType.MOUNTED_RIDER),
new MessageSessionDestination(BattleManager.getRoutingInfo(
BattleLocation.NEAREST))),
MessageFailureReasonCode.UNKNOWN_RIDER_FAILURE);
For the lack of a message,
((BattleNotificationSender)
BattleResourceMediator.getMediatorInstance().getResource(
BattleParticipant.PROXY_PARTICIPANT,
BattleResource.BATTLE_NOTIFICATION_SENDER)).sendNotification(
((BattleNotificationBuilder)
(BattleResourceMediator.getMediatorInstance().getResource(
BattleOrganizer.getBattleParticipant(Battle.Participant.GOOD_GUYS),
BattleResource.BATTLE_NOTIFICATION_BUILDER))).buildNotification(
BattleOrganizer.getBattleState(BattleResult.BATTLE_LOST),
BattleManager.getChainOfCommand().getCommandChainNotifier()));
For the lack of a battle,
try {
synchronized(BattleInformationRouterLock.getLockInstance()) {
BattleInformationRouterLock.getLockInstance().wait();
}
} catch (InterruptedException ix) {
if (BattleSessionManager.getBattleStatus(
BattleResource.getLocalizedBattleResource(Locale.getDefault()),
BattleContext.createContext(
Kingdom.getMasterBattleCoordinatorInstance(
new TweedleBeetlePuddlePaddleBattle()).populate(
RegionManager.getArmpitProvince(Armpit.LEFTMOST)))) ==
BattleStatus.LOST) {
if (LOGGER.isLoggable(Level.TOTALLY_SCREWED)) {
LOGGER.logScrewage(BattleLogger.createBattleLogMessage(
BattleStatusFormatter.format(BattleStatus.LOST_WAR,
Locale.getDefault())));
}
}
}
For the lack of a war,
new ServiceExecutionJoinPoint(
DistributedQueryAnalyzer.forwardQueryResult(
NotificationSchemaManager.getAbstractSchemaMapper(
new PublishSubscribeNotificationSchema()).getSchemaProxy().
executePublishSubscribeQueryPlan(
NotificationSchema.ALERT,
new NotificationSchemaPriority(SchemaPriority.MAX_PRIORITY),
new PublisherMessage(MessageFactory.getAbstractMessage(
MessageType.WRITTEN,
new MessageTransport(MessageTransportType.WOUNDED_SURVIVOR),
new MessageSessionDestination(
DestinationManager.getNullDestinationForQueryPlan()))),
DistributedWarMachine.getPartyRoleManager().getRegisteredParties(
PartyRoleManager.PARTY_KING ||
PartyRoleManager.PARTY_GENERAL ||
PartyRoleManager.PARTY_AMBASSADOR)).getQueryResult(),
PriorityMessageDispatcher.getPriorityDispatchInstance())).
waitForService();
All for the lack of a horseshoe nail.
Se la tua testa fa male a guardarlo, beh ... fa male anche al mio.
Il punto di non creare oggetti che finiscono con 'er' è semplicemente che, se la tua classe termina in er
, è meglio mettere quella funzionalità nell'oggetto reale che la tua classe helper sta aiutando. Questo è tutto.
Un'ultima nota: Non esiste un modo giusto o sbagliato. Esiste solo il modo in cui meglio soddisfa i requisiti software e le esigenze aziendali. Se tutta la cerimonia funziona perché sei un negozio Java, il codice legacy è tutto Kingdom of Nouns e tutti lo comprendono, quindi con tutti i mezzi, continua lungo quel percorso.
Non è l'unico percorso, però.