标签: software-design

C 头文件可以被视为接口吗?

我正在从 Robert C. Martin 的《Clean Architecture》一书中学习建筑。本书强调的主要规则之一是 DIP 规则,该规则规定源代码依赖项必须仅指向内部,指向更高级别的策略。尝试将其翻译到嵌入式领域假设 2 个组件schedulertimer. 调度程序是高级策略,它依赖于低级计时器驱动程序,需要调用 API get_current_time()set_timeout()我只需将模块拆分为一个实现文件timer.c和一个标头(一个接口?)timer.h,并且scheduler.c可以简单地包含timer.h使用这些 API 。读这本书将前面的场景描述为违反了依赖关系规则,并暗示应该实现两个组件之间的接口来打破依赖关系。

例如,要模仿 c 中的情况,timer_abstract可以包含带有函数指针的通用结构 struct timer_drv { uint32 (*get_current_time)(void); void (*set_timeout)(uint32 t); }

对我来说,这看起来像是过度设计。一个简单的头文件还不够吗?C 头文件可以被视为接口吗?

c c++ architecture software-design clean-architecture

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

无标签最终效果传播

无标签最终模式让我们可以编写纯函数式程序,这些程序明确说明了它们所需的效果。

然而,扩展这种模式可能会变得具有挑战性。我将尝试用一个例子来证明这一点。想象一个简单的程序,它从数据库读取记录并将其打印到控制台。除了 cats/scalaz 之外,我们还需要一些自定义类型类Database和来组合它们:ConsoleMonad

def main[F[_]: Monad: Console: Database]: F[Unit] =
  read[F].flatMap(Console[F].print)

def read[F[_]: Functor: Database]: F[List[String]] =
  Database[F].read.map(_.map(recordToString))
Run Code Online (Sandbox Code Playgroud)

当我想在内层的函数中添加新的效果时,问题就开始了。例如,我希望我的read函数在未找到记录时记录一条消息

def read[F[_]: Monad: Database: Logger]: F[List[String]] =
  Database[F].read.flatMap {
    case Nil => Logger[F].log("no records found") *> Nil.pure
    case records => records.map(recordToString).pure
  }
Run Code Online (Sandbox Code Playgroud)

但现在,我必须向链上游Logger的所有调用者添加约束。read在这个人为的示例中,它只是main,但想象一下这是一个复杂的现实应用程序的几个层。

我们可以从两个方面来看待这个问题:

  1. 我们可以说,明确我们的效果是一件好事,并且我们确切地知道每一层需要哪些效果
  2. 我们还可以说,这泄漏了实现细节 -main不关心日志记录,它只需要read. 此外,在实际应用中,您会在顶层看到很长的效果链。感觉像是代码味道,但我无法确定我还可以采取什么其他方法。

很想了解您对此的见解。

谢谢。

functional-programming scala software-design tagless-final

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

检查异常是否违反了开闭原则?

我有两个已检查的异常:TestException1TestException2以及以下代码:

void p1() throws TestException1{
    p2();
}

void p2() throws TestException1 { 
    p3();
}

void p3() throws TestException1 {}
Run Code Online (Sandbox Code Playgroud)

对p3的签名进行如下编辑是否违反了开闭原则?

void p3() throws TestException1, TestException2 {}
Run Code Online (Sandbox Code Playgroud)

java oop software-design open-closed-principle

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

同步来自 REST 和 Websocket 的数据

我们正在构建类似于 Messenger 的聊天应用程序。有必需的行为:

  • 用户登录
  • 用户应该看到最后 N 条消息,并且他应该能够加载较旧的消息
  • 还应附加新消息

我的解决方案:

  • 我想结合 REST 使用 websockets 来实现此目的。我的想法是客户端应用程序通过消息 ID 来决定哪些消息需要。因此,REST 将用于初始消息获取和旧消息获取。
  • Websocket 将接收新消息

我应该处理的可能问题:

  • 应用程序开始订阅新消息的 websocket 通道并发送没有初始消息 id 的旧消息请求
  • 调用 GET 请求后有可能出现新消息,并将其存储在 DB 中
  • 客户端应用程序开始订阅 websocket 通道,因此消息将由 websocket 接收。
  • GET 请求不知道此消息并获取最后 N 条消息,其中将出现此新消息,并且客户端应用程序将具有重复记录并且必须过滤此消息

如果有一些优雅的方法来处理这种情况,你能给我建议吗?谢谢。

rest software-design websocket

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

美人鱼 c4 图:元件放置不良

我正在 GitHub 上玩 mermaid 构建 C4 图。

我找不到任何正确放置元素的好方法。

我尝试将 2 个元素与它们之间的关系放在一起(请参阅实时编辑器)。

两个元素的位置非常接近,以至于关系文本不可见。

有什么办法可以改善这一点吗?

