2015-04-01 2 views
2

у меня есть экземпляр класса адреса, которые я должен меняться в зависимости от окружающей среды:
1) Регион: базовый класс с суб-классов региональных веб и RegionB
2) Сайт: основы класс с подклассами SiteA, SiteB и SiteC
3) Язык: базовый класс с подклассами LanguageA и LanguageB
Каждый подкласс определяет ограничения на модификацию адреса.
Проблема в том, что каждый кортеж (Region, Site, Language) должен определять свой собственный модификатор.JAVA: Выбор алгоритма основан на нескольких измерениях

Итак, у меня есть метод корректировки (Адрес в, г, область сайта С, язык л):

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

Можете ли вы привести пример 'регулировки()'? когда вы говорите: «Каждый кортеж (Region, Site, Language) должен определять свой собственный модификатор», вы имеете в виду, что модификатор кортежа не является комбинацией каждого модификатора элемента? –

+0

Изменен вопрос на примере – AndreyP

ответ

1

Это типичная бизнес-логика со многими случаями/правилами. Для этого нужно сделать декларативное решение.

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

Это позволяет строить в диагностике, проверке целостности, бревенчатый обнажение случаев, сделать исторические журналы для будущего анализа на будущих сообщений об ошибках.

Это может быть даже более читаемым. Преобразуется в красивую иерархию таблиц HTML для документации уровня менеджера.

Это сводится к тому, что ваш код является процедурным, без возможности сохранения пути потока управления. Подход, основанный на модели, может облегчить это. DSL будет осуществимым, но я считаю, что метод данных с произвольной формой будет немного более креативным, прямым.

+0

+1. Возможно ли установить различные форматы адресов с помощью вашего решения? Это то, что действительно интересно. ОП просто дал плохой пример. – mike

+0

... да, это должно быть: D – mike

2
  • Использование полиморфизм разреши if с и instanceof сек!
  • Используйте abstract factory pattern для удобства создания информации о улице.

Region и Language являются (суб) продукты (соответственно их заводы, если учесть, как я сделал это), которые используются для создания улицы в 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, как вы можете видеть, что делегаты части создания улицы для region и language (в этом нет ничего особенного, но вы получите точку).

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"); 
    } 
    } 
} 
Смежные вопросы