Questions tagged «architecture»

软件系统的高级设计和描述。架构设计提取了实现,算法和数据表示的细节,以专注于“黑匣子”组件的交互。

8
将网站设计为高度可扩展的最佳方法是什么?
对于需要高度可扩展性的网站(例如Facebook之类的社交网络),设计网站的最佳方法是什么? 我是否应该具有网站查询的Web服务以获取所需的数据? 要么 该网站应该直接查询数据库吗?(可以使用内置的语言构造来自动填充表格等)。 我认为Web服务是更好的设计,因为它提供了集中的数据访问,并且诸如缓存之类的东西变得更易于控制,但是其他人怎么看?

3
如何构建完全模块化的Web应用程序
在接下来的几个月中,我们将开始一个项目,我们将采用为客户端(v1)构建的系统,并从头开始对其进行重建。v2的目标是使其模块化,以便该特定客户端拥有自己使用的一组模块,然后另一个客户端可以完全使用另一组模块。这里的窍门是,公司A可能具有一系列结帐和用户模块,这些模块会更改系统的工作方式。公司B可能会遵循标准的结帐程序,但会自定义产品的浏览方式。 当您要从头开始构建一个要Core在所有客户端之间共享的应用程序,同时又要为要专门针对客户端修改的内容保持灵活性时,应用程序体系结构有哪些好的方法? 我已经看过CodeIgniter的钩子,并且认为这不是一个好的解决方案,因为我们最终可能会有250个钩子,但仍然不够灵活。还有哪些其他解决方案?理想情况下,我们不需要在沙子上画一条线。

5
微服务和存储过程
在微服务体系结构中,存储过程是否被视为不良做法? 这是我的想法: 大多数有关微服务的书籍建议每个微服务使用一个数据库。存储过程通常在整体数据库上工作。 再次,大多数微服务架构书籍都指出,它们应该是自治的且松散耦合的。使用专门在Oracle中编写的存储过程,可以将微服务与该技术紧密结合。 大多数微服务架构书籍(我已经阅读过)都建议微服务应面向业务(使用域驱动设计(DDD)设计)。通过将业务逻辑转移到数据库中的存储过程中,情况已不再如此。 有什么想法吗?

5
您应该在哪里放置常数,为什么?
在大多数大型应用程序中,通常只有几个“常量”位置: 一类用于GUI和内部内容的内容(制表页标题,组框标题,计算因子,枚举) 一类用于数据库表和列(此部分是生成的代码)以及它们的可读名称(手动分配) 一类应用程序消息(日志,消息框等) 在这些类中,常量通常分为不同的结构。在我们的C ++应用程序中,仅在.h文件中定义常量,而在.cpp文件中分配值。 优点之一是,所有琴弦等都放在一个中央位置,每个人都知道在必须更改某些内容时可以在哪里找到它们。 这尤其是项目经理在人们来来往往时喜欢的东西,这样每个人都可以更改这些琐碎的事情,而不必深入研究应用程序的结构。 另外,您可以轻松地一次更改相似的“组框” /“选项卡页”等的标题。另一个方面是,您可以仅打印该类并将其交给非程序员,该非程序员可以检查字幕是否直观,向用户发送的消息是否太详细或太混乱等。 但是,我看到了某些缺点: 每个类都与常量类紧密耦合 添加/删除/重命名/移动常量需要重新编译至少90%的应用程序(注意:至少在C ++中,不需要更改值)。在我们的一个带有1500个类的C ++项目中,这意味着大约7分钟的编译时间(使用预编译的标头;如果没有它们,则大约为50分钟),再加上大约10分钟的链接到某些静态库。 通过Visual Studio编译器构建速度优化的发行版最多需要3个小时。我不知道是否大量的类关系是源,但也有可能。 您会被迫将临时硬编码的字符串直接转化为代码,因为您想非常快速地测试某项内容,并且不想仅等待15分钟来进行该测试(并且可能以后每次测试)。每个人都知道“以后我会解决”的想法。 在另一个项目中重用一个类并不总是那么容易(主要是由于其他紧密的耦合,但是常量处理并没有使它更容易。) 您将在哪里存储这样的常量?为了使您的项目经理相信还有更好的概念也符合上面列出的优点,您还会提出什么论点? 随意给出特定于C ++或独立的答案。 PS:我知道这个问题是主观的,但是老实说,我不知道有比这个网站更好的地方。 有关此项目的更新 关于编译时间,我有个新闻: 在Caleb和gbjbaanb的帖子中,有空时,我将常量文件拆分为其他几个文件。我最终还将我的项目分成几个库,现在可以轻松得多。在发布模式下进行编译显示,包含数据库定义(表,列名等-超过8000个符号)并建立了某些哈希值的自动生成的文件在发布模式下造成了巨大的编译时间。 现在,通过停用包含DB常量的库的MSVC优化器,我们可以将发布模式下的项目(几个应用程序)的总编译时间从最多8小时减少到不到一小时! 我们还没有找到为什么MSVC很难优化这些文件,但是现在,由于我们不再只依赖夜间构建,因此此更改减轻了很多压力。 这个事实以及其他好处,例如紧密耦合少,可重用性更好等,也表明花时间拆分“常量”并不是一个坏主意;-) 更新2 由于这个问题仍然受到关注: 这是过去几年中我一直在做的事情: 将每个常量,变量等完全放在与其相关的范围内:如果仅在单个方法中使用常量,则可以在该方法中定义它。如果单个类对此感兴趣,请将其保留为该类的私有实现细节。这同样适用于名称空间,模块,项目,公司范围。我还将相同的模式用于助手功能等。(如果您开发一个公共框架,这可能不会100%适用。) 这样做可以提高可重用性,可测试性和可维护性,使您不仅花费更少的时间(至少在C ++中),而且花费在错误修复上的时间也更少,这使您有更多的时间实际开发新功能。同时,开发这些功能的速度会更快,因为您可以更轻松地重用更多代码。这在一定程度上胜过中央常量文件可能具有的任何优势。 如果您想了解更多,请特别看一下接口隔离原则和单一职责原则。 如果您同意,请支持Caleb的回答,因为此更新基本上是他所说的更一般的看法。

