标签: software-design

在 Ruby 生产中使用断言...是还是否?

所以,这就是交易。我目前在 Ruby on Rails 环境中工作,已经工作约 1 年了。在此之前,我在 C++/Java 领域工作了近十年。我(仍在)试图弄清楚 Ruby 的断言方式是什么。

我不担心技术细节。我知道 TestUnit 有可以在测试环境中使用的断言,并且我知道我可以将自己的断言方法添加到我的 Ruby 项目中,并在生产 Rails 中使用它们来锁定已知条件。问题是:Ruby 的方式是什么来确保代码中我知道应该/不应该发生的事情?

作为记录,我一直在测试中断言并在生产中提高。我仍然忍不住想念我的生产断言......

ruby software-design

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

基于订阅的软件许可 - 离线验证

我正在尝试创建一个基于订阅的许可系统,如果您为 1 年 1 位用户购买软件,您只能在用于激活软件的机器上使用它一年,之后您必须更新您的许可证钥匙。这是非常基本的,但实现您自己的相同场景是完全不同的场景。

所以让我讨论我到目前为止所做的:(不包括代码,如果你想让我粘贴它们,请告诉我)

首先,我有一个托管的 MySQL 数据库,其中有一个数据库,其中存储了所有与许可证相关的信息(产品、serial_keys、计划等)。

因此,当您第一次启动该软件时,它会检查注册表中的几个值(多个位置),如果没有找到,它将要求您提供序列号。

输入序列号后,软件将连接到数据库并验证您的密钥并计算以下内容

  1. 验证序列号
  2. 计算唯一的机器 ID - 获取 BIOS_SL 、 MB_SL 、 HDD_SL ,将它们添加到一个字符串中并对其进行 MD5。
  3. 计算许可证有效性 - 获取 Internet 当前时间,使用计划持续时间增加年份
  4. 将以下信息存储在注册表中(多个位置)- license_id 、 machine_id、valid_till、activation_date、last_updated 和 license_status

此处略过一些逻辑步骤,例如如果许可证已经激活,请检查并匹配注册的 machine_id

这样软件就注册好了。现在,每次软件启动时,我都会再次在注册表中查找这些值并根据它做出决定,这就是我卡住的地方,需要您的专家建议。

  1. 软件启动
  2. 检查注册表值
  3. 生成 machine_id 并将其与存储的匹配
  4. 读取 valid_till 值(到期日期)并将其与当前时间匹配。

考虑到用户没有上网,只用了一次激活或上网套餐过期,如何进行合法的日期查询?不能使用系统时间,他们非常脆弱。

此时我想创建一个服务,该服务将具有回调函数,以便在用户尝试更改系统日期时采取行动。但这很乏味,我认为这不是最好的解决方案。

或者在启动时记录系统时间并依赖于它,但是用户甚至可以在系统启动之前通过 BIOS 更改它。

抱歉问了这么长的问题,但必须解释整个场景。

简而言之,用户没有互联网连接如何维护或获取日期/时间呼叫的合法来源?

c++ date software-design license-key visual-c++

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

控制员应该与演示者交谈吗?

在Robert Martin 的Clean Architecture中,假设我有这个简化版本(没有显示模型、网关、边界等其他内容):

在此输入图像描述

现在假设我有一个View带有 2 个按钮的DarkLight,单击时应更改 的背景颜色View并在屏幕上显示一些文本(文本的颜色应始终为蓝色)。所以我想到了这样的事情:

在此输入图像描述

假设这里我必须在控制器中对两个按钮使用一种方法(可能因为它是一个表单或其他什么),则变量buttonin将包含有关是否按下或按钮buttonClicked(button)的信息。DarkLight

现在,Interactor本例中的 只负责检索要显示的文本,但它不需要了解有关背景颜色的任何信息。

那么,控制器应该告诉演示者选择了哪种颜色(即按钮),还是我应该将此信息转发给Interactorjust 以便它可以将其传递给Presenter?请记住,他们Interactor甚至不会使用此信息。

architecture software-design clean-architecture

5
推荐指数
0
解决办法
1140
查看次数

java中未使用的导入会影响性能并消耗内存吗?

import java.io.*;
class Myclass
{
 //Some programming code that does not call any java io package methods or variables
}
Run Code Online (Sandbox Code Playgroud)

