Questions tagged «architecture»

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

5
作为“最低开发商”与技术债务作斗争?
假设您在一家公司工作,而您所要做的就是为他们开发软件。您不了解总体情况,也可能不了解。您所拥有的是通过问题跟踪系统分配给您的任务。您得到了任务,使它们按照任务描述它们的方式工作,然后将其发回。像加2个整数: function add(a,b){return a + b;} 但是后来,随着项目的进行,您注意到随着add变得越来越复杂,您意识到它应该需要某种形式的体系结构,而不仅仅是添加参数并返回值的函数。但是,您不知道。首先,他们所需要的就是这么简单add。您没想到add会变得如此复杂。 该项目具有更多功能,而您最初没有想到这些功能。最后,您将不断堆积各种技巧和功能,以免破坏/重写现有代码。 您如何处理这些情况?作为“最低开发商”,您如何应对技术债务? 澄清: 您是层次结构中最低的“实施者”。 您看到了问题,但对此没有发言权。 我不是在量化技术债务或寻找工具。 关于第三个“重复” 重构和重写-您被锁定在任务上。您无需支付额外费用。 体系结构概述-您了解整个系统,但不了解体系结构。 代码冻结-不是您的电话。您不是管理者。 模块化-不了解架构。模块随需求的变化而变化。 自动化测试-不存在。

3
PHP Web应用程序体系结构/设计
按照目前的情况,这个问题不适合我们的问答形式。我们希望答案会得到事实,参考或专业知识的支持,但是这个问题可能会引起辩论,争论,民意调查或扩展讨论。如果您认为此问题可以解决并且可以重新提出,请访问帮助中心以获取指导。 7年前关闭。 我已经被投入到使用PHP开发Web应用程序的新工作中。我绝不是PHP的新手,但我以前从未开发过大型应用程序。我想知道如何安排自己的发展,以避免将来遇到麻烦。如何以合理的方式设计和构造应用程序,以使它们可以在功能和性能方面随时间扩展。我在想这样的事情: 将后端与前端分开 目录结构 我希望能获得指向体系结构和应用程序设计模式,框架和方法的指针,这些指针使我能够以可持续的方式进行大规模PHP Web应用程序开发。