6
如何在事件驱动的体系结构中处理初始状态?
在事件驱动的体系结构中,每个组件仅在事件通过系统发送时起作用。 假设有一辆带有刹车踏板和刹车灯的假想汽车。 刹车灯在接收到刹车启动事件时亮起,并在接收到刹车关闭事件时熄灭。 制动踏板发送brake_on当它被按下事件和brake_off当它被释放事件。 这是一切都很好,直到你有其中汽车已开启,制动踏板的情况已经按下。由于刹车灯从未收到过刹车事件,因此它将保持熄灭状态-显然是不希望的情况。默认情况下,打开刹车灯只会扭转这种情况。 如何解决此“初始状态问题”? 编辑:谢谢您的所有答复。我的问题不是关于一辆真正的汽车。在汽车中,他们通过不断发送状态来解决此问题-因此在该域中没有启动问题。在我的软件领域,该解决方案将使用许多不必要的CPU周期。 编辑2:除了@gbjbaanb的答案外,我还将使用以下系统: 假设的制动踏板在初始化后会发送一个事件及其状态,并且 假设的制动灯在初始化后发送一个事件,要求从制动踏板发出状态事件。 使用此解决方案,组件之间没有依赖关系,没有竞争条件,没有消息队列过时,也没有“主”组件。

