标签: software-design

如何组织我已经工作的插件系统的文件结构?

我正在研究一个项目,其主要设计指导原则是可扩展性.

我通过定义一个元类来实现一个插件系统,该元类使用类方法注册任何被加载的插件的类名(每种类型的插件都继承自核心代码中定义的特定类,因为有不同类型的插件应用程序).基本上这意味着开发人员必须将他的类定义为

class PieChart(ChartPluginAncestor):
    # Duck typing:
    # Implement compulsory methods for Plugins 
    # extending Chart functionality
Run Code Online (Sandbox Code Playgroud)

并且主程序将知道他的存在,因为PieChart将包含在可用的已注册插件列表中ChartPluginAncestor.plugins.

作为类方法的安装方法,所有插件在其类代码加载到内存时都会被注册(因此即使在实例化该类的对象之前)也是如此.

该系统对我来说工作得很好(虽然我总是对如何改进架构的建议持开放态度!)但我现在想知道什么是管理插件文件的最佳方式(即包含插件的文件的位置和方式)应该存储).

到目前为止,我正在使用 - 用于开发目的 - 我称之为"插件"的包.我将所有包含插件类的*.py文件放在包目录中,我只需import plugins在main.py文件中发出,以便正确安装所有插件.

编辑:杰夫在评论中指出,import plugins包的各个模块中包含的类将不会随时可用(我没有意识到这一点 - 因为我是 - 为了调试目的 - 分别导入每个类from plugins.myAI import AI).

但是,在我开发和测试代码时,这个系统才有用,如:

  • 插件可能带有自己的单元测试,我不想在内存中加载它们.
  • 所有插件目前都已加载到内存中,但实际上有些插件是同一功能的替代版本,所以你真的需要知道你可以在两者之间切换,但是你想要加载到你选择的那个内存中从配置窗格中.
  • 在某些时候,我希望有一个双重位置来安装插件:系统范围的位置(例如在某处/usr/local/bin/)和用户特定的位置(例如在某处/home/<user>/.myprogram/).

所以我的问题确实 - 或许 - 三个:

  1. 插件容器:我的目标最明智的选择是什么?单个文件?包?一个简单的.py文件目录?)
  2. 识别插件的存在而不必加载(导入)它们:使用Python内省的智能方法是什么?
  3. 将插件放在两个不同的位置:是否有标准的方法/最佳实践(至少在gnu/linux下)?

python plugins introspection software-design file-management

5
推荐指数
1
解决办法
304
查看次数

软件设计与Web服务设计

我即将设计我的Web服务API,我的API的大多数功能基本上与我的Web应用程序非常相似.

现在问题是,我应该创建1个单一方法并将它们重用于Web应用程序和Web服务API吗?(这似乎是合乎逻辑的解决方案,但它非常复杂;复制Web应用程序使用的方法要容易得多,并且保持两者分离,即Web应用程序的一种方法和Web服务的一种方法.)

你们是怎么做到的?

1)REUSE:一种主要方法,并将它们重用于Web应用程序和Web服务应用程序(我喜欢这个,但它很复杂)

  • WebAppMethodX --uses - > COMMONFUNCTIONMETHOD_X
  • APIMethodX ---使用----> COMMONFUNCTIONMETHOD_X

即Commonfunctionmethod_x包含可重用的一组常用功能

PRO:更少的代码,更少的维护,更少的错误.

CON:非常复杂

2)DUPLICATE:两种方法,一种是Web应用程序的方法,另一种是Web服务的方法.

  • WebAppMethodX
  • APIMethodX

PRO:简单

CON:复制=更多代码,更多维护,更多错误!

c# asp.net api web-services software-design

5
推荐指数
1
解决办法
451
查看次数

关于软件设计:哪里必须检查参数?

想象一下,我有一个应用程序向用户请求一个名称,一个类别列表.当用户单击"保存"按钮时,应用程序会将名称和类别保存到数据库中.

我有一个从UI获取名称和类别的图层.此图层检查是否有名称(长度> 0的字符串).如果这是正确的,它会将一个类别的名称传递给另一个图层.注意:category是radiobutton列表,其中始终选择一个项目.

在第二层,应用程序将根据类别选择合适的类来保存名称.

在最后一层,类将该名称保存在数据库中.在这个课上,我将检查姓名是否为空.

我的问题是:检查方法输入参数的正确位置在哪里?在每一层?也许,我将在其他开发中使用这些层.

我的例子是正确的吗?也许,我可以在数据库层上保留验证并向UI层引发异常.

validation software-design

5
推荐指数
1
解决办法
740
查看次数

序列图

我正在浏览大型开源应用程序的代码,并希望了解它是如何设计的以及它是如何工作的.有没有一种工具可以将C和C++代码反向工程为序列图?

可能这可能有点牵强但是当一个应用程序正在处理输入时,可以给我一个被称为(在各种模块和正确的顺序中)的函数列表的工具呢?或者帮助我快速分析给定的应用程序(特别是具有大代码库的应用程序)?

期待我的答案,因为我认为这必须是一个很好的主题.

uml sequence-diagram software-design

5
推荐指数
1
解决办法
3348
查看次数

数据传输对象可以/应该实现接口吗?

我想知道是否有人可以帮助我解决这个“架构困境”,

我正在从不同类型(类)中检索一些对象,例如:帖子、文档和图片

事实证明,在表示层中,我必须将它们呈现在单个容器中:想想 sharepoint 库的示例,其中有一个文件夹,并且可以在其中包含各种对象。

