黒馬プログラマーjava-交通灯管理システム『十』


――Javaトレーニング、Androidトレーニング、iOSトレーニング、.Netトレーニング、お客様とのコミュニケーションを楽しみにしています!――
1、交通灯管理システムの原理と分析
まずその動作原理を理解して、車を習ったばかりなので、交通灯がどのように動いているのかは大体分かりますが、一般的には車が右に曲がるのは明かりを見なくてもデフォルトで、直接右に曲がることができます.
しかし、交通に矢印が表示されている場合もあるので、私たちはこのような状況を考えません.では、デフォルトの右折ランプはずっと緑です.東西南北の四つの方向によって
の車にはそれぞれの3つの路線があり、道理で東南西北の4つの方向にはそれぞれの3つの方向の交通灯がある.車側から考えると12(3 x 4)の路線がありますが、
対応する交通灯も12個あります.一つの方向から議論すると、例えば南(South)の方向には、右に曲がる(つまり南から東へ)のは理にかなっていない3つのケースがあります.
直進(南から北)と左折(南から西)が残り、直進のランプが緑になったと仮定すると、対応方向(北から南)も緑になります.直進のランプが赤くなると、対応方向
(北から南へ)も赤くなり、次のランプを左に曲がる(南から西へ)と緑になります.他の方向もそう分析されています.
2、車とランプとランプ制御の分析
車:12種類の路線の車は時間ごとにこの路線に車を追加して、毎秒現在の方向の明かりが緑になっているかどうかを検査して、どのように緑になったら現在の方向の車は削除します.
ランプ:12方向のランプ、南(South)方向、3つのケースがあり、右折(つまり南から東へ)は理にかなっていないので、直進(南から北へ)と左折(南から西へ)が残り、
直進するランプが緑になったとすると、対応する方向(北から南)も緑になります.直進するランプが赤くなると、対応する方向(北から南)も赤くなり、次のランプが左折(南から西)すると緑になります.基本的には各方向のランプは2つの関連する方向のランプに関連付けられます.
道:全部で12種類の路線があります.各路線は同じ方向の車に対応しなければなりません.
3、対象思想に向けて交通灯システムを設計する
(1)ランプ:これはカスタマイズの一種であることは明らかであり、最も良い実現方法はjavaの列挙クラスで実現される.
各Lamp要素は一方向のランプを表し、全部で12方向あり、全部で12個のLamp要素がある.
いくつかの方向のランプがあり、2つごとに1つのグループを形成し、1つのグループのランプが同時に緑になるか赤くなるので、プログラムコードは各グループのランプの1つを制御するだけでよい:s 2 n,n 2 s s s 2 w,n 2 e e 2 w,w 2 e
             e2s,w2n   s2e,n2w  e2n,w2s.上の最後の2行のランプは仮想的で、南から東へと西から北へ、そしてそれらの対応方向が信号の制御を受けないため、
だから、いつも青信号だと想像することができます.だから全部で12個のlamp要素があり、実際には4組のランプ、すなわち4方向のランプが使われています.Lamp元素の構造方法には上記の分析があるはずです
の2つの関連する方向のランプ、もう1つの自分のランプの状態の値(falseあるいはtrue)があります.ランプは自分のランプの状態を判断する方法があるべきで、緑になって赤くなる方法があります.
ランプのコードは次のとおりです.
public enum Lamp {

/*                 */

S2N("N2S","S2W",false),S2W("N2E","E2W",false),E2W("W2E","E2S",false),E2S("W2N","S2N",false),

/*                   ,   “     ” “    ”     !*/

N2S(null,null,false),N2E(null,null,false),W2E(null,null,false),W2N(null,null,false),

/*                       ,  ,          */

S2E(null,null,true),E2N(null,null,true),N2W(null,null,true),W2S(null,null,true);

 private Lamp(String opposite,String next,boolean lighted){

this.opposite = opposite;

this.next = next;

this.lighted = lighted;

}