1
为什么数据库作为队列那么糟糕?[关闭]
我刚刚读了这篇文章,我很困惑。 假设有1个webapp和1个不同的应用程序充当“工作者”,它们共享同一个数据库。 哦,我说“分享” ..但是这篇文章警告了什么?: 第四,在应用程序(或服务)之间共享数据库是一件坏事。在其中放置无定形共享状态太诱人了,在您不知道它的情况下,您将拥有一个巨大的耦合怪物。 =>不同意。在某些情况下,不同的应用程序仍然是同一单元的一部分,因此,在这种情况下,“耦合问题”的概念毫无意义。 让我们继续:Web应用程序处理客户端HTTP请求,并可能随时更新某些聚合(DDD术语),从而生成相应的域事件。 工作人员的目标是通过处理所需的作业来处理那些域事件。 重点是: 事件数据应如何传递给工作人员? 正如阅读的文章所提倡的那样,第一个解决方案是使用RabbitMQ,它是一款出色的面向消息的中间件。 工作流程将很简单: 每当Web dyno生成事件时,它都会通过RabbitMQ发布该事件,从而为工作人员提供帮助。 缺点是,如果不处理潜在的发送失败或硬件问题,则无法保证提交汇总更新和事件的发布之间的即时一致性。这是另一个主要问题。 示例:发布事件可能没有成功进行汇总更新...导致事件代表域模型的错误表示。 您可能会争辩说存在全局XA(两阶段提交),但这不是适合所有数据库或中间件的解决方案。 那么,什么是确保这种即时一致性的好的解决方案?: IMO,将事件存储在数据库中,并且与聚合更新在同一本地事务中。 将创建一个简单的异步调度程序,并负责从数据库查询当前未发布的事件,并将其发送到RabbitMQ,后者再填充工作程序。 但是,为什么还要在webapp端并需要一个额外的调度程序:为什么在这种情况下需要RabbitMQ? 通过这种解决方案,在逻辑上似乎可以不需要RabbitMQ,尤其是因为数据库是共享的。 确实,无论如何,我们都看到即时一致性涉及从数据库进行轮询。 因此,为什么工人不直接对这次投票负责? 因此,我想知道为什么网络上有那么多文章在推广面向消息的中间件时几乎没有批评数据库排队。 文章摘录: 简单,使用正确的工具完成工作:这种情况正在引起消息传递系统的注意。它解决了上述所有问题;不再需要轮询,高效的消息传递,无需从队列中清除已完成的消息以及没有共享状态。 和即时的一致性,被忽略了吗? 综上所述,实际上无论情况如何,无论是否共享数据库,我们都需要数据库轮询。 我错过了一些批评观念吗? 谢谢

8
SOLID,避免贫血领域,依赖注入?
尽管这可能是与编程语言无关的问题,但我对针对.NET生态系统的答案很感兴趣。 这是这种情况:假设我们需要为公共管理开发一个简单的控制台应用程序。该应用程序是关于车辆税的。他们(仅)具有以下业务规则: 1.a)如果车辆是汽车,而车主最后一次缴税是在30天前,则车主必须再次缴税。 1.b)如果车辆是摩托车,且车主上次缴税是60天前,则车主必须再次缴税。 换句话说,如果您有汽车,则必须每30天支付一次费用;如果您有摩托车,则必须每60天支付一次费用。 对于系统中的每辆车,应用程序都应测试这些规则并打印不满足这些规则的车辆(车牌号和车主信息)。 我想要的是: 2.a)符合SOLID原则(尤其是开放/封闭原则)。 我不想要的是(我认为): 2.b)一个贫血的领域,因此业务逻辑应该放在业务实体内部。 我从这个开始: public class Person // You wanted a banana but what you got was a gorilla holding the banana and the entire jungle. { public string Name { get; set; } public string Surname { get; set; } } public …
33 c#  .net  design  architecture 

3
跨微服务共享DTO的方法?
我的情况如下。 我正在设计一个系统,该系统旨在从各种类型的传感器接收数据,然后进行转换并将其持久化,以供以后的各种前端和分析服务使用。 我正在尝试将每个服务设计为尽可能独立,但是遇到了一些麻烦。团队已决定要使用的DTO。面向外部的服务(传感器数据接收者)将以自己独特的方式接收数据,然后将其转换为JSON对象(DTO)并将其发送给Message Broker。消息的使用者将确切地知道如何读取传感器数据消息。 问题是我在几个不同的服务中使用了相同的DTO。必须在多个位置实施更新。显然,我们的设计方式使得此处的DTO中有一些多余或缺失的字段,并且在更新服务之前不会有太大的问题,但这仍然困扰着我,并使我感到自己犯错误。它很容易变成头痛。 我在设计系统时会出错吗?如果没有,那么有什么解决办法,或者至少可以缓解我的担心?

