对于一道面试题的一点看法
2008-07-14 16:21 GUO Xingwang 阅读(3077) 评论(53) 编辑 收藏 举报最近在逛csdn时遇到个关于一道面试题的讨论,觉得很有趣.说的是有位朋友在面试时被问到”电饭煲是如何知道饭已熟了的”问题.(原文和讨论http://topic.csdn.net/u/20080709/17/5262b09f-9d3a-4294-a27c-ac972e2cc34c.html),对于这个问题每个人都有不同的看法.在这里,我主要想谈一下自己对这个问题的一点看法.
我觉得面试官出的这个问题是很有水平的.个人觉得面试官好像在考查应聘者的分析问题和解决问题的能力,在考应聘者的抽象思维,更具体的就是在考应聘者设计模式的应用.面试官想通过这道问题看出应聘者对待问题的一种思维方式.我的分析是这样的(灵感来源于张子阳的大作 <<C# 中的委托和事件>> 中的热水器的案例):我认为这就是一个观察者模式的应用,我们可以简单把电饭煲看成由加热器Heater和控制器Controller(具体构成可能远远不止这两个)两个关键部件组成.加热器只负责加热,不能进行控制.而控制器主要负责使电饭煲跳闸或置于保温状态,它不能加热.在具体了解我的看法之前,我们先来看一下观察者模式的原型,观察者设计模式中主要包括如下两类对象:
Subject:监视对象,它往往包含着其他对象所感兴趣的内容。在这个案例中,加热器就是一个监视对象,它包含着其他对象所感兴趣的内容,那就是temprature字段,假设当这个字段的值到101时,会把数据发给监视它的对象。置于为什么会说假设温度达到101时呢,这里也涉及到一些高中物理方面的知识.加热的对象是水和米的混合物,开始时混合物从某一较低的温度上升,直到上升到100摄氏度(标准大气压下)时就不会上升了,这时水处于沸腾状态(气化),慢慢水干以后,剩下的米饭温度会继续上升直到101度发出通知,之后监视者进行一些处理.
Observer:监视者,它监视着Subject,当Subject中的某件事发生的时候,会告知Observer,而Observer则会采取相应的行动。在本案例中,Observer就是控制器,它采取的行动就是使电饭煲处于保温状态或跳闸。
下面就用观察者模式模拟一下电饭煲的工作吧:
加热器(Subject):
1
public class Heater
2
{
3
private string _name;
4
private int _temperature;
5![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
6
//监视者列表
7
private ArrayList _observers = new ArrayList();
8![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
9
public Heater(string name, int temperature)
10
{
11
_name = name;
12
_temperature = temperature;
13
}
14![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
15
//增加监视者
16
public void AttachListener(Controller observer)
17
{
18
_observers.Add(observer);
19
}
20![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
21
//删除监视者
22
public void DetachListener(Controller observer)
23
{
24
_observers.Remove(observer);
25
}
26![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
27
//煮米饭
28
public void BoilRice()
29
{
30
for (int i = _temperature; i <= 101; i++)
31
{
32
_temperature = i;
33
Thread.Sleep(1);//为观察结果方便
34
Console.WriteLine("当前温度{0},正在上涨!", _temperature);
35![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
36
//当温度超过100时发出通知
37
if (_temperature > 100)
38
{
39
foreach (Controller c in _observers)
40
{
41
c.Shutdown();
42
}
43
}
44
}
45
}
46![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
47
public string Name
48
{
49
get { return _name; }
50
set { _name = value; }
51
}
52![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
53
public int Temperature
54
{
55
get { return _temperature; }
56
set { _temperature = value; }
57
}
58
}
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
2
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
3
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
4
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
5
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
6
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
7
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
8
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
9
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
10
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
11
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
12
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
13
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
14
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
15
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
16
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
17
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
18
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
19
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
20
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
21
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
22
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
23
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
24
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
25
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
26
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
27
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
28
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
29
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
30
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
31
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
32
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
33
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
34
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
35
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
36
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
37
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
38
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
39
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
40
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
41
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
42
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
43
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
44
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
45
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
46
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
47
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
48
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
49
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
50
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
51
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
52
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
53
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
54
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
55
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
56
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
57
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
58
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif)
控制器(Observer):
1
public class Controller
2
{
3
private string _name;
4
private Heater _sender;
5
6
public Controller(string name, Heater sender)
7
{
8
_name = name;
9
_sender = sender;
10
}
11![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
12
//监视者处理通知
13
public void Shutdown()
14
{
15
Console.WriteLine("我是{0},{1}目前的温度为{2}", _name, _sender.Name, _sender.Temperature);
16
}
17
}
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
2
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
3
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
4
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
5
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
6
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
7
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
8
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
9
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
10
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
11
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
12
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
13
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
14
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
15
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
16
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
17
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif)
测试主程序:
1
class MainApp
2
{
3
static void Main()
4
{
5
Console.Read();
6![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
7
Heater h = new Heater("加热器", 80);
8![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
9
h.AttachListener(new Controller("控制器", h));
10![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
11
h.BoilRice();
12![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
13
Console.Read();
14
}
15
}
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
2
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
3
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
4
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
5
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
6
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
7
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
8
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
9
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
10
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
11
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
12
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
13
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
14
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
15
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif)
输出结果:
这是我对电饭煲工作原理的理解,由于每个人的世界观是不同的,对同一事物的理解可能千差万别.不知道大家是怎么看的!
总结:为什么我们要面向对象设计,为什么要使用设计模式.主要就是面向对象设计可以非常好的描述出事物本来的面目.事物的存在就有它存在的理由,这是自然规律,所以按照事物本身的特征去描述它自然也就是合理的.软件设计就是如此.
希望这篇文章能给大家在应用设计模式和解决问题方面带来收获!
为了方便还是附上源码:/Files/Thriving-Country/Observer20080714/Observer.rar
【作者】:GUO Xingwang
【来源】:http://thriving-country.cnblogs.com/
本文版权归作者和博客园共同所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接。
【来源】:http://thriving-country.cnblogs.com/
本文版权归作者和博客园共同所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接。