前段时间在论坛看到有个兄弟说面试遇到问他怎么设计一个电梯,他当时回答是有个电梯类,然后有向上,向下方法。然后面试面不是很满意,在论坛里面问,我记得我当时思考了一下回贴说是把接口设计好,有什么安全机制等等这些。然后国庆放假前一个下午没事就想简单写写看,我主要是考虑了接口,但是安全还是没有写入代码里面,当时的想法是电梯下面还会有安装机制,意外的情况下怎么处理等等,但是说来容易,写起来也是不易啊。现在调了两次能基本调通也算不错了。如果真正的一个电梯程序确实应该很复杂,因为还要后面的扩展,比如两个电弟同时使用等情况。下面是最简单的实现的初步,有好多问题没有考虑进去。
/// <summary> /// 内部操作 /// </summary> interface IKeyBoard { //正楼层数 int Count { get; set; } //负楼层数 int NegCount { get; set; } //当前几楼 int CurrentNum { get; set; } //点击楼层 void Click(int num); //双击楼层 void DoubleClick(int num); //关门 void Open(); //开门 void Close(); //紧急信号 void Call(); //紧急电话 void Tell(string info); } /// <summary> /// 外部操作 /// </summary> interface IOutKeyBoard { //正楼层数 int Count { get; set; } //负楼层数 int NegCount { get; set; } //当前几楼 int CurrentNum { get; set; } //上 void Up(); //下 void Down(); //停电梯 void Stop(string key); //开电停门 void Open(string key); }
这部分代码就是主要的接口,也是平时我们看到电梯能操作到的地方。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
/// <summary> /// 电梯 /// </summary> public class Elevator { public Room room; public Way way; public Elevator(int count, int negCount) { way = new Way(count, negCount); room = new Room(count, negCount); way.Room = room; } } /// <summary> /// 电梯间 /// </summary> public class Room : IKeyBoard { public int Count { get; set; } public int NegCount { get; set; } public int CurrentNum { get; set; } public Room(int count, int negCount) { onNums = new List<int>(); isRun = false; isOpen = false; Count = count; NegCount = NegCount; } public void Click(int num) { if (!onNums.Contains(num)) { onNums.Add(num); if (num > CurrentNum) direction = 1; else direction = 0; Run(); } } public void DoubleClick(int num) { if (onNums.Contains(num)) { onNums.Remove(num); } } public void Open() { isOpen = true;//开门 Show("开门"); } public void Close() { isOpen = false;//关门 Show("关门"); } public void Call() { throw new NotImplementedException(); } public void Tell(string info) { throw new NotImplementedException(); } private List<int> onNums; public List<int> OnNums { get { return onNums; } set { onNums = value; } } private bool isRun;//运行状态 private bool isOpen;//门是否打开 private int direction; //方向 0向下 1向下 public int Direction { get { return direction; } set { direction = value; } } //核心方法 public void Run() { if (!isRun) { isRun = true; if (onNums.Count > 0 && !isOpen) { while (isRun) { //用循环摸拟 if (direction == 1) { CurrentNum++; if (CurrentNum == 0) CurrentNum++; } else { CurrentNum--; if (CurrentNum == 0) CurrentNum--; } Show("运行"); if (onNums.Contains(CurrentNum)) { isRun = false; Open(); onNums.Remove(CurrentNum); Thread.Sleep(2000);//2称后关门 Close(); isRun = true; } if (onNums.Count <= 0) { Stop(); break; } if (CurrentNum >= Count) { if (onNums.Count > 0) direction = 0; else Stop(); } if (CurrentNum <= NegCount) { if (onNums.Count > 0) direction = 1; else Stop(); } } } } } public void Stop() { isRun = false; isOpen = false; } private void Show(string tip = "") { Console.WriteLine("{4}:{0}楼,电梯运行状态:{1},门状态:{2},运行方向:{3}", CurrentNum, isRun ? "运行" : "停止", isOpen ? "开" : "关", direction == 1 ? "上" : "下", tip); } } /// <summary> /// 轨道 /// </summary> public class Way : IOutKeyBoard { public int Count { get; set; } public int NegCount { get; set; } public int CurrentNum { get; set; } public Room Room { get; set; } public Way(int count, int negCount) { Count = count; NegCount = negCount; CurrentNum = 1; } public void Up() { Room.OnNums.Add(CurrentNum); if (CurrentNum > Room.CurrentNum) Room.Direction = 1; else Room.Direction = 0; Room.Run(); } public void Down() { Room.OnNums.Add(CurrentNum); if (CurrentNum > Room.CurrentNum) Room.Direction = 1; else Room.Direction = 0; Room.Run(); } public void Stop(string key) { if (key == "KEY") { Room.Stop(); } } public void Open(string key) { if (key == "KEY") Room.Open(); } } }
这部分是就是一坨死一样的代码,实现电梯的基本功能,不过确实没有时间来重构了。主要说说这部分丑陋的地方,1.电梯的运行机制丑陋,用的++,--用循环来实现,没有直实的以现实电梯的运作模式来操作,没有处理好异步等,实际是电梯内按键都是异步的。2.功能没有分细,只是用了两个类来实现,如果细分一下可能会好一些。3.里面有些if的判断确实没有处理好,比如方向的处理,这个就是最实没有设计进去,后面调试加入的,所以会感觉很不协调。
简单测试和结果
//场景1 // 3楼有人要上10楼,12楼有人要下1楼 Elevator elevator = new Elevator(32, 2); elevator.way.CurrentNum = 3; elevator.way.Up(); elevator.room.Click(10); elevator.way.CurrentNum = 12; elevator.way.Down(); elevator.room.Click(1);
总结:练练手,写写shi代码。