Ho il compito di implementare lo schema di stato in una delle mie classi. Il compito faceva riferimento a un'implementazione suggerita, e dopo aver esaminato tale implementazione ero confuso poiché ritenevo che fosse privo di senso per la maggior parte delle applicazioni e francamente semplicemente negativo dal punto di vista del design, dal momento che elimina completamente alcuni principi di base del codice software.
Questo è il diagramma di classe dell'implementazione suggerita:
Michiedo:acheservequestaimplementazione?Esso(imo)violachiaramenteidueprincipidiprogettazioneprincipalidell'ingegneriadelsoftware:Renderelecosefacilmentemanutenibiliefacilmenteestensibili.
Aimieiocchi,questaimplementazionenonhaun'estensionefacile(devimodificarel'originedialmenodueclassi,adesempio,perimplementareunnuovostatochetiseidimenticatoquandolohaiimplementatoperlaprimavolta).L'accoppiamentotraquestocodiceeilcodiceclientesembraessereenorme.Serimuoviqualcosainquestomodello,tuttoilcodiceclientsiinterromperà.Sevuoiaggiungerequalcosa,devimodificaretuttoilcodiceclienteperadattare,adesempio,unnuovostato,perchéinuovistatipossonoessereimmessisolotramiteilmetodoenter()dellostatoconcreto,oindirizzandoliainiettarliinilcontrollercheutilizzailmetodochangeState().
Comebonus,puoiaveresolounaportadelgarageintuttoilmondo,dalmomentocheglistatisonopraticamentesingletons.Ilmetodoenter()neglistaticoncretièstatodatoinquestomodo:
publicstaticStateenter(Controllerc){if(m_instance==null)m_instance=new<<concreteStateName>>(c);returnm_instance;}
Oppurepuoiaverepiùportedelgarage,chesiapronotuttecontemporaneamenteseneapriuna.
PerchédovrestimetteretuttiimetodinellaclasseStateastratta?Dov'èilpolimorfismo?Perchéglistaticoncretihannoversionidimetodidilanciovuoteodieccezionichenonhannonullaachefareconillorostato(adesempio,l'interfacciarisultantediOpenavràunmetodo"lock ()", anche se non è possibile bloccare direttamente il garage porta quando è aperta. Devi prima chiuderla). Perché non scegliere un singolo metodo e implementarlo in modo diverso negli Stati concreti, rendendo la cosa facilmente estendibile di nuovo?
È anche (di nuovo, per quanto posso vedere) non realmente mantenibile senza un sacco di problemi. E se tu, dopo un paio di mesi di utilizzo del garage, decidi che uno stato non è solo obsoleto ma sbagliato? Dovrai portarlo fuori, e il metodo secondo in State () con esso, rompendo l'intero codice base che utilizza questa implementazione. Questa è una porta del garage con quattro stati. Non vorrei lavorare su quella cosa se avesse altri stati.
La situazione diventa più confusa quando guardo su Internet: il pattern sembra essere implementato esattamente in questo modo un sacco di volte (per esempio è implementato in questo modo nella nostra Wikipedia nazionale (tedesco)).
La domanda attuale: mi manca qualcosa o è semplicemente brutto? Dato che è così diffuso, penso che potrei mancare qualcosa di ovvio qui.