与没有未使用导入的程序相比,该程序是否占用更多内存,甚至更糟地影响软件/应用程序的性能?

java memory software-design

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

设计应用程序以支持配置更改而无需重新启动

有哪些方法可以设计应用程序,以便无需重新启动应用程序即可更改配置?

一种方法是只拥有一个包含配置的平面文件,然后应用程序在需要特定值时从配置中读取,并且从不在内存中存储任何配置值。

另一种选择是允许应用程序加载配置文件一次并将值存储在内存中,但随后定期重新加载配置文件以防发生变化。

c++ architecture configuration software-design configuration-files

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

Java 设计中 if-else 和 instanceof 的替代方案

我们的 Java 应用程序在后端使用Google Guava EventBus进行通信。其中一些事件使用 Jersey 的服务器发送事件 支持发送到客户端以启用通知。客户端仅对某些类型的事件感兴趣,并且这些事件以 JSON 格式发送到客户端。

目前,我们正在使用if-elsewithinstanceof来处理巨型方法中的 JSON 正文生成。UIEvent只是一个用作过滤器的标记接口。

@Subscribe
public void handleEvent(final UIEvent event) {
  if (event instanceof A) {
    A a = (A) event;

  } else if (event instance B) {
    B b = (B) event;

  } ...
}
Run Code Online (Sandbox Code Playgroud)

当越来越多的事件添加到系统中时,这段代码开始变得混乱。经过一番研究,有一些替代方案,但还不够好。

1)反思。

使用反射意味着我们可以使用声明性方式从事件对象中检索数据,而无需知道确切的类型。但是使用反射不是类型安全的,并且在处理嵌套路径时可能会很混乱,例如a.b.c.

2)多态性

多态性看起来是一个很好的替代方案instanceof,但在这种情况下确实有效。使用多态性意味着toJSONUIEvent接口添加类似的方法。但这会恢复依赖流并将 UI 详细信息暴露给事件总线。

3)包装类

我还在考虑使用事件包装器类将 JSON 主体构建逻辑封装在单独的类中。然后在事件总线的handleEvent方法中,我可以获取事件对象的类型并使用命名约定找到包装类,然后构造包装类实例,调用toJson方法来获取 JSON 主体。 …

java architecture json software-design instanceof

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

观察者模式遵循/违反哪些可靠原则?

我正在准备考试,目前正在阅读有关观察者模式的内容。然后我想知道观察者模式遵循或违反了哪些SOLID原则?

software-design solid-principles observer-pattern

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

您如何重写在 Java 8 中使用泛型和函数并仅使用面向对象的混合 oop 和函数式编程的代码?

我遇到过这种设计,但我没有完全掌握在 Java 8 中混合面向对象编程和函数式编程。

我对混合两种语言范式很感兴趣,而且互联网上的大多数教程都很简单,所以我无法通过混合来找到有关大规模软件设计的示例。所以有了这个示例案例,我想我有机会挖掘它的某些案例。

在这种情况下,让我展示代码的相关部分。这段代码包含一个通用的 FetchUtils 类,它实现了一个自定义迭代器,但为了简洁起见,我删除了一些部分。

public class FetchUtils<R, MSGIN, MSGOUT> {
    public SomeClass<R> getSomething(MSGIN query,
                                Function<MSGIN, MSGOUT> queryFunc,
                                Function<MSGOUT, List<R>> getResultList) {

               //...
                        MSGOUT callResult = queryFunc.apply(query);
                        buffer = getResultList.apply(callResult);
               //...
               //return someThing;
            }
            //...    
}
Run Code Online (Sandbox Code Playgroud)

在客户端中定义了一个函数和一个指向getCustomer类方法引用的 lambda 表达式。从客户端到使用泛型类型的上述方法的实际调用正在发送这些功能。

public class CustomerResponse {
   //...
   public List<Customer> getCustomer() {
        if (thing == null) {
            thing = new ArrayList<Customer>();
        }
        return this.customers;
    }
   //...
}

public class MyClient {

   //...

   @Autowired
   private FetchUtils<Customer, CustomerRequest, CustomerResponse> fetchUtils;

