design patterns - JAVA: Choosing algorithm based on multiple dimensions -
i have instance of class address, have change according environment:
1) region: base class sub-classes regiona , regionb
2) site: base class sub-classes sitea, siteb , sitec
3) language: base class sub-classes languagea , languageb
each subclass defines constraints address modification.
problem each tuple (region, site, language) has define own modifier.
so, have method adjust(address a, region r, site s, language l):
void adjust(address a, region r, site s, language l){ if(r instanceof russia && s instanceof mailru && language instanceof russian){ a.set_street("abc") } else if(r instanceof russia && s instanceof mailru && language instanceof english){ a.set_street("fgh") } }
what best design patter use in case?
- use polymorphism loose
if
s ,instanceof
s! - use abstract factory pattern easier creation of street info.
region
, language
(sub)products (resp. factories, when consider way did it), used create street in address
.
package address.example; public class addressexample { public static void main(string[] args) { languagefactoryprovider lfp = new languagefactoryprovider.languagefactoryproviderimpl(); regionfactoryprovider rfp = new regionfactoryprovider.regionfactoryproviderimpl(); addressprovider provider = new addressprovider(lfp, rfp); address = provider.createaddress("ru", "usa", "famous street"); system.out.println(a.getstreet()); system.out.println("-----"); address b = provider.createaddress("en", "rus", "good street"); system.out.println(b.getstreet()); } }
output
address format: ru famous street usa ----- address format: en street rus
this address class, can see delegates parts of street creation region
, language
(it's nothing fancy, point).
package address.example; import address.example.languagefactoryprovider.language; import address.example.regionfactoryprovider.region; public interface address { public string getstreet(); static class addressimpl implements address { private final region region; private final language language; private final string street; public addressimpl(region region, language language, string street) { this.region = region; this.language = language; this.street = street; } @override public string getstreet() { stringbuilder sb = new stringbuilder(); sb.append(string.format("address format: %s", language.getspecifier())); sb.append(string.format("%n")); sb.append(street); sb.append(string.format("%n")); sb.append(region.getspecifier()); return sb.tostring(); } } }
and here other used classes. i'll add more thoughts time.
package address.example; import address.example.languagefactoryprovider.language; import address.example.regionfactoryprovider.region; public class addressprovider { private final languagefactoryprovider lfp; private final regionfactoryprovider rfp; public addressprovider(languagefactoryprovider lfp, regionfactoryprovider rfp) { this.lfp = lfp; this.rfp = rfp; } public address createaddress(string language, string region, string street) { language _language = lfp.getlanguagefactory(language).createlanguage(); region _region = rfp.getregionfactory(region).createregion(); return new address.addressimpl(_region, _language, street); } }
package address.example; import java.util.hashmap; import java.util.map; public interface languagefactoryprovider { public languagefactory getlanguagefactory(string language); static interface languagefactory { public language createlanguage(); } static interface language { public string getspecifier(); } static class languageimpl implements language { private final string specifier; public languageimpl(string specifier) { this.specifier = specifier; } @override public string getspecifier() { return specifier; } } static class languagefactoryproviderimpl implements languagefactoryprovider { private static final map<string, languagefactory> factories = new hashmap<>(); static { factories.put("en", new englishlanguagefactory()); factories.put("ru", new russianlanguagefactory()); } @override public languagefactory getlanguagefactory(string language) { if (!factories.containskey(language)) throw new illegalargumentexception(); languagefactory factory = factories.get(language); return factory; } } static class russianlanguagefactory implements languagefactory { @override public language createlanguage() { return new languageimpl("ru"); } } static class englishlanguagefactory implements languagefactory { @override public language createlanguage() { return new languageimpl("en"); } } }
package address.example; import java.util.hashmap; import java.util.map; public interface regionfactoryprovider { public regionfactory getregionfactory(string region); static interface regionfactory { public region createregion(); } static interface region { public string getspecifier(); } static class regionimpl implements region { private final string specifier; public regionimpl(string specifier) { this.specifier = specifier; } @override public string getspecifier() { return specifier; } } static class regionfactoryproviderimpl implements regionfactoryprovider { private static final map<string, regionfactory> factories = new hashmap<>(); static { factories.put("rus", new russianregionfactory()); factories.put("usa", new usregionfactory()); } @override public regionfactory getregionfactory(string region) { if (!factories.containskey(region)) throw new illegalargumentexception(); regionfactory factory = factories.get(region); return factory; } } static class russianregionfactory implements regionfactory { @override public region createregion() { return new regionimpl("rus"); } } static class usregionfactory implements regionfactory { @override public region createregion() { return new regionimpl("usa"); } } }
Comments
Post a Comment