8
巨大的整体应用的危险
我现在从事的一个大型项目现在是高级设备的控制(及所有)应用程序,它是固件的核心。 该设备相当先进,具有比我在内存中所能说的更多的不同功能,其中98%由该庞大的可执行文件处理。一方面,该程序可维护性强,内部模块化程度高,文档正确,并且按目录和文件等对功能进行了合理隔离。 但是最后,它被全部集中到一个应用程序中,该应用程序执行从远程数据库通信,触摸屏处理,处理十二种各种通信协议,测量,几种控制算法,视频捕获,日出时间和复活节日期(认真地,通常,这是非常紧密相关的内容,通常仅通过一些在一些远模块之间滴加的数据才相关。 它可以通过几个单独的可执行文件相互通信来完成,例如,通过套接字进行通信,具有更特定的目的,可以根据需要加载/卸载等等。没有这种特定方式的原因。 一方面,它有效,而且还可以。该项目更加简单,无需维护多个二进制文件的构建。当您可以仅调用方法或读取变量而不是通过套接字或共享内存进行通信时,内部结构也更容易。 但另一方面,这东西的大小,规模让我感到无所适从,感觉就像是驾驶泰坦尼克号一样。我总是被教导要模块化,将所有内容都聚集到一个庞大的文件中感觉很不对。我知道的一个问题是,一个严重的崩溃(甚至无关紧要的)使所有模块崩溃了,但是代码质量确保在发行版中不会真正发生这种情况。否则,内部隔离和防御性编程可确保即使一半内部模块由于某种原因正常发生故障,该操作仍将大部分正确地运行。 我还忽略了哪些其他危险?为什么这使我感到恐惧?这只是对未知的非理性恐惧吗?这样进行严肃的大型项目是否可以接受?请平息我的担心,或者给我一个很好的理由将2.0版重构为多个较小的二进制文件。

3
DDD应用程序服务和REST API之间的概念不匹配
我正在尝试设计一个具有复杂业务域和支持REST API(严格来说不是REST,而是面向资源)的应用程序。我想出一种以面向资源的方式公开域模型的方法时遇到一些麻烦。 在DDD中,域模型的客户端需要通过过程“应用程序服务”层来访问由实体和域服务实现的任何业务功能。例如,有一个具有两种方法来更新User实体的应用程序服务: userService.ChangeName(name); userService.ChangeEmail(email); 此应用程序服务的API公开命令(动词,过程),而不是状态。 但是,如果我们还需要为同一应用程序提供RESTful API,则有一个用户资源模型,如下所示: { name:"name", email:"email@mail.com" } 面向资源的API公开状态,而不是命令。这引起了以下问题: 根据REST API上的每个属性,每个针对REST API的更新操作都可以映射到一个或多个Application Service过程调用。 对于REST API客户端,每个更新操作看起来都是原子操作,但是并不是那样实现的。每个应用程序服务调用被设计为一个单独的事务。在资源模型上更新一个字段可能会更改其他字段的验证规则。因此,我们需要一起验证所有资源模型字段,以确保所有潜在的应用程序服务调用在开始创建之前都是有效的。一次验证一组命令要比一次执行简单得多。我们如何在甚至不知道存在单个命令的客户端上执行此操作? 以不同的顺序调用Application Service方法可能会产生不同的效果,而REST API看起来没有什么区别(在一个资源内) 我可以想出更多类似的问题,但是基本上它们都是由同一件事引起的。每次调用应用程序服务后,系统状态都会更改。什么是有效更改的规则,即实体可以执行下一个更改的一组操作。面向资源的API试图使它们看起来都像原子操作。但是跨越这个鸿沟的复杂性一定要到某个地方,而且看起来是巨大的。 另外,如果UI更加面向命令(通常是这种情况),那么我们将不得不在客户端的命令和资源之间进行映射,然后再在API端进行映射。 问题: 所有这些复杂性是否应该仅由(厚)REST到AppService映射层处理? 还是我对DDD / REST的理解缺少什么? REST是否对于在一定程度(相当低)的复杂度下公开域模型功能不可行?

4
为什么不使用SQL而不是GraphQL?
最近,我了解了GraphQL,它声称比RESTful更好。但是,我开始怀疑为什么不将SQL语句简单地放入HTTP GET请求中。 例如,在GraphQL中,我将编写 { Movie(id: "cixos5gtq0ogi0126tvekxo27") { id title actors { name } } } 这并不比它的SQL比较简单 SELECT id, title FROM movies WHERE id = cixos5gtq0ogi0126tvekxo27; SELECT actors.name FROM actors, actors_movies WHERE actors.id == movies.actor_id AND movie.id == cixos5gtq0ogi0126tvekxo27; 也许我们可以对查询进行URL编码并发送到服务器 GET endpoint?q=SELECT%20id%2C%20title%20FROM%20movies%20WHERE%20id%20%3D%20cixos5gtq0ogi0126tvekxo27%3B%0ASELECT%20actors.name%20FROM%20actors%2C%20actors_movies%20WHERE%20actors.id%20%3D%3D%20movies.actor_id%20AND%20movie.id%20%3D%3D%20cixos5gtq0ogi0126tvekxo27%3B HTTP/1.1 是的,查询URL可能太长,但是如果您不关心REST遵从性,则可以将其放入POST请求的正文中。(顺便说一句,我认为需要对REST进行HTTP RFC的修订才能有意义:限制查询字符串的长度从一开始就将实现与规范混合在一起) 从客户端直接发出SQL的优势还在于 解析GraphQL不需要服务器端代码/库,从而减少了开发时间。 解析GraphQL不需要服务器端开销,从而减少了运行时间。 SQL语句比GraphQL灵活得多,因为(在大多数情况下)GraphQL无论如何都会简化为SQL。 每个人都知道SQL。 那么,GraphQL与SQL相比有什么优势?

6
我应该按业务领域还是技术领域来组织文件夹?
例如,如果我使用某种类似于MVC的体系结构,则应使用哪种文件夹结构: domain1/ controller model view domain2/ controller model view 要么: controllers/ domain1 domain2 models/ domain1 domain2 views/ domain1 domain2 我故意省略了文件扩展名,以使该问题与语言无关。 就个人而言,我更喜欢按业务领域(直觉)分开,但我看到大多数/许多框架都按技术领域分开。为什么我要选择谁呢?

2
如何在保持效率的同时将用户界面与业务逻辑分开?
假设我想显示一个表示组合框上10个不同对象的表单。例如,我希望用户从10个不同的包含番茄的汉堡包中选择一个。 因为我想分离UI和逻辑,所以我必须通过表单来表示汉堡包的字符串,以便在组合框中显示它们。否则,UI必须深入到对象字段。然后,用户将从组合框中选择一个汉堡包,并将其提交回控制器。现在,控制器将不得不根据表单使用的字符串表示形式(也许是ID?)再次查找所述汉堡包。 这不是效率低下吗?您已经有了想要从中选择一个的对象。如果您将整个对象提交给表单,然后返回一个特定的对象,则以后不必重新引用它,因为表单已经返回了对该对象的引用。 而且,如果我错了,而您实际上应该将整个对象发送到表单,那么如何将UI与逻辑隔离?

5
在哪里描述架构问题?
我加入了一个已经运行了几年的中型项目的中间阶段。问题之一是从未描述过描述体系结构的文档。现在,我被分配了编写架构描述的任务。 在从事该项目的过程中,我收集了编写文档所需的所有信息。由于还添加了一些功能,因此确定了一些代码,这些代码显然破坏了所描述的体系结构。 例如,GUI应该是没有业务逻辑的薄层。那就是我被告知的。该实现包含很多逻辑。 老板给我分配了任务,写了描述系统体系结构的文档。目标受众是从事该项目的现在和将来的开发人员。我需要描述应该是什么,但是我还需要以某种方式描述偏差。 那么,我应该在哪里描述这些问题呢?错误跟踪软件?还是应该在描述系统体系结构的文档中描述实现与体系结构的偏差?

4
持久性如何适合纯功能性语言?
使用命令处理程序处理持久性的模式如何适合于一种纯函数式语言,在这种语言中,我们希望使与IO相关的代码尽可能的薄? 当以面向对象的语言实现域驱动设计时,通常使用命令/处理程序模式执行状态更改。在这种设计中,命令处理程序位于您的域对象之上,并负责无聊的与持久性相关的逻辑,例如使用存储库和发布域事件。处理程序是您域模型的公开面孔;诸如UI之类的应用程序代码在需要更改域对象的状态时会调用处理程序。 C#中的草图: public class DiscardDraftDocumentCommandHandler : CommandHandler<DiscardDraftDocument> { IDraftDocumentRepository _repo; IEventPublisher _publisher; public DiscardDraftCommandHandler(IDraftDocumentRepository repo, IEventPublisher publisher) { _repo = repo; _publisher = publisher; } public override void Handle(DiscardDraftDocument command) { var document = _repo.Get(command.DocumentId); document.Discard(command.UserId); _publisher.Publish(document.NewEvents); } } 该document域对象是负责执行业务规则(如“用户应该有权丢弃文档”或“你不能放弃一个已经被丢弃的文件”),并产生我们需要发布域事件(document.NewEvents会是一个IEnumerable<Event>,并且可能包含一个DocumentDiscarded事件)。 这是一个不错的设计-易于扩展(您可以通过添加新的命令处理程序来添加新用例,而无需更改域模型),并且不知道对象的持久化方式(可以轻松地将NHibernate存储库换成Mongo存储库,或将RabbitMQ发布者替换为EventStore发布者),这使得使用伪造品和模拟进行测试变得容易。它还遵循模型/视图分离-命令处理程序不知道批处理作业,GUI或REST API是否正在使用它。 在Haskell这样的纯功能语言中,您可以大致像这样对命令处理程序进行建模: newtype CommandHandler = CommandHandler {handleCommand :: …


3
从整体式迁移到微服务时,如何处理外键约束?
我的团队正在从单一的ASP.NET应用程序迁移到.NET Core和Kubernetes。代码更改似乎正在进行中,并且可以预期,但是我的团队遇到的很多问题都围绕数据库进行。 当前,我们有一个相当大的SQL Server数据库,其中包含了整个业务的所有数据。我提议我们以与拆分代码类似的方式拆分数据库-一个逻辑数据库中的目录数据,另一个数据库中的库存数据,另一个数据库中的订单等-每个微服务都将成为其数据库的关守者。 这就意味着跨微服务边界的外键将必须被删除,跨边界的程序和视图将被禁止。所有数据模型可能会或可能不会驻留在同一个物理数据库中,但是即使它们存在,它们也不应直接相互交互。订单可能仍按ID引用目录项,但不会在数据库级别严格执行数据完整性,并且必须将数据以代码而不是SQL形式联接。 我认为这些损失是迁移到微服务并获得随之而来的可伸缩性优势时的必要折衷。只要我们明智地选择接缝并围绕它们发展,那应该没问题。其他团队成员坚持认为,所有内容都必须保留在同一个整体数据库中,以便所有内容都可以是ACID并在各处保留引用完整性。 这使我想到了我的问题。首先,我对外键约束和加入的立场是否合理?如果是这样,有人知道我可以提供给同事的任何可靠的阅读材料吗?他们的立场几乎是宗教性的,他们似乎不会因马丁·福勒本人告诉他们自己的错而受到任何影响。

2
将大型Angular 2应用与其中的多个小型应用组合
经过3个月的辩论和研究,关于在React(与Redux)和Angular 2之间进行选择的研究,我公司的前端团队最终决定采用Angular 2(因为它更适合我们的问题)。 我们正在从事企业应用程序业务,该业务目前由许多不同的前端技术组成(同时拥有整个后端RESTful),我们希望将其全部替换,并拥有一种技术来简化将来的培训和质量控制。 鉴于我们产品的性质,产品范围很广,并且其中包含模块,这些模块本身是不同的域,可以作为独立的应用程序制作,但产品本身位于单个URL中。 例; 我们将我的产品称为SuperApp。 作为UI,SuperApp具有标准的登录系统,并可以导航到子模块/子产品,因此工作流如下所示。 超级应用 验证用户 忘记密码向导 无需身份验证即可访问公共页面 认证用户 导航系统 家 子产品1 子产品2 子产品3 轮廓 ... ... 团体 ... ... 请注意,在以上表示中,Sub-product1和Sub-product2是两个完全不同的领域,具有完全不同的业务领域。 我现在可以想到的是,我可以将SuperApp创建为单个Angular 2项目,仅包含与其自身相关的组件和视图,并且SuperApp还负责加载多个子应用程序;Sub-product1,Sub-product2(同样是不同的Angular 2项目,它们都有自己的package.json,webpack配置等)通过哑组件,并充当提供顶级路由的Shell和占位符来容纳这些子应用。 有一次,Sub-product1在壳体内加载时,它会自己的路由附加到当前路由SuperApp在已经登陆。 我想要分离的原因是因为这些不同的应用程序(当前使用ExtJS构建)具有专门的团队(我们是一家拥有500多个开发人员的公司),因此,如果他们拥有自己的Angular项目,则可以管理其工具并依赖于他们的喜好,而无需依赖父级父级应用。 但是我无法在官方的Angular文档中或网上找到任何地方是否可以嵌套Angular应用程序(以这种方式共享框架代码,而完全隔离子应用程序的依赖项并仅在应用程序加载时需要),或者是否有其他替代方法可以解决此问题。 任何指导,甚至任何相关文章的链接,将不胜感激。

5
数据库中的功能是否阻碍了可扩展性?
我可能无法为该问题提供正确的标题。但这是 我们正在开发财富管理的金融门户。我们期望超过10000个客户端使用该应用程序。门户根据股票市场的技术分析计算各种绩效分析。 我们通过存储过程,用户定义的函数,触发器等通过数据库开发了许多功能。我们认为,与通过C#代码相比,直接在数据库中执行操作可以大大提高性能。实际上,我们确实获得了巨大的性能提升。 当我试图向我们的CTO吹牛时,他反驳了我决定在数据库中而不是代码中实现功能的决定。据他介绍,此类应用程序存在可伸缩性问题。用他的话说:“如今,这些东西都保存在内存/缓存中。随着时间的推移,很难管理集群数据。Facebook,Google在数据库中什么也没有。这是瘦服务器和胖客户端的时代。DB仅用于存储纯数据并且功能应该与数据库完全分离。” 你们能给我一些关于他说的是否正确的建议。如何进行架构师这样的应用程序?

2
储存库和工作单元之间的关系
我将实现一个存储库,并且我想使用UOW模式,因为该存储库的使用者可以执行多个操作,因此我想一次提交它们。 在阅读了有关该问题的几篇文章之后,我仍然不知道如何将这两个元素联系起来,具体取决于文章是通过其他方式完成的。 有时,UOW是存储库内部的内容: public class Repository { UnitOfWork _uow; public Repository() { _uow = IoC.Get<UnitOfWork>(); } public void Save(Entity e) { _uow.Track(e); } public void SubmittChanges() { SaveInStorage(_uow.GetChanges()); } } 有时它是外部的: public class Repository { public void Save(Entity e, UnitOfWork uow) { uow.Track(e); } public void SubmittChanges(UnitOfWork uow) { SaveInStorage(uow.GetChanges()); …

4
依赖注入和单例。他们是两个完全不同的概念吗?
我一直在听说要为我的同事在Singleton上使用依赖项注入。我仍然无法确定它们是否是可以互相替换的两个正交图案?还是DI是使Singleton模式可测试的方法? 请看下面的代码片段。 IMathFace obj = Singleton.Instance; SingletonConsumer singConsumer = new SingletonConsumer(obj); singConsumer.ConsumerAdd(10,20); 所述SingletonConsumer正在接受类型的参数IMathFace。而不是在内部访问singleton类,而是SingletonConsumer将获得调用者传递的singleton实例。这是通过依赖注入使用单例类的一个好例子吗?

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.