i read tutorials factory abstract factory pattern , saw examples of it. in 1 of tutorials read factory pattern replace major "if" or "switch case" statements , follows open/closed (solid) principles.
in 1 of projects have huge "switch case" wanna replace a(n) (abstract) factory. it's interface based implementing factory shouldn't difficult in examples read in tutorials factory produced single concrete type based on configuration. can point me in right direction how implement factory produce multiple types based on enum follows solid principles replaces large "switch case"....or misinformed , "switch case" moved factory?
code @ moment:
public interface isinglemailprocessor : imailprocessor { mailresult procesmail(mail mail); } public mailresult getmailresult(mail) { isinglemailprocessor mailprocessor; switch (mail.mailtype) { case mailconnector.mailtype.acronisbackup: mailprocessor = new acronisprocessor(); return mailprocessor.procesmail(mail); case ......etc. } }
what have there implemented strategy pattern still valid approach. anyway, if want replace whole switch , make more maintainable can use this
public interface iprocessmail { bool canprocess(mailtype type); mailresult getmailresult(mail mail); } each mail processor implement interface. you'll have
public class mailprocessorexecutor { public mailprocessorselector(ienumerable<iprocessmail> processors) { _processors=processors; } public mailresult getresult(mail mail) { var proc=_processor.firstordefault(p=>p.canprocess(mail.mailtype)); if (proc==null) { //throw } return proc.getmailresult(mail); } static iprocessmail[] _proccache=new iprocessmail[0]; public static void autoscanforprocessors(assembly[] asms) { _proccache= asms.selectmany(a=>a.gettypesderivedfrom<iprocessmail>()).select(t=>activator.createinstance(t)).cast<iprocessmail>().toarray(); } public static mailprocessorexecutor createinstance() { return new mailprocessorexecutor(_proccache); } } //in startup/config mailprocessorexecutor.autoscanforprocessors([assembly containing concrete types]); //usage var mailproc=mailprocessorexecutor.createinstance(); var result=mailproc.getresult(mail); ok, so, point there object in charge of selecting , executing processors. static methods optional, autoscan method searches given assemblies concrete ipocessmail implementations instantiates them. allows add/remove processor , used automatically (no other setup required). there no switch involved , there never be. note gettypesfromderived helper method use (it's part of cavemantools library) , activator requires parameterless constructor. instead of can use di container instances (if you're using 1 or processors have deps)
if you're using di container, don't need createinstance method. register mailprocessorexecutor singleton , inject (pass constructor argument) need it.
Comments
Post a Comment