   //... …
Run Code Online (Sandbox Code Playgroud)

java generics functional-programming software-design java-8

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

使用线程和 tkinter 模块在 python 中停止线程并避免“RuntimeError”的最佳方法是什么?

我在网上经历了多种解决方案,但它们需要大量代码,一旦您扩展,这些代码可能会令人困惑。是否有一种简单的方法可以停止线程并避免RuntimeError: threads can only be started once, 以便无限次调用线程。这是我的代码的简单版本:

import tkinter
import time
import threading

def func():

    entry.config(state='disabled')
    label.configure(text="Standby for  seconds")
    time.sleep(3)
    sum = 0
    for i in range(int(entry.get())):
        time.sleep(0.5)
        sum = sum+i
        label.configure(text=str(sum))
    entry.config(state='normal')

mainwindow = tkinter.Tk()
mainwindow.title('Sum up to any number')

entry = tkinter.Entry(mainwindow)
entry.pack()
label = tkinter.Label(mainwindow, text = "Enter an integer",font=("Arial",33))
label.pack()

print(entry.get())

button = tkinter.Button(mainwindow, text="Press me", command=threading.Thread(target=func).start)
button.pack()
Run Code Online (Sandbox Code Playgroud)

python multithreading tkinter software-design python-multithreading

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

在洋葱、六边形或简洁架构中,域模型是否可以包含与数据库中的域模型不同的属性?

我问你谁知道并有使用任何分层架构(洋葱、六边形、干净等)构建软件的经验。每当我在谷歌上搜索软件架构时,人们都会有不同的观点,并以不同的方式解释相同的架构。

条款

在您阅读问题之前,有些术语可能会让您感到困惑,因此我将在下面对其进行定义。我不确定我是否对它们有“正确”的定义,但我从互联网上收集了这些信息。如果我有误解,请告诉我。

领域层:包含企业/业务逻辑并使用领域模型。位于中心并且不依赖于除领域模型之外的任何其他层。

应用层:包含应用逻辑,从基础设施层接受DTO,传递View Model

DTO(Data Transfer Object):用于在层与层之间传输数据的类、JSON字符串等。可能是一个纯数据容器。

VM(View Model):从应用层传递到表示层的DTO。

DO(Domain Model):域层使用的类、JSON字符串等。可能是一个纯数据容器。

VO(Value Object):数据库实体(一个数据库行),或者数据库使用的一种数据格式。可以从数据库层转移到应用层。

概括

在洋葱、六边形或简洁架构中,域层位于中心(即域层不依赖于域模型以外的任何层,域模型用于将数据传输到其他层或接受来自更高层的数据)。

这意味着域使用的域模型(DTO、POJO、VO 或其他)可能与数据库用于保存持久数据的模型不同。

我画了一个图表,以便我可以给你更好的解释。

在此处输入图片说明

在此处输入图片说明

第一季度

请看第二张图片的红色部分。

与传统的分层或 n 层架构不同,如果领域层位于中心,那么领域模型是否可以拥有比数据库实体(行)更多的属性(或不同的属性)?

例如,假设域层使用一个名为Person的类。用户请求所有在服务器中注册的人的照片。让我们假设数据库只包含所有人的姓名。但是,我们可能会使用其他网络服务器通过姓名请求某人的照片。所以应用层会从数据库中读取所有的名称,并通过这些名称,通过 HTTP 请求从其他 Web 服务器获取所有图片。之后,带有姓名和图片的Person列表将作为视图模型(DTO)发送给用户。

问题二

持久层可能由数据库、文件系统、其他 Web API 等组成。

表示层可以是网站、桌面应用、移动应用、Web API 等。

这两层都是基础设施层的一部分,都依赖于应用层,而应用层只依赖于领域层。

当应用层接受来自表现层的请求时,没有问题,因为表现层调用应用层,表现层知道应用层。

大多数时候,应用层需要从持久层获取数据。

应用层无法在没有任何依赖的情况下调用持久层,因为它不知道持久层中的任何类。

这就是我目前的理解,谁能给我一个清晰的解释,数据应该如何流动以及从低层到高层的通信是如何完成的?

对于那些想写代码的人,我更喜欢 C#。

software-design n-tier-architecture hexagonal-architecture onion-architecture clean-architecture

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