2014-11-14 239 views
0

假設我有兩個對象LightLightSwitch我想做的事是如何共享兩個類之間變量沒有在Java中使用全局變量?

接通LightSwitch然後檢查Light是打開或關閉(在這種情況下,預期的答案是「上」)

注意的是,當開關被接通時該共享變量名current將設置爲true然後Light也將開啓

我感興趣的這個問題是:

  • 如何兩個類(在這種情況下是LightLightSwitch)可以在不使用全局變量(在這種情況下,共享變量current)共享變量的值?
  • 如何實現面向對象的概念,這個簡單的問題嗎?

預期輸出(或只是你喜歡,可以告訴我確定另一個輸出,指示燈開啓/關閉):

switch on: true  // This line just set variable `current` in `LightSwitch` class 
Light is turned on // This line just check that `current` variable in `Light` class is True or false 
switch on: false 
Light is turned off 
+0

聽起來像經典的觀察者設計模式可以適應這裏。 – Avi 2014-11-14 20:23:05

+0

你是什麼意思「全局變量」?你的意思是靜態變量? – Loc 2014-11-14 20:26:22

+0

@LocHa是的,有點像'公共靜態...' – fronthem 2014-11-14 20:30:03

回答

4

有2種方法。

更具體的做法

public class Light implements Switchable{ 
    private boolean on; 

    @Override 
    public boolean isOn() { return on; } 

    @Override 
    public void setIsOn(boolean on) { this.on = on; }  
} 


public class LightSwitch { 

    public void List<Switchable> switchables = new ArrayList<Switchable>(); // A generic list of things that are controlled by the switch. Doesn't have to be lights. 

    public void off() { setState(false); } 

    public void on() { setState(true); } 

    private void setState(boolean state) { 
     for(Switchable switchable: switchables) { 
      switchable.setIsOn(state); 
     } 
    } 
} 

觀察員的做法

observer design pattern可能是一個非常不錯的選擇更多的東西通用的,它實際上是擴展了我之前給的例子。如果你不熟悉它,這是實現事件的一種方式,因此在兩個物體的狀態之間保持聯繫,而當一個物體發生變化時,另一個物體「觀察」這種變化並作出相應的反應。在這種情況下,你的光線會觀察開關。

2

有幾個選擇,雖然在一般情況下,這個優雅的解決方案是完全不使用全局變量,不得私自使用它們:)

Singleton模式

讓單身LightState或什麼 - 讓它的構造PRIVA在工廠類中返回單個靜態光源狀態。然後,每當有人要求「lightstate」,他們將給予相同的值

靜態變量

只是做一個靜態的(私人,吸氣劑)變量在這兩個類中的一個,並有另一個請求它。

Observer模式

應用其他兩種方法之一,但留在國家的負擔,通知正確的代理時的狀態的變化;這樣,代理不負責鏈接到狀態,這使鏈接更簡單和更優雅。

替代地,觀察者可以通知控制器劑,這將隨後用任何操作需要發生,這意味着兩個獨立的元件可以保持完全不知道的共享信息採取相應的行動。

繼承

輕LightSwitch中的一個子類,或者反之亦然?它依賴於使用情況,但可能不是。但是,如果是這樣,您可以創建一個可以訪問的受保護的靜態變量。通過使「最終」包裝對象的這種狀態下,你會確保每nobobdy切換出來,導致混亂的錯誤引用

直接聯繫

有LightSwitch的跟蹤光。您仍然想知道燈的狀態何時從開關以外的某種方式改變,因此觀察者模式仍然可以派上用場。

2

通常,每個LightSwitch連接到一個(或多個)Light(s)。我將開始將Light實例傳遞給LightSwitch(並將其保存爲交換機中的一個字段)。

private Light current; 
public LightSwitch(Light light) { 
    this.current = light; 
    on(); 
} 
public boolean isOn() { 
    return current.isOn(); 
} 
public void on() { 
    current.setOn(true); 
} 
public void off() { 
    current.setOn(false); 
} 
public String toString() { 
    return isOn() ? "switched on" : "switched off"; 
} 

那麼你main()可能看起來像,

LightSwitch switch = new LightSwtich(new Light()); 
System.out.println("Light is: %s%n", switch); 
switch.off(); 
System.out.println("Light is: %s%n", switch); 

輸出將

Light is: switched on 
Light is: switched off 
1

最基本的答案是,在OOP你不同意這樣的變量。 OOP(以及其他模塊化編程範例)的要點之一是封裝。可以根據公共接口如何指定它可以修改或查詢對象。要修改對象的狀態或更改其行爲,必須調用屬於該對象的方法之一。這樣,目標就完全控制着自己的狀態;它知道何時調用它自己的方法,並且這些方法本身能夠修改對象的狀態信息。

