2015-04-01 65 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"); 
    } 
    } 
}