我如何根据主管的建议停止设计并开始设计该项目?[关闭]


42

我是一名初级开发人员(约3年经验),在我的工作中,我们正在设计一个新系统。我的首席开发人员将是首席架构师,但是他向我提出挑战,要求我自己(并行)架构系统。

在反复集思广益的想法并提出我认为是架构建议的过程中,我的领导给了我反馈,我所做的大部分工作都是“设计”而不是“架构”。

他将差异描述为架构与实现无关,而设计是对实现的描述。他说我需要脱下设计师的帽子,戴上建筑师的帽子。他给了我一些建议,但我也想问你:

如何摆脱软件设计师模式,开始像架构师那样思考?


以下是我提出的一些“设计” 示例,这些示例被我的领导认为与架构无关:

  1. 我想出了一种用于从系统中加载和卸载资源的算法,我的负责人说算法绝对不是体系结构。
  2. 我想出了系统应该引发的一系列事件以及应该以什么顺序引发它们,但是这似乎也没有将其视为架构。

我似乎陷入了细节之中,没有退后一步。我发现,即使我提出的是体系结构级别的内容,我也经常通过尝试各种实现并仔细研究细节,然后进行概括和抽象来达到目标​​。当我向我的领导描述时,他说我采用了错误的方法:我需要思考的是“自上而下”而不是“自下而上”。


这里是有关该项目的一些更具体的细节

  • 我们正在设计的项目是一个Web应用程序。
  • 我估计大约有10到10万行代码。
  • 我们是一家初创公司。我们的工程团队大约3-5人。
  • 我可以将应用程序与之最接近的是轻量级CMS。它具有类似的复杂性,并且主要处理组件的加载和卸载,布局管理以及插件样式的模块。
  • 该应用程序是ajax-y。用户一次下载客户端,然后根据需要从服务器请求数据。
  • 我们将使用MVC模式。
  • 该应用程序将具有身份验证。
  • 我们不是很在意旧的浏览器支持(哇!),因此我们希望利用现有的最新和最大的支持。(HTML5,CSS3,WebGL ?、媒体源扩展等等!)

这是该项目的一些目标

  • 应用程序需要扩展。在不久的将来,我们的用户数量将达到数百至数千,但我们正在计划数以万计至数百万甚至更多。
  • 我们希望该应用程序永远存在。这不是临时解决方案。(实际上,我们已经有了一个临时的解决方案,而我们正在设计的是长期替代现有的解决方案)。
  • 该应用程序应该安全,因为它可能与敏感的个人信息联系在一起。
  • 应用程序必须稳定。(理想情况下,它在gmail级别左右是稳定的,但不必在火星漫游者的极端位置。)


78
建筑师没有戴帽子,而是构想出抽象的头部保护系统。
乔恩·雷诺2014年

3
您能否分享您想到的东西?我不愿将体系结构描述为与实现无关的……魔鬼总是存在于细节中。就是说,您不希望细节掩盖全局。没有更多信息,很难说出是哪种情况。
Telastyn 2014年

4
别难过,在3年的时间里,我不希望您能够实现他所推动的抽象飞跃。我想他之所以这样做是因为他喜欢您的工作,并且正在通过给您一项任务以帮助您成长和学习的工作,来帮助您指导自己。如果他确实希望您成功完成此任务,直到拥有成功的体系结构,那么他就误以为某人习惯于看到足以被视为体系结构方法的模式所需要的大量经验。
吉米霍法2014年

3
@Daryl:我当然认为值得学习,尽管我会与您的架构师一起找出他实际使用的图表(某些UML的价值值得怀疑)。
罗伯特·哈维

Answers:


26

首先,我要说的是架构和设计之间的区别主要是语义。一些团队在两者之间有检查点。您的技术主管将架构定义为与设计之前相同,并且架构与实现无关。因此,我认为我们所谈论的是瀑布模型中的设计,而不是工业设计,这将帮助您在进入软件体系结构之前设计出具有用户视角的产品。我认为架构通常会渗入设计中,这并不一定是一件坏事,对于架构师而言,深入了解手头系统中可能存在的功能通常非常有帮助。