擁有一個共享變量會毀掉所有這一切。如果一個變量在兩個對象之間共享,那麼當一個對象分配給變量時,它可以以另一個對象無法控制的方式修改另一個對象的行爲。所以這是要避免的。

相反,其中一個對象需要調用另一個對象的方法。如果您的LightSwitchturnOn方法很可能需要打開Light。最直接的方式做到這一點,我認爲,就是要告訴LightSwitch在其構造它會變成什麼Light上:

public LightSwitch (Light light) { ... } 

,或者如果它控制一個以上的光,

public LightSwitch(Light[] light) { ... } // or use a List or Set or whatever 

然後,構造函數將保存該引用,然後其turnOn方法將調用light.turnOn()。這就是你如何在OOP中處理這個問題,而不是使用共享變量。

1

無論誰教你,都會給你一些壞習慣,使你的Java編程(和OOP)變得困難。

你需要更好的封裝。東西沿線

class Light { 
    ... 
    public void startCurrent(){...}; 
    public void stopCurrent(){...}; 
    public boolean isOn(); 
} 

class Switch { 
    Ligh target; 
    public Switch(Ligh target) {...} 

    public clickOn(){target.startCurrent();} 
    public clickOff(){target.stopCurrent();} 
} 

// now wire it all together 

public static void main(String argv) { 
    Light light = new Light(); 
    Switch switch = new Switch(light); 

    System.out.println("Light is on: " + light.isOn()); 
    switch.clickOn(); 
    System.out.println("Light is on: " + light.isOn()); 
    switch.clickOff(); 
    System.out.println("Light is on: " + light.isOn()); 
} 

這是更面向對象,不需要任何全局變量。

+0

@Arkadity謝謝你的回答你在OOP課上學到了什麼,但我只是覺得如何才能生活在沒有任何意義的開關中。這個案例研究我只關注兩個完全獨立的類,但他們可以互相分享變量。問題是如何? – fronthem 2014-11-14 21:05:23

+0

@ terces907:我的解決方案將解決您的問題:燈和開關之間完全獨立。 – Loc 2014-11-14 21:10:11

+1

燈不「居住」開關。開關是「意識到」光。開關必須切換一些東西,對吧? (實際上,你需要一個可切換的界面)。術語是「組合」(不是我們這裏所擁有的)和「定向聯繫」(我們在這裏有)。 – Arkadiy 2014-11-14 21:16:05

2

查看我的解決方案如果您想要在LightSwitch & Light之間解除耦合。您可以輕鬆地添加/刪除燈之間的聯繫,並切換

燈類:

public class Light { 

    private boolean on; 

    public void setOn(boolean on) { 
     this.on = on; 
    } 

    public boolean isOn() { 
     return on; 
    } 
} 

的LightSwitch類:

public class LightSwitch { 

    private boolean on; 

    private Map<String, SwitchListener> listeners = new HashMap<String, SwitchListener>(); 

    public void switchState() { 
     on = !on; 
     SwitchEvent event = new SwitchEvent(on); 

     for (SwitchListener switchListener : listeners.values()) { 
      switchListener.switchPerformed(event); 
     } 
    } 

    public void addListener(String id, SwitchListener listener) { 
     listeners.put(id, listener); 
    } 

    public void removeListener(String id) { 
     listeners.remove(id); 
    } 
} 

SwitchEvent類:

public class SwitchEvent { 

    private boolean on; 

    public SwitchEvent(boolean on) { 
     this.on = on; 
    } 

    public boolean isOn() { 
     return on; 
    } 
} 

SwitchListener類:

public interface SwitchListener { 

    void switchPerformed(SwitchEvent event); 
} 

使用例如:

public static void main(String[] args) { 

     LightSwitch lightSwitch = new LightSwitch(); 

     final Light light1 = new Light(); 
     final Light light2 = new Light(); 

     lightSwitch.addListener("light1", new SwitchListener() { 

      @Override 
      public void switchPerformed(SwitchEvent event) { 
       light1.setOn(event.isOn()); 
      } 
     }); 

     lightSwitch.addListener("light2", new SwitchListener() { 

      @Override 
      public void switchPerformed(SwitchEvent event) { 

       // Example: light 1 on, light 2 off -- light 1 off, light 2 on 
       light2.setOn(!event.isOn()); 
      } 
     }); 

     // Test switch 
     lightSwitch.switchState(); // light 1 ON, light 2 OFF 

     lightSwitch.switchState(); // light 1 OFF, light 2 ON 
    } 
相關問題