2015-04-01 75 views
2

我有类地址的实例,这是我具有根据环境来改变选择算法类别与子类SiteA,SiteB和SiteC
3)语言:基类与子类语言A和语言B
每个子类定义约束地址修改的约束。
问题是每个元组(Region,Site,Language)都必须定义自己的修饰符。JAVA:基于多个尺寸

所以,我有一个方法调整(地址一,区域R,站点S,语言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") 
    } 
} 

什么是最好的设计模式在这种情况下使用?

+0

你能给的'调整()'的例子吗?当你说“每个元组(区域,网站,语言)必须定义自己的修饰符”时,你的意思是一个元组修饰符不是每个元素修饰符的组合? – 2015-04-01 13:38:32

+0

用示例 – AndreyP 2015-04-01 14:25:20

回答

1

这是典型的商业“逻辑”与许多案件/规则。它为此付出了声明性的解决方案。

<rule> 
    <when category="Region" value="Russia"/> 
    <when category="Site" value="MailRu"/> 
    <action category="Address" value="abc"/> 
</rule> 

这使得构建在诊断,完整性检查,日志破获案件,使历史日志将来对未来错误报告分析。

它可能更具可读性。可以转换为一个漂亮的HTML表格层次结构,用于管理员级文档。


它归结为一个事实,即你的代码是程序性的,没有可能性存储所采取的控制流动路径。模型驱动的方法可以缓解这种情况。一个DSL是可行的,但我发现一个免费的表单数据方法更有创意,直接。

+0

+1修改了问题。您的解决方案可以设置不同的地址格式吗?这真的很有趣。 OP刚刚举了一个不好的例子。 – mike 2015-04-01 19:30:50

+0

...是的,它应该是:D – mike 2015-04-01 19:42:13

2
  • 使用多态性宽松的if S和instanceof小号!
  • 使用abstract factory pattern可以更轻松地创建街道信息。

RegionLanguage是(子)产品(分别是他们的工厂,当你考虑我所采取的方式),用于在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 a = 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()); 
    } 
} 

输出是

Address format: RU 
Famous Street 
USA 
----- 
Address format: EN 
Good Street 
RUS 

这是Address类,你可以看到它代表的街头创作的部分regionlanguage(这没有什么花哨,但你明白了吧)。

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(); 
    } 
    } 
} 

这里还有其他用过的类。我会再补充一些更多的想法。

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"); 
    } 
    } 
}