生活中的模式






4.77/5 (55投票s)
现实生活中的模式 - 设计模式与人而非对象相结合。
引言
在面向对象设计(OO)中,我们为每个对象分配明确的职责。对象就像一个黑盒子,可以接收和发送消息。所有对象共同构成完整的系统。Gang of Four 的设计模式介绍了许多通用的可重用解决方案,用于解决软件设计中常见的问题。我总是将对象之间的交互与涉及人或真实事物的现实生活交互联系起来。环顾四周,您可以看到许多现实生活中的模式示例,但它们是用人而不是真实对象来扮演的。在本文中,我将尝试为您解释一些这些设计模式的现实生活示例。
谁可以阅读本文?
当然,任何能读懂英语的人都可以阅读本文,但目标读者是具有一定软件经验的人。您无需了解任何特定的编程语言,但必须了解一门面向对象语言。此外,您应该熟悉设计模式和设计模式中使用的术语。
组合模式
在组合模式中,您不区分叶节点和组合节点。客户端以相同的方式对待叶节点或组合节点。您可以将此模式与组织关联起来。一个组织包含许多部门。每个部门包含许多项目。每个项目包含许多项目成员。典型的组织结构如下所示。
递归
使组合模式如此美妙的是递归的力量。我可以用同一个组织示例来解释这一点。您想找到支付给组织所有员工的总工资。它等于 CEO 的工资 + 支付给所有部门的工资。部门的工资是多少?它是部门负责人的工资 + 所有项目的工资。项目的总工资是多少?它是项目经理的工资 + 所有项目成员的工资。简而言之,任何东西的工资是它本身的工资 + 它所有子组的工资。
软件场景中的一个典型示例是 XML DOM(文档对象模型)结构。下面显示了一个简单的 XML 结构。
正如您在这里看到的,“employees
”是一个节点。“employee
”是另一个节点,它是 employees
的子节点。employee
中的 name
呢?那也是一个节点。它只不过是一组节点对象。每个节点可以有 n 个子节点。如果我绘制同一个类的类图,它将如下图所示。
如果我根据 XML 文件输入在系统中创建对象的结构,您将拥有一个结构,该结构可以从单个对象到涉及任意数量对象的复杂结构。下面显示了一个典型结构。
为了描述组合模式的优点,我想举一个简单的组织结构为例,如下所示。如果您想找到组织中的员工总数,它是根节点 + 所有子节点的总和。计算递归进行,如下所示。
递归力量的另一个典型示例是 GUI 工具包。例如,Java SWT(标准小部件工具包)。如果您想为对话框应用主题,您需要为对话框 + 所有子组件应用主题。子组件可以是组合节点或小部件本身。如果是小部件,则没有子组件,并且只需要为小部件应用主题。但如果它是组合节点,我们需要为其所有子组件应用主题。现在,子组件可以是小部件或组合节点。循环继续,直到覆盖所有子小部件。
我可以想到的另一个例子是 C++ 中对象的销毁。获取任何没有垃圾回收器的 OO 语言。试想一下,您有一个如下所示的数据结构。每个对象仅引用其子对象,而客户端只知道根节点对象。您将如何销毁所有对象,而不留下任何内存泄漏?只需几行代码即可销毁整个代码。
销毁一个节点 = 销毁其所有子节点,然后销毁自身。
由于子节点也是节点类型,因此循环一直持续到最底层没有子节点为止。
观察者模式
观察者模式的一个典型示例是传统的邮件递送系统。每当有邮件时,邮递员就会来到您家敲门送信。想象一下,如果您每天都要去邮局检查是否有邮件。这会是一个非常低效的系统,因为每个人都需要定期去邮局。通过引入邮件递送机制,这在现实生活中被消除了。
GUI 系统也是如此,如下所示。您的业务逻辑,在这种情况下,磁带播放器,会定期更新所有 GUI 组件,就像邮递员带着邮件来您家一样。对于整个系统来说,让每个小部件定期检查进度会很低效。
观察者模式有两种典型模型,取决于数据的传递方式。它可以是推模型或拉模型。在推模型中,数据随通知一起推送。邮件递送、杂志订阅等是此模型的示例。在拉模型中,客户端会收到关于发生了什么的通知。但是,客户端是否需要检查相关数据是否存在始终是客户端的责任。RSS Feed 是一个例子。每当网站发生变化时,如果您订阅了 Feed,您就会收到通知。但是,是否需要回去查看您是否感兴趣取决于您。
工厂模式和抽象工厂模式
想象一下您正在建造一栋房子,您找到一位木匠来做门。您提供门的尺寸和您的要求,他会为您建造一扇门。在这种情况下,木匠是门的工厂。您的规格是工厂的输入,门是工厂的输出或产品。
现在,考虑一下同样的门。您可以去找木匠,也可以去塑料门店或 PVC 店。它们都是门厂。根据情况,您决定需要找哪种工厂。这就像一个抽象工厂。
适配器
我认为这是一个不言自明的模式。您可以在现实生活中找到许多此模式的示例,最简单的一个,被称为同一名称,是电源适配器。您有交流电源,适配器的职责是提供不同类型的插座,以适应所需的插座。
另一个例子是翻译器,他将一个人说的语言翻译给另一个人。
外观
想象一下您想组织一场婚礼招待会。您需要装饰计划举办活动的场地。您需要一个乐队来演奏一些音乐。您想为大约 100 人组织晚餐,并在晚上为大约 50 人组织小吃。如果您在十年前想组织这样的活动,您需要去找餐饮服务商、音乐剧团,并组织鲜花和装饰人员,等等。二十年前,我们需要去鱼市、肉店、蔬菜市场等地方购买食物的原材料,然后组织一个厨师,这样您就可以为活动准备好一切。现在,有了活动策划者,生活变得更加简单。您只需要去活动策划者那里,告诉他您需要一个装饰有鲜花的场地,为 100 人提供晚餐,为 50 人提供小吃,还需要一个好的乐队在招待会进行时演奏音乐。您不必担心任何事情,他们会处理其余的事情。这是一个典型的外观模式示例。您不必为每项活动与许多不同的对象进行交互。您将获得一个单一的接口,它将充当许多活动的“外观”。这使得客户端的生活更加简单。
外观模式的其他示例包括一站式账单支付店、大组织中的支持部门,它接收各种支持请求等。
装饰器 (Decorator)
装饰器会装饰某些东西。太阳镜就是一个例子。它以光线为输入,去除光线中所有有害的部分,然后将其传递出去。如果您将苹果作为输入给一个系统,而它输出的是橙子,那**不是**装饰器。另一个例子是音乐过滤。
装饰器模式的软件示例是 JAVA I/O。起初,我奇怪为什么我们需要创建这么多对象才能进行文件操作。一段时间后,我才意识到它是多么灵活和美妙。
模板
模板模式的一个典型示例是计算机工程学位课程。它涵盖了一个典型的软件工程师所需的所有基本知识。他不能直接在行业中工作,因为他需要填补特定领域所需的许多空白。但是,他将拥有在课程完成后进入任何软件公司所需的知识。
反应器
最近,我去班加罗尔的一家餐厅吃饭。外面有一个女人,接待所有进入餐厅的人。她微笑着接待了我们,然后带我们进去,帮我们找了一张桌子。她为我们指派了一名服务员,然后又回到接待处等待新客户。她所做的就是接待新访客。她就像一个为多个客户端提供服务的 Web 服务器。在典型的 Web 服务器中,有一个线程只是等待来自客户端的请求。每当有客户端请求时,它就会创建一个单独的线程并将该线程分配给处理请求。该线程在服务完请求后会消失。
结论
您可以在我们日常生活中找到更多类似的现实生活设计模式的例子。如果我们把它们联系起来,我们会更好地欣赏这些模式。其中大多数现实生活模式经过长时间的演变,由聪明的人们为了社会的高效系统而创造。如果我们将其应用到软件系统中,我们可以像周围其他高效系统一样创建高效的软件系统。