我还尝试添加具有白色背景的空元素(请参阅实时编辑器)。

但是,我们依赖于 GitHub 主题之间不同的背景颜色。

不管怎样,需要它自己的UpdateElementStyle块的空元素对我来说似乎是解决方法。

我希望有一个更好的本地解决方案。

architecture diagram software-design mermaid

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

用C/C++编写数据库软件

我几年来一直是一名自学成才的Web开发人员,通常使用C#/ ASP.NET,Python和PHP.但是我想通过做一些更先进的事情来提高我的技能.我希望尝试构建像SQLite这样的数据库程序,或者只是为了练习和学习新东西而在C/C++中构建一个迷你MySQL类的东西.

编辑: 我的项目不一定是RDBMS.它可以是简单的Web服务器之类的东西.如果我喜欢做那种比Web开发更多的东西,那就好了.

但是,我似乎无法在网上找到任何类型的书或教程来教授这类事情.有谁知道我在哪里可以找到有关此的资源?我有一本教授语言本身的C书,但是当我尝试构建像数据库引擎等特定的东西时,我学会了如何更好地思考问题.感谢任何输入.

c c++ database software-design

4
推荐指数
3
解决办法
6709
查看次数

Zend Framework 2 Architecture (how to reduce coupling between modules)?

There are many components in one ZF2 system. Each component has its own presentation layer, business layer, and data layer. The problem is when component Foo has a Controller which uses component Bar's data layer.

example:

<inside modules, each module can be individually deployed or removed>
\modules
   \Foo                  ; one module (this directory) can be added or removed
     \view               ; presentation layer (view) for all subcomponents
        \Subcomponent1
            \Action1
        \Subcomponent2
            \Action2
        ...
     \src
        \Subcomponent1
            \Entity      ; data layer     (model)
            \Controller  ; …
Run Code Online (Sandbox Code Playgroud)

php architecture software-design zend-framework2

4
推荐指数
1
解决办法
1721
查看次数

在java中使用嵌套类的好处

在Java中使用嵌套类有什么好处?在许多示例中,在我看来它只会增加设计的复杂性.是否有任何示例显示使用嵌套类与复合模式进行比较的能力?

java software-design

4
推荐指数
2
解决办法
3078
查看次数

应用程序架构MySQL/PHP/Java/AngularJS

简介: 我们正在重新设计我们的应用程序架构,我们即将制定导入设计决策.

背景和依赖关系:所有数据都存储在分布式MySQL数据库中.我们有两个访问数据库的系统 - 一个执行常规任务,用Java和我们的Web应用程序编程 - 目前是Apache2,PHP(Zend1框架)和JavaScript(jQuery).
Java应用程序将不会重新设计,数据库应保留为MySQL.
Web应用程序应该更改为REST API和通过JSON进行通信的现代,快速,实时的AngularJS前端.
由于我们已经在PHP中编写了所有后端功能,因此坚持使用PHP用于REST API可能是有意义的 - 但如果它使未来的开发更容易,更快速和面向未来,那么这不是必须的.
Java应用程序和Web应用程序共享一些MySQL查询.

问题:

  1. 共享MySQL查询:我们应该将它们实现为a)MySQL过程/视图,b)分别用Java和PHP实现,c)独立服务(例如另一个REST API)
  2. 我们应该坚持使用Zend1还是使用更合适的PHP REST框架(例如Slim或Restler或其他东西)?
  3. 我们应该坚持使用Apache2/PHP作为REST API(也许使用Node.js)?

谢谢!

mysql architecture rest web-applications software-design

4
推荐指数
1
解决办法
870
查看次数

DDD:更新实体的多个属性的指南

所以,我决定学习DDD,因为它似乎解决了我一直面临的一些架构问题.虽然有很多视频和示例博客,但我还没有遇到一个指导我解决以下场景的方法:

假设我有实体

public class EventOrganizer : IEntity
{
    public Guid Id { get; }

    public string Name { get; }

    public PhoneNumber PrimaryPhone { get; }

    public PhoneNumber AlternatePhone { get; private set; }

    public Email Email { get; private set; }

    public EventOrganizer(string name, PhoneNumber primaryPhoneNr)
    {
        #region validations

        if (primaryPhoneNr == null) throw new ArgumentNullException(nameof(primaryPhoneNr));

        //validates minimum length, nullity and special characters
        Validator.AsPersonName(name);

        #endregion

        Id = new Guid();
        Name = name;
        PrimaryPhone = primaryPhoneNr;
    }
}    
Run Code Online (Sandbox Code Playgroud)

我的问题是:假设这将被转换并提供给MVC视图,并且用户想要更新AlternatePhone,电子邮件以及对于给定的有界上下文在该实体中存在有意义的许多其他属性(为简洁起见未示出) ) …

.net c# domain-driven-design software-design

4
推荐指数
1
解决办法
1872
查看次数