  /*       */

private boolean lighted;

/*             */

private String opposite;

/*             */

private String next;

public boolean isLighted(){

return lighted;

}

 /**

 *       ,           

 */

public void light(){

this.lighted = true;

if(opposite != null){

Lamp.valueOf(opposite).light();

}

System.out.println(name() + " lamp is green,       6          !");

  }

  /**

 *       ,          ,            

 * @return         

 */

public Lamp blackOut(){

this.lighted = false;

if(opposite != null){

Lamp.valueOf(opposite).blackOut();

}

  Lamp nextLamp= null;

if(next != null){

nextLamp = Lamp.valueOf(next);

System.out.println("   " + name() + "-------->   " + next);

nextLamp.light();

}

return nextLamp;

}

} 

(2)ルート:合計12のルートがあります.つまり、12のインスタンスオブジェクトを生成し、各ルートに新しい車両をランダムに追加し、車を1つのセットに追加して保存することができます.
処理します.各路線は1秒ごとに本路線を制御するランプが緑かどうかをチェックし、本路線保存車の集合中の最初の車を削除します.つまり、車が交差点を通ったことを示します.
道の類、道は自分の路線の名前があって、路線の上の車の名前は同じで、すべて文字列で表すべきで、例えば“s 2 n”、車両が絶えずランダムに道を行く過程はスレッドで実現するのが最も良いです、
車両を追加する過程はforサイクルで実現できる.追加車両がある以上は車両を削除し、現在の路線のランプが緑かどうかを毎秒チェックするのでスレッドで実現し、
現在の路線のランプが緑かどうかを判断し、緑であれば一番前の車両、すなわち第1部車を削除します.
道路のコードは次のとおりです.
public class Road {

private List<String> vechicles = new ArrayList<String>();

   private String name =null;

public Road(String name){

this.name = name;

  //             

ExecutorService pool = Executors.newSingleThreadExecutor();

pool.execute(new Runnable(){

public void run(){

for(int i=1;i<1000;i++){

try {

Thread.sleep((new Random().nextInt(10) + 1) * 1000);

} catch (InterruptedException e) {

e.printStackTrace();

}

vechicles.add(Road.this.name + "_" + i);

}

}

 });

 //              ,       

ScheduledExecutorService timer =  Executors.newScheduledThreadPool(1);

timer.scheduleAtFixedRate(

new Runnable(){

public void run(){

if(vechicles.size()>0){

boolean lighted = Lamp.valueOf(Road.this.name).isLighted();

if(lighted){

System.out.println(vechicles.remove(0) + " is traversing !");

}
}
}
},
1,
1,
TimeUnit.SECONDS);
 }
}

(3)ランプの制御類:10秒ごとに現在の青信号を赤信号に変更し、次の方向のランプを緑に変更する.だからスレッドでも実現しなければなりません.
コードは次のとおりです.
public class LampController {

private Lamp currentLamp;

public LampController(){

//            ;

currentLamp = Lamp.S2N;

currentLamp.light();

/*  10          ,           */

ScheduledExecutorService timer = Executors.newScheduledThreadPool(1);

timer.scheduleAtFixedRate(

new Runnable(){

public  void run(){

System.out.println("  ");

currentLamp = currentLamp.blackOut();

}

},
10,
10,
TimeUnit.SECONDS);

}
}

(4)起動プログラム:
public class MainClass {

  public static void main(String[] args) {

 /*  12      */

String [] directions = new String[]{

"S2N","S2W","E2W","E2S","N2S","N2E","W2E","W2N","S2E","E2N","N2W","W2S"

};

for(int i=0;i<directions.length;i++){

new Road(directions[i]);

}

 /*         */

new LampController();

}
}

まとめ:
難点:
               1.交通システムの業務論理は分かりにくい.
               2.処理する各種交通状況は比較的に多く,列挙類を用いて各状況を細分化する必要がある
               3.どのようにオブジェクト向けの思想で考えるか:どのようにクラスを設計するか、およびクラスの属性と行為.クラスとクラスの間にはどのような関係と相互影響がありますか.