我想按属性对它们进行排序(假设是 PublishingDateTime)

我知道如果我想对它们进行排序,它们都应该实现相同的接口,所以将它们实现为(假设 ISortingCapable)

现在,在我的领域层,接口看起来很好,

但是后来,我意识到这无济于事,因为这些实例化的对象作为 DTO 进入表示层(它们不再是相同的域对象)=> 将 DTO 视为 MVC 中的视图模型。

简单的说:

如果在表示层我有一个

List<PostDTO> 
List<PictureDTO> 
List<DocDTO> 
Run Code Online (Sandbox Code Playgroud)

=> 简单的对象,简单的渲染。

现在我想在单个内容流中对它们进行排序。

我的问题是:DTO 是否应该再次实现完全相同的接口?还是我从错误的方面看问题?

model-view-controller software-design n-tier-architecture

5
推荐指数
1
解决办法
913
查看次数

在库中使用srand()的问题

srand()/rand()第三方库中有大量使用预定义种子的呼叫.在同一过程中组合不同的库时会出现问题.有时很难确保正确的呼叫顺序,混合srand()rand()呼叫是可能的.另一个问题是无法在应用程序级别选择播种值.作为一般规则,我们是否应该避免srand()在库中使用(包括开源),将播种任务留给应用程序?

c c++ random software-design

5
推荐指数
1
解决办法
401
查看次数

类中的私有接口

在这里,我遇到了这句话:

实现私有接口是强制在该接口中定义方法而不添加任何类型信息(即不允许任何向上转换)的方法.

我发现很难理解这一点.有人可以帮我解释一下吗?

java oop interface software-design

5
推荐指数
2
解决办法
260
查看次数

如何使用库检查空值比获取NPE更好?

有时我看到开发人员使用像Guava的Preconditions这样的库来验证方法开头的空值参数.与在运行时期间获取NPE有什么不同,因为运行时异常以任何一种方式发生?

编辑:如果有充分的理由,那么开发人员是否应该使用库对所有方法进行空值检查?

java software-design guava

5
推荐指数
1
解决办法
114
查看次数

如何处理复合微服务请求中的验证?

考虑具有两个实体的应用程序:

  • User (包含基本用户数据,例如名称)
  • Passport (包含身份验证凭据,即密码)

还有两个内部微服务:

  • UserService (负责创建和管理用户及其基本数据)
  • AuthService (负责用户身份验证和密码处理)

User实体属于UserServicePassport实体属于AuthService.

这两个服务应该分开,因为它们解决了截然不同的任务:配置文件数据身份验证.

另外,请考虑我们有一个包含三个字段的注册表:

  • 电子邮件
  • 名称
  • 密码

此表单将触发GatewayService对该应用程序的HTTP请求,该请求拦截对应用程序的所有请求并将它们路由到内部微服务(或组合/聚合它们).

现在,当网关服务收到包含所有表单数据的请求时,它需要执行以下操作:

  1. 调用UserService创建新用户(它将以生成的方式响应userId).
  2. 呼叫AuthService为新创建的用户创建护照.它将需要userId步骤#1中收到的和password原始请求中的字段.

这看起来非常简单,但如果AuthService在步骤#2中不可用会发生什么?我们需要以某种方式分离这些请求!

经典方法是使用最终一致性并Passport通过异步调用创建实体(我们可以将此请求放入队列并在单独的服务中处理它).为了做到这一点,我们将向AuthService传递userIdpassword向它发送异步请求,而不是步骤#2,因此步骤#1将立即返回对客户端的响应.

但是,如果password字段格式不正确(打破验证规则)怎么办?验证逻辑仅出现在AuthService,因此我们无法知道密码是否正确,直到调用它为止.现在,请求是异步处理的,因此我们无法回复用户并告诉他更正密码.

那么,您如何正确处理微服务应用程序的分布式复合请求中的验证?

  1. 天真的解决方案是将验证逻辑移到GatewayService自身,但这是一个糟糕的主意,因为它会使它变胖并且会泄露业务逻辑AuthService.

  2. 另一个想法是提供一种额外的密码验证方法,并在步骤#1和#2之前调用它.它看起来像一个可行的解决方案,但它将迫使我们为我们的微服务中的每个业务方法提供两种方法,一种用于事先验证,一种用于实际操作.此外,验证和操作之间存在时间空间,因此在实际执行操作时,较早的正确值可能会变得不正确.

  3. 我们可以将表单拆分为两个以避免复合请求,并在询问个人数据并为他创建帐户后询问用户密码.但是,这可能会导致安全问题,其中一些其他可能猜到下一个用户的用户可以拦截用户帐户userId.我们可以使用一些额外的安全令牌,但它会为服务引入奇怪的功能,并使整个设置更加复杂.

    此外,这种方法看起来像是试图逃避问题,您不能总是避免复合请求.

  4. 我们可以使用全面的分布式事务,例如2PC,但它会使系统变得非常复杂,并且首先会减少MSA的使用.

  5. 最后的想法是将这两种服务合并在一起,但在微服务架构中这样做是没有意义的.

architecture software-design distributed-transactions microservices

5
推荐指数
1
解决办法
1553
查看次数

哪一个更安全的本地存储或cookie?

我正在使用Django REST API(后端)和React JS(前端)开发项目.我Json Web token用于身份验证.但我很困惑,我是否应该存储Json Web tokenlocal storage或在cookies?哪一个更安全,为什么?如何大公司处理这类之间的安全性APIclient side

security software-design jwt django-rest-framework reactjs

5
推荐指数
1
解决办法
896
查看次数