2
如何设计可扩展的通知系统?[关闭]
我需要写一个通知系统管理员。 这是我的要求: 我需要能够在可能完全不同的不同平台上发送通知(例如,我需要能够发送SMS或电子邮件)。 有时,对于给定平台的所有收件人,通知可能是相同的,但是有时,可能是每个平台(或多个)每个收件人的通知。 每个通知可以包含特定于平台的有效负载(例如,MMS可以包含声音或图像)。 系统需要可伸缩,我需要能够发送大量通知而不会导致应用程序或服务器崩溃。 这是一个分为两个步骤的过程,首先,客户可以输入消息并选择要发送到的平台,然后创建通知,以便稍后进行实时处理。 然后,系统需要将通知发送到平台提供商。 就目前而言,尽管我得到了一些结论,但是我不知道它的可扩展性或它是否是一个好的设计。 我有以下对象(使用伪语言): 通用Notification对象: class Notification { String $message; Payload $payload; Collection<Recipient> $recipients; } 如果我有1.000.000收件人,则以下对象的问题是什么?即使Recipient对象很小,也会占用太多内存。 我还可以为每个收件人创建一个通知,但是某些平台提供商要求我批量发送该通知,这意味着我需要定义一个包含多个收件人的通知。 每个创建的通知可以存储在诸如DB或Redis的持久性存储中。 稍后汇总此内容以确保其可伸缩性是否很好? 在第二步中,我需要处理此通知。 但是,如何区分通知给正确的平台提供商的通知呢? 我应该使用诸如MMSNotification扩展对象之类的对象abstract Notification吗?或类似的东西Notification.setType('MMS')? 为了允许同时处理大量通知,我认为像RabbitMQ这样的消息传递队列系统可能是正确的工具。是吗? 这将使我可以排队很多通知,并有几个工作人员弹出通知并进行处理。但是,如果我需要如上所述对收件人进行批处理怎么办? 然后我想象NotificationProcessor的,我我可以添加对象NotificationHandler的每个NotificationHandler将负责连接平台提供商和执行通知。 我也可以使用EventManager允许插入行为。 有任何意见或建议吗? 感谢您抽出宝贵的时间。 注意:我曾经使用过PHP,并且它可能是我选择的语言。 编辑 (根据morphunreal的答案) 您每秒发送多少消息(定义当前/初始级别,定义在重新设计之前系统应处理的最大级别) 系统具有哪些硬件限制(内存,CPU等可供系统使用) 硬件将如何扩展(即添加更多服务器,云计算等) 哪些语言/系统将生成通知? 它是我自己的事情,我负责以编程方式创建通知,但该通知是通过用户界面构建的。 生成器是否知道消息的收件人(?),还是通过其他某种方式提供消息(例如,某些警报类型的业务规则将发送给某些收件人) 应该可以为特定收件人,一组收件人(例如,使用标签系统)或整个平台创建通知。 是否有添加CC / BCC /阅读收据的业务规则 是。请注意,这实际上是特定于平台的,read或cc并非在所有平台上都可用。 …

11
设计良好/高质量的开源软件
我正在参加软件设计课程,我应该从软件设计的角度选择一个开源软件进行分析。 它必须是一个大项目:不少于100,000行代码。 我真的很想选择一种设计和架构都很好的软件,以便对好的软件设计有深刻的见解。 所谓好的设计,是指诸如有意义的类和体系结构,(设计)模式的良好使用,抽象的良好使用,组件的良好组织,组件之间的高内聚和低耦合等。 您有什么软件可以建议我吗? 请注意,软件只需要具有良好的设计,而无需将设计记录在案!:) 它不一定是最终用户的应用程序...也可以是库,工具等...


2
用全栈javascript分离前端和后端的方法?
假设我有一个前端,该前端主要是一个单页面的应用程序,它是使用angular,grunt和bower编写的。假设我有一个后端,主要是一个坐在ORM之上的REST API,它使用grunt,express和sequelize之类的东西从数据库中存储/检索对象。 角度应用程序执行用户看到的所有可视化内容,但是它是通过后端提供的服务上的GUI来完成的。 希望将它们分成两个不同的代码库,以允许独立开发,版本控制,持续集成,推送到开发等。 我的问题是,有什么方法可以干净地进行此操作?是否有针对全栈javascript的推荐最佳实践? 选项#1似乎是一个整体,即“不要将它们分开”。优点是构建链很简单,而且一切都集中在一个地方-但似乎有很多弊端。很难独立版本化,正面折断意味着背面无法展开,依此类推。 选项#2似乎是一个准整体,其中前端构建链导致将一堆文件写入后端。dist前端的目录将引用后端的某个目录,因此从本质上讲,当前端最小化,丑化等等时,它最终将发布到后端,后端将运行所有内容。 选项#3似乎是完全分开的:前端和后端各自在不同的端口上运行各自的服务器,并且它们是完全独立的项目。缺点似乎是需要将它们配置为了解彼此的端口。后端必须允许来自前端的CORS,并且前端需要知道所有这些端点的预期位置。 选项#4可能是使用docker-compose之类的东西将整个东西装配在一起。 我确定还有其他选择。建议的最佳做法是什么?