说了这么多之后,您需要针对所处的情况提供一些建议。那里有整个软件体系结构,论文,书籍,会议,但是您通常在寻找模式和抽象。没有该项目的更多细节,我只能举一个广泛的例子。例如,如果您正在集成中,则有面向服务的体系结构(SOA)模式,您可以将系统的各个部分分成“服务”,以便可以按定义的方式使用每个部分,然后在Web程序中通常将其实现为Web服务(尽管不应仅限于此)以及最近使用JSON的RESTful API的兴起,我还是要说这是一种来自SOA体系结构的设计。我会说模型,视图,控制器(MVC)是常用的体系结构模式的另一个示例,它划分了系统组件的职责以允许替换零件,包含错误和测试。

从10,000英尺的高度来看,如果您可以将其绘制在白板上并向不擅长您的领域并且不了解您的编程语言和当前实现细节的有能力的程序员进行解释,则可能是架构。如果您可以写一本公司以外的人都关心的书,那可能就是体系结构。如果您发现自己的解释细节,并且无法将其推广到其他代码库/公司/行业,则可能是设计问题。

我同意您给出的两个示例是代码设计而不是体系结构。第一个是因为我认为当您说出要加载资源的“算法”时,我想您的意思是您设计了一组指令来完成该任务,而不是设计了他们将在第一年教授的新算法。明年COMSC。在第二个示例中,我再次同意它是设计。如果您向我展示了这些想法中的任何一个,我将无法在我的随机软件项目中使用它们。您必须进入Java的“更高级别”的面向对象(OO),而不是希望Customer类成为Person类的子类。一般而言,即使谈论异常也可以被认为是太低的级别(太接近实现了)。

为了尝试解决您列出的细节,我认为您应该考虑的是如何构建基于Web的CMS。Wordpress有一个站点体系结构规范,在其中他们谈论了很多有关设计实现的细节,但是从帖子中可以很清楚地看出,他们的主要体系结构围绕使Wordpress具有主题可扩展性。为主题设计一个清晰的界面,使其可以由公司外部的某人编写,显然是他们做出的体系结构决定。在设计您的“长期”(非临时)解决方案时,最好记在纸上,以便在开发过程中做出所有设计和实现决策(所有开发人员而不仅仅是建筑师)都是这样的符合这个想法。

您所处架构的其他示例:

  1. 将整个事情放在虚拟机上,托管在云提供商或内部,并具有无状态的机器实例,这样,任何发生故障的机器都可以用虚拟机的新实例替换,而不必跨任何状态复制或丢失任何信息。
  2. 混乱的猿人开始就进行实时生产故障测试 。

也许尝试在白板上绘制整个系统。在不同的细节级别上尝试它,第一块面板可以是GUI-> dispatcher-> backend-> DB之类的东西,然后向下钻取,直到您开始使用代词。


我针对正在处理的项目类型添加了更多的特殊性。(PS谢谢您的回答!我正在处理很多有用的细节。)
Daryl 2014年

2
不需要诸如“更新到地址OP编辑”之类的符号。编辑的完整历史记录维持每一个岗位,包括这一个,你可以在“编辑原因”中的编辑汇总字段中指定一个编辑页面
罗伯特·哈维

1
“对于建筑师了解可能的东西通常非常有帮助”,我认为这是最重要的。我无法想象住在建筑师对木材,混凝土和玻璃的可能性一无所知的建筑物中。知识越深,架构就越令人兴奋和突破。
克里斯·韦瑟林

尽管此处的几乎所有答案都很有帮助,但您的答案可能是最有用的,社区似乎也发现它最有用。
达里尔

16

在我工作的地方,这两个想法之间的区别非常重要。

您所说的“架构”,我们称之为“英语编程”。这一点很重要,因为如果您无法将其描述给非程序员,那可能是错误的。可能是您对问题的理解不够,或者可能是您正在解决“幻像”问题(此处未讨论)。

设计的这两个不同方面所使用的术语通常是不同的,但是原理很容易在任何地方得到认可。一个方面(以您为例,架构师,以我为设计师)为英语编程,而另一个方面(以您为例,设计师为“ designer”,为开发人员)以特定语言编程。它们也通常被称为“设计”和“实现”。“设计”是应该实现的目标,“实现”是实现它的代码。

我研究过的一些例子:

一个程序的体系结构是:我们需要一个中央管理器或集线器,可以轻松地向其中添加模块。该管理器会将事件分发到所有已注册的模块。模块可以在事件管理器中注册自己,从而将事件发布到系统的其余部分,并接收其关心的事件。每个模块都有一个“邮箱”,可以根据需要将其选中并清空。这将使我们能够容纳我们尚不知道的新模块。

那里没有代码。可以用任何语言编写。此描述并不要求实现。

另一个项目的体系结构是:我们需要一种可靠地启动和停止其他程序而无需等待它们的方法。我们可以有一个负责特定程序的经理。我们可以告诉它启动或停止其程序,而经理则负责它。如果要求该另一个程序停止并且没有在给定的时间内运行,则管理器知道如何强制其停止并清理混乱。该程序不会被其他任何程序启动或停止,并且可以询问管理器其程序是正在运行,已停止还是正在等待停止。这使我们可以继续进行我们需要做的其他事情,同时仍然可以正确启动和停止其他程序。

再次强调,这里没有任何内容指示实现,尽管某些实现显然比其他实现更有用。

设计(我们称之为模式或实现)与体系结构(我们称为设计)之间的区别在于,它们之一解决了编码/实现问题,而另一个解决了实际问题。


2
您的自然语言区分很有趣,并且对我的目标很有帮助。谢谢!
达里尔2014年

14

也许这会有所帮助。我一直将工程师的资历视为他们自己可以解决多大的问题。

粗略地讲出这个想法:

  • 您可以给刚接触小型任务的新手,其中包含许多明确的说明,说明该任务如何与其他部分集成

  • 中级开发人员是可以描述应用程序某些部分并使其在该应用程序的上下文中工作的人。

  • 在商店的技术限制内,高级开发人员可以从头开始构建中型应用程序。

  • 一个更高级的开发人员可以做到这一点,并在使用哪种技术使其正常工作的过程中进行技术选择。

...但是这些并不是一成不变的规则。而且有些人以“高级”恕我直言走出了大门,即使他们不得不花一些时间来改头换面。

架构师要问的是要比这个​​问题更普遍地看待问题。如果必须组合许多应用程序才能使系统正常运行:

  • 您需要什么应用程序和服务?
  • 哪些部分与客户交互,哪些部分彼此交互?
  • 他们将如何沟通?
  • 他们将数据存储在哪里?
  • 失败的风险在哪里?
  • 您将如何提供可靠性?
  • 您将如何提供安全性?

因此,从某种意义上说,技术架构就像建筑架构。是布局,还是计划。它显示了各个部分需要什么,它们如何保持在一起,以及为什么重要。

(顺便说一句,我向架构师解释了类似的增长曲线,范围从架构一系列相关应用程序或一组非常复杂的功能到为团队设定技术方向,再到为整个组织制定战略技术决策)

就是说,我认为大多数各级工程师也必须进行一些“架构”。这不是一条明线。听起来,如果您先关注大图,而又不迷上实现细节,那么您将更加符合他的需求。顺便说一句,能够看到“大图片”和“小细节”是该行业的一项巨大资产,因此这听起来像是一个巨大的机会。

...这是一个比喻。假设您被要求创建一个魔术黑匣子。作为工程师,您应该痴迷于Magic Black Box的内部工作原理。但是作为一名建筑师,您的关注点有所不同。你可能会偷看入禁区出于好奇,但你希望缠住一切周围所有的魔术黑匣子。

与该类推类似,您可能会认为架构角色将整个系统视为魔术盒。因此,如果您使用Gigantic Glass Box,然后将客户,客户端应用程序,防火墙,服务层,数据库,甚至是devops放入内部,那么作为架构师,您将着迷于如何制作大型系统盒工作


2

“设计”和“体系结构”之间的确切区别有些主观,并且有些重叠。但是,据我了解,这是不同的:

体系结构着眼于高级概念。谁是系统中的参与者?主要对象是什么,哪些负责?当我想到架构时,我想到的是Visio,而不是代码。

例如,事件系统可能具有事件管理器,该事件管理器接受传入的事件并将其分派给事件处理程序。线程,异步与同步以及其他较低级别的概念在这里不起作用。MVC是另一个示例:在这三个部分如何交互的高层没有指定具体细节,只是存在由单独的代码包处理的三个单独的问题。

设计涉及原型设计,草绘代码接口,代码框架等。它位于抽象体系结构和低级“代码猴子”工作之间。

在事件框架中,设计可能会说“事件使用此接口”和“有一个线程池,事件管理器使用该线程池将事件分派给工作人员”。MVC的设计可能是“将Hibernate用于模型,将Spring用于控制器,将GWT用于视图”。

在进行设计工作时,我已经草绘了接口和代码框架,然后将结果交给程序员。有时我就是那个程序员。但这是两个独立的阶段,两者都比具体存在于架构上。

戴上体系结构帽子意味着您要清除代码的思路,并在白板上考虑对象。考虑对象,包,框架以及它们之间的消息流。如果您只想一行代码,那您就做错了。不要陷入诸如“哦,该消息可能是字符串,或者使用SOAP之类的东西”之类的麻烦。在此级别上,发生通信这一事实就足够了。细节无关紧要。


2

如果我可以在此处添加任何内容,那就是:不要认为code。完全没有

不要考虑如何编写代码来完成某件事,而是考虑实现它的最佳 方法是什么。您对需要做的事情的描述应该与语言无关,因此您将在谈论设计模式-这是使用不同编程语言的用户之间的通用“语言”-讨论如何继续进行。

对于您的特定用例,我认为更多的体系结构问题应遵循以下方面:

  • 为什么要使用MVC?你知道吗?是否有更好的模式可以使用?为什么?
  • 您将使用什么框架,为什么
  • 您将如何扩展?不是代码明智的,因为这无关紧要。水平缩放的条件是什么?您将使用什么服务(AWS)来做到这一点?
  • 身份验证将如何执行?不是代码明智的:您将要在每个请求上生成一个随机的唯一令牌,并根据预期令牌进行检查吗?不要认为您将如何在代码中执行此操作。考虑一下为什么要这样做-因为实际上可以使用任何网络语言来完成。

基本上,根本不谈论代码。即使您不知道怎么做,只要有意愿,就有办法。在担心实际将拼图拼凑在一起之前,请多考虑一下拼图的各个部分将如何最好地组合在一起。


1

考虑一下系统可以执行的所有操作(即用例)。对于每个操作,请记录每个操作在业务领域方面发生的情况。您仅应就您的问题域进行讨论,而不应描述任何实施细节。画一个大块并将其称为“系统”。此“大块”和操作说明的组合是最高级别的系统体系结构。

尽管这种高级体系结构确实提供了一个不错的起点,但在构建实际系统时确实没有多大价值。您必须将其简化为一个详细的级别,才能将其转变为有用的体系结构。

因此,您遵循与“大块”方法相同的一般思想,只是开始添加完成每个操作所必需的“子块”。这些“子块”通常称为域类或模块。通过使用操作说明(大块方法)和绘制序列图,可以轻松识别这些内容。之所以将它们称为域类是因为它们并非旨在成为“真实”类,而是旨在根据系统的问题域来描述您的系统。

创建所有序列图并标识所有“子块”的最终结果是,您现在有了域类及其操作列表。这通常最终导致一个相当可用的软件体系结构,其中每个“子块” /模块都可以打包给不同的开发人员进行设计和实现。

当然,如果您保持原样,则设计人员将在定义模块之间的接口时彼此进行大量交互。因此,架构师还可决定要在模块之间使用的特定接口机制和数据类型。

而且,某些“子块”在引擎盖下仍将非常复杂。因此,可能需要“子块”方法的另一次迭代,但是仅这次是在新识别的模块之一上。

最后,架构师希望系统遵守的接口之间可能存在一些特定的模式/限制(例如,事件回调与直接方法调用),因此在架构设计中需要讨论这些决策。另外,架构师可能希望每个人都可以使用“通用”模块。


0

作为开发人员,您可能习惯于提供解决方案。这是一种非常好的思考方式,但是在考虑架构时可能会妨碍您。

我发现这有助于描述您首先要解决的问题。有什么要求?有什么限制?您能否与利益相关者交谈以找出这些要求?

如果您还可以描述自己的设计目标,则可能会有所帮助。您的解决方案是否需要扩展,还是单用户设计就足够了?您的解决方案需要保持多长时间有效?它是一次性修复还是长期基础架构解决方案?也许同样重要:您的体系结构可接受的限制是什么?

并且由于这是一种学习经历,所以即使他们很傻也不要害怕提出问题。


1
为了更加清晰,我列举了该项目的一些目标。
达里尔
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.