2017-06-18 89 views
2

我有一個具有各種屬性的類,我想圍繞它們編寫一個包裝方法,以便更容易地環繞它們。返回一個集合或單個值的方法

一些屬性返回值的收集,有的值。我正在尋找最佳方法。

我的第一種方法是讓包裝方法返回任何屬性getters返回。

public class Test { 

    public Object getValue(String propName) { 
     if ("attr1".equals(propName)) return getAttribute1(); 
     else if ("attr2".equals(propName)) return getAttribute2(); 
     else return null; 
    } 

    public List<String> getAttribute1() { 
     return Arrays.asList("Hello","World"); 
    } 

    public String getAttribute2() { 
     return "Goodbye"; 
    } 

    public static void main(String[] args) { 

     final Test test=new Test(); 

     Stream.of("attr1","attr2") 
       .forEach(p-> { 
        Object o=test.getValue(p); 
        if (o instanceof Collection) { 
         ((Collection) o).forEach(v->System.out.println(v)); 
        } 
        else { 
         System.out.println(o); 
        } 
       }); 
    } 

} 

壞點這種方法是調用者測試自己的結果是否是一個集合與否。

調用方無縫的其他方法是始終返回一個集合,即。包裝函數將單個值包裝到Collection中。這裏有一個HashSet,但我們可以想象一個adhoc,最少1個元素列表。

public class TestAlt { 

    public Collection getValue(String propName) { 
     if ("attr1".equals(propName)) 
      return getAttribute1(); 
     else if ("attr2".equals(propName)) { 
      Set s = new HashSet(); 
      s.add(getAttribute2()); 
      return s; 
     } 
     else 
      return null; 
    } 

    public List<String> getAttribute1() { 
     return Arrays.asList("Hello", "World"); 
    } 

    public String getAttribute2() { 
     return "Goodbye"; 
    } 

    public static void main(String[] args) { 

     final TestAlt test = new TestAlt(); 

     Stream.of("attr1", "attr2") 
       .forEach(p -> { 
        test.getValue(p).forEach(v -> System.out.println(v)); 
       }); 
    } 

性能方面,設計方面......您對這些方法有什麼看法?你有更好的想法嗎?

+0

Guess =你可以有一個只有一個項目的集合嗎? – Marichyasana

+0

你是_just_試圖打印所有的值?沒有其他用途?此外,該類型將始終是「列表」和「字符串」之一嗎?會有其他類型像'int'嗎? – Sweeper

+0

@Marichyasana只有一個項目的集合很容易寫入 – lvr123

回答

0

那麼,您可以將對每個屬性執行的操作傳遞給對象,並讓對象決定如何處理它。例如: -

在類檢驗

public void forEachAttribute(String propName, Handler h) { 
    if ("attr1".equals(propName)) 
     h.handle(getAttribute1()); 
    else if ("attr2".equals(propName)) { 
     getAttribute2().forEach(o -> h.handle(o)) 
    } 
} 

而且隨着功能handle(String s),這不,你想要做什麼一類Handler

如果您不能編輯Test,你也可以移動功能外Test

public void forEachTestAttribute(Test t, String propName, Handler h)... 

性能方面:這消除了一個if從句

設計方面:這消除鑄造,而造成更多的類。

*編輯:它還保留類型安全的,如果存在多種屬性(Stringint等),你可以添加更多的handle -functions,要仍然保持類型的安全性。

+0

這可以工作,如果我不希望從'Handler'得到一些結果...我可以替換2'Function':執行動作並輸出一些結果,一個積累'forEach'結果的結果融入一種價值......不那麼容易。 – lvr123

+0

@ lvr123所以你想'handler.handle()'產生某種結果?一種做法是,將所有這些添加到「收藏」中。另一種方法是將需要結果的代碼放入'Handler'中,但我不知道這是否可行。 – Poohl

0

關於設計,我會重寫你的代碼到這一點:

TestAlt.java

import java.util.*; 
import java.util.stream.Stream; 

public class TestAlt { 

    private Map<String, AttributeProcessor> map = AttributeMapFactory.createMap(); 

    public Collection getValue(String propName) { 
     return Optional 
      .ofNullable(map.get(propName)) 
      .map(AttributeProcessor::getAttribute) 
      .orElse(Arrays.asList("default")); //to avoid unexpected NPE's 
    } 


    public static void main(String[] args) { 

     final TestAlt test = new TestAlt(); 

     Stream.of("attr1", "attr2") 
      .forEach(p -> test.getValue(p).forEach(v -> System.out.println(v))); 
    } 
} 

AttributeMapFactory.java

import java.util.HashMap; 
import java.util.Map; 

public class AttributeMapFactory { 

    public static Map<String, AttributeProcessor> createMap() { 
     Map<String, AttributeProcessor> map = new HashMap<>(); 
     map.put("attr1", new HiAttributeProcessor()); 
     map.put("attr2", new ByeAttributeProcessor()); 
     return map; 
    } 
} 

AttributeProcessor.java

import java.util.Collection; 

public interface AttributeProcessor { 

    Collection<String> getAttribute(); 
} 

HiAttributeProcessor。java的

import java.util.Arrays; 
import java.util.Collection; 

public class HiAttributeProcessor implements AttributeProcessor{ 

    @Override 
    public Collection<String> getAttribute() { 
     return Arrays.asList("Hello", "World"); 
    } 
} 

ByeAttributeProcessor.java

import java.util.Arrays; 
import java.util.Collection; 

public class ByeAttributeProcessor implements AttributeProcessor{ 

    @Override 
    public Collection<String> getAttribute() { 
     return Arrays.asList("Goodbye"); 
    } 
} 

主要的一點是,你擺脫的if-else使用地圖和動態調度報表。

這種方法的主要優點是您的代碼變得更靈活,以進一步的變化。在這個小程序的情況下,它並不重要,而且是一個矯枉過正的問題。但是如果我們談論的是大型企業應用程序,那麼是的,它變得至關重要。

+0

好吧,這與我的TestAlt方法大致相同,您可以將單個項目屬性封裝到一個集合中(在您的示例中,通過Arrays.asList指定一個ArrayList)。剩下的,我不明白它是如何更高效的,因爲您爲每個getValue調用爲每個屬性創建了映射和數組。因此,如果我有10個要循環訪問的屬性,則您將創建10個調用getValue的值,以創建1個map + 10個列表:= 110個集合。雖然我的TestAlt在相同條件下創建了10個集合。 – lvr123

+0

我專注於設計問題,而不是性能。但毫無疑問,你是對的:最好不要創建額外的集合。您可以將映射初始化爲TestAlt的類變量一次。我會相應地編輯我的答案。我想再次強調一下:如果你正在處理不斷增長的代碼庫,那麼我的示例中的設計更可取。新代碼支持,單元測試和補充更容易。它在概念上與您的方法不同,因爲我使用多態而不是if-else語句。 –

相關問題