6
如果它允许更轻松地解决另一个问题,是否可以散发出代码的味道?[关闭]
我和一群朋友在过去的一段时间里一直在从事一个项目,我们想发明一种很好的面向对象的方法来表示特定于我们产品的方案。基本上,我们正在开发东方风格的 子弹地狱游戏,我们希望建立一个系统,在其中可以轻松表示我们可以梦想的子弹的任何可能行为。 这就是我们所做的;我们制作了一个非常优雅的架构,使我们可以将项目符号的行为划分为不同的组件,这些组件可以随意附加到项目符号实例上,类似于Unity的组件系统。它工作得很好,易于扩展,灵活并且覆盖了我们的所有基础,但是存在一个小问题。 我们的应用程序还涉及大量的程序生成,即我们以程序方式生成项目符号的行为。为什么这是个问题?好吧,我们的OOP解决方案虽然表现优雅,但是代表人的举止却很复杂,如果没有人使用它,工作起来会有些复杂。人类足够聪明,可以想到既合理又明智的问题解决方案。程序生成算法还不那么聪明,我们发现很难实现一个充分利用OOP架构的AI。诚然,该体系结构的一个缺陷是并非在所有情况下都直观。 因此,为了解决此问题,我们基本上将不同组件提供的所有行为都推到了bullet类中,这样我们可以想像到的一切都直接在每个bullet实例中提供,而与其他关联的组件实例不同。这使我们的过程生成算法更容易使用,但是现在我们的bullet类是一个巨大的上帝对象。到目前为止,它很容易成为程序中最大的类,它的代码量是其他任何代码的五倍以上。维护也有点麻烦。 可以让我们的一个类变成一个上帝对象,只是为了使其更容易处理另一个问题吗?通常,如果它允许更轻松地解决其他问题,代码中是否会有代码味道是可以的吗?

6
使用EntityFramework反对什么参数?[关闭]
我当前正在构建的应用程序一直在使用存储过程和手工制作的类模型来表示数据库对象。有人建议使用Entity Framework,由于我对项目的了解并不多,因此我正在考虑切换到该框架。我的问题是,我觉得为EF争论的人只是在告诉我事情的好处,而不是坏的事情:) 我主要关心的是: 我们希望使用DataAnnotations进行客户端验证,这听起来好像我还是必须创建客户端模型,所以我不确定EF是否会节省那么多编码时间 我们希望通过网络时使类尽可能的小,并且我读到使用EF通常会包含不需要的额外数据 我们有一个跨多个数据库的复杂数据库层,我不确定EF是否可以处理此问题。我们有一个Common数据库,其中包含诸如Users,StatusCodes,Types等内容,以及针对应用程序不同实例的主数据库的多个实例。SELECT查询可以并且将在数据库的所有实例之间进行查询,但是用户只能修改当前正在使用的数据库中的对象。他们可以在不重新加载应用程序的情况下切换数据库。 对象模式非常复杂,通常涉及很多联接 EF的参数为: 并发。我不必在检查中编写代码以查看记录是否在每次保存之前都已更新 代码生成。EF可以为我生成部分类模型和POCO,但是我并不肯定这会为我节省很多时间,因为我认为我们仍然需要创建客户端模型进行验证和一些自定义解析方法。 由于我们不需要为每个数据库对象创建CRUD存储过程,因此可以加快开发速度 我们当前的体系结构由WPF服务和WPF桌面客户端组成,该WPF服务通过参数化的存储过程处理数据库调用,从WCF服务和WPF客户端传入/传出的POCO对象,以及将POCO转换为类模型以进行验证和验证的WPF桌面客户端本身。数据绑定。 所以我的问题是,EF是否适合这样做?我没有意识到关于EF的陷阱吗?

15
程序员可以从建筑业中学到什么?[关闭]
在与同事讨论软件设计和开发原理时,我注意到类比的最常见来源之一是建筑行业。我们构建软件,并将设计和结构视为体系结构。 学习(或教导)的最佳方法之一是通过分析类比- 从构造中还能得出哪些其他类比? (是否已经在软件中普遍使用)。 请提供有关编程概念与构造概念的相似之处的描述或您的个人经验。 [ 取材于艺术和人文科学的编程概念学分]

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.