[英]How to share properties between class instances and other possible users of those properties?
假設存在多個實現接口I的類{ C1 , C2 ... ...},其中包括名為getColor() , getName()和move()的方法 。 調用getColor()和getName()時, C1的每個實例都返回相同的值,與C2和實現I的所有其他類相同。 移動也是按類定義的,但受實例變量影響,並且每個實例的行為方式可能不同。 C1類中的getColor()和getName()的實現可能類似於:
public Color getColor() {
return Color.RED;
}
public String getName() {
return "C1!!!";
}
實現該接口的所有對象我可以添加到並繪制到屏幕上。 但是,假設添加這些對象的方式是通過一個帶有按鈕的不同屏幕。 當單擊這些按鈕之一時,它向應用程序發出信號,與單擊的對象相關聯的對象類型應添加到屏幕上。
如果目標是標記與由C1返回的字符串C1相關按鈕的的getName()和彩色按鈕與顏色返回C1的的getColor(),一個可以實例C1的新實例,然后檢索其名稱和顏色以自定義其關聯的按鈕:
...
I instance = new C1();
Button C1Button = new Button();
C1Button.setLabel(instance.getName());
C1Button.setColor(instance.getColor());
...
...然后按照與C1相同的過程實例化C2和C3以及...和C50的新實例。
但是,這似乎很臟,不再為了實現I中的其他方法而實例化這些類,而只是為了獲取按鈕的color和name屬性。 此外,這將是很多代碼。 誰能提供有關如何將color和name屬性與實現I的類分離的建議,以減少實現I的類的數量急劇增加到兩個以上時所需的代碼長度 ? 是否有任何特定的設計模式可以用來解決此問題?
我通常通過創建一個與實現類分開的枚舉來執行此類操作
public enum TypeOfC
{
C1(Color.RED, C1::new),
//you don't have to use different classes for every one!
CX(Color.BLACK, () -> new C1(5)),
C2(Color.BLUE, C2::new);
private final Color m_color;
private final Supplier<I> m_constructor;
TypeOfC(Color color, Supplier<I> ctor)
{
m_color = color;
m_constructor = ctor;
}
public Color getColor()
{
return m_color;
}
public I create()
{
return m_ctor.get();
}
}
然后,您可以制作如下按鈕:
for (TypeOfC t : TypeOfC.values())
{
Button b = new Button();
b.setColor(t.getColor());
b.setLabel(t.name()); // make a different getter if you don't want the enum constant name
b.setAction(()->doWatever(t.create()));
allButtons.add(b);
}
我發現的一個可能答案涉及使用類似類型對象模式的東西。 從概念上講,這與馬特的建議有關。 無需定義多個繼承自I的不同類,只需定義一個類C ,即可在其構造函數中接受另一個類Properties 。 然后,可以從與其關聯的Properties類中檢索C的所有屬性:
public class C implements I {
private final Properties properties;
public C(Properties p) {
this.properties = p;
}
@Override
public Properties getProperties() {
return properties;
}
}
這些屬性都可以在PropertyDictionary中定義。 構造新的C時 ,可以從PropertyDictionary中獲取對象的適當屬性。 這樣,繼承自I的類仍保持相同的功能(盡管使用更改的方法名),並且數據的其他訪問者可以通過查詢PropertyDictionary了解有關C可能取值的信息:
Properties p = new Properties("Class name", Color.YELLER);
I instance = new C(p);
// instance.getProperties().getColor() == p.getColor(); --> True
...
for(Properties prop : PropertyDictionary.getProperties()) {
Button b = new Button();
b.setLabel(prop.getName());
b.setColor(prop.getColor());
}
具有相同屬性的C的多個實例都在PropertyDictionary中引用了相同的Properties實例,有點像在Flyweight中 :
final Properties p = new Properties("Cat", Color.BLACK);
List<I> cats = new ArrayList<>(1000);
// make 1000 black cats:
for(int i = 0; i < 1000; i++) {
cats.add(new C(p));
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.