标签: software-design

我应该在.cpp和.h中重复包含吗?

场景:

foo.h中:

#include <vector>

class foo {
  public:
  std::vector<int>* getVector();

  /* ... other methods declarations ... */

}
Run Code Online (Sandbox Code Playgroud)

Foo.cpp中:

#include "foo.h"
#include <vector>

/* ... other methods definitions using std::vector ... */

std::vector<int>* foo::getVector() {
  return new std::vector<int>();
}
Run Code Online (Sandbox Code Playgroud)

我希望.cpp独立于标头中未来可能的任何变化.如果由于某种原因,类的接口发生了变化并且依赖性<vector>可以被消除,我冒着.cpp中的其他方法也会失去包含的风险.

重复包含<vector>在.cpp和.h中是否正确?这种做法是否有意义,还是仅仅依靠标题中包含的内容?

c++ software-design include

7
推荐指数
1
解决办法
1255
查看次数

为移动和Web应用程序设计通用服务器端

我有一个项目,我应该开发一个移动应用程序(android)和一个网站.由于它们都具有相同的数据库/内容和功能,我想为移动和Web应用程序编写通用服务器端.

现在我有两个选择:

  1. 我的Android应用程序和网站(HTML/Javascript)将与之通信的服务器端开发RESTful Web服务.我认为这不适合网站开发,因为您在页面加载时使用javascript填充所有HTML组件值.

  2. 使用MVC框架(例如CodeIgniter)开发Web应用程序,其中每个页面将具有两个视图:
    a)用于Web站点的公共HTML/CSS/Javascript页面
    b)用于移动应用程序的JSON数据.在这种情况下,移动应用程序将对URL进行HTTP GET调用:www.mySite/someParameters,它将响应JSON数据.

哪一个更好选择?
或者,您还有其他建议吗?

architecture web-applications server-side software-design mobile-application

7
推荐指数
1
解决办法
3792
查看次数

如何在双向关联中实例化不可变类?

我有两个不可变的类:用户部门,它们使用双向关联连接 - 用户部门的引用,部门有一个用户列表.如何使用提供的用户创建新的Department实例?

码:

class User {
    private final Department department;
    private final String name;

    public User(Department department, String name) {
        this.department = department;
        this.name = name;
    }
}

class Department {
    private final List<User> users;
    private final String name;

    public Department(List<User> users, String name) {
        this.users = new ArrayList<>(users);
        this.name = name;
    }
}
Run Code Online (Sandbox Code Playgroud)

java software-design immutability

7
推荐指数
2
解决办法
902
查看次数

用于对两个竞争对象建模的设计模式

我正在试图找出用于管理两个交互对象之间"竞争"的最佳设计模式.例如,如果我想要Fox一个Rabbit通过简单环境追逐类的类.我想让他们"竞争"并找出哪一个获胜.最终它将成为学生可以用来试验继承和其他OO编程技能的教学工具.

这个用例是否有既定的设计模式?

这是我能想到的最好的:一个表示托管其他对象的环境的类.我保持它非常简单,并假设动物只是直线运行而狐狸抓住兔子,如果他足够接近咬兔子.这是一些代码,展示了我所描述的内容.我使用PHP是因为我可以快速编写它,但我不想专注于语言的细节.我的问题是关于设计模式/架构.

class Forrest() {
        public $fox;
        public $rabbit;
        public $width = 100; //meters?
        public $length = 100;

        __construct() {
                $this->fox = new Fox();
                $this->rabbit = new Rabbit();
                $this->theChase();
        }

        public function theChase() {
                 while (!$this->rabbit->isBitten) {
                         $this->rabbit->react($fox);
                         $this->fox->react($rabbit);
                 }
                 log('The fox got the rabbit!');
        }
}

abstract class Animal() {
        public $speed;
        public $hasTeeth = false;
        public $position;
        public $direction;
        public $isBitten = false;
        public function run($distance) {
                // update coordinates based on direction …
Run Code Online (Sandbox Code Playgroud)

events design-patterns software-design game-engine game-loop

7
推荐指数
1
解决办法
315
查看次数

TypeScript/Angular2中的DTO设计

我目前正在开发一个Angular 2应用程序.在开发过程中,我开始使用TypeScript类从JSON创建对象,我通过HTTP或在表单中创建新对象时创建对象.

例如,该类可能看起来像这样.

export class Product {
    public id: number;
    public name: string;
    public description: string;
    public price: number;
    private _imageId: number;
    private _imageUrl: string;

    constructor(obj: Object = {}) {
        Object.assign(this, obj);
    }

    get imageId(): number {
        return this._imageId;
    }
    set imageId(id: number) {
        this._imageId = id;
        this._imageUrl = `//www.example.org/images/${id}`;
    }

    get imageUrl(): string {
        return this._imageUrl;
    }

    public getDTO() {
        return {
            name: this.name,
            description: this.description,
            imageId: this.imageId,
            price: this.price
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

到目前为止,上面显示的这个解决方 但现在让我们假设对象中有更多属性,我想要一个干净的DTO(例如没有私有属性),通过POST将此Object发送到我的服务器.一个更通用的getDTO()功能怎么样?我想避免列出很长的财产分配清单.我在考虑为属性使用装饰器.但我真的不知道如何使用它们来过滤DTO的属性.

software-design restful-architecture typescript ecmascript-6

7
推荐指数
1
解决办法
7023
查看次数

在Angular中使用jQuery是不好的做法吗?

我的问题如下。我应该避免在Angular应用程序中使用任何种类的jQuery代码,因为与DOM交互只有一件事是合法的。另一个问题是,是否有人遇到除了使用jQuery编写快速hack之外找不到其他解决方案的问题。

谢谢!

javascript jquery software-design angularjs angular

7
推荐指数
2
解决办法
4343
查看次数

通常的做法是从实现中抽象库依赖项吗?

我对这个问题的回答是"不".但我的同事不同意.

我们正在重建我们的产品,并在短期内做出许多关键决策.

在做我自己的一些工作时,我注意到我们有一些内部C++类来抽象一些POSIX API(线程,互斥,信号量和rw锁)和其他实用程序类.请注意,这些类是基本的,并且尚未从Linux移植(可移植性是重建的一个因素.)我们也使用POCO C++库.

我把它引起了我的同事的注意,并建议我们放弃我们的内部课程以支持他们的POCO等价物.我想充分利用我们已经使用的库.他们建议我们应该使用POCO实现我们的内部类,并在必要时进一步抽象出额外的POCO类,以便不依赖于任何特定的C++库(引用未来的未知数 - 如果我们想要使用不同的lib /框架,那该怎么办? QT或提升,如果我们选择的那个结果不好或开发变得不活跃,等等.)

他们也不想重构遗留代码,并且通过使用我们自己的类抽象POCO的部分,我们可以实现其他功能(经典OOP.)我可以理解这两个参数.但是,我认为,如果我们正在进行重新编码,我们应该变大,或者回家.现在是重构的时候了,它确实不应该那么糟糕,特别是考虑到我们的类和POCO(线程等)之间的相似性我不知道对于第二点说什么 - 我们应该只使用需要功能的扩展类?

我的同事也不想在整个地方乱丢POCO命名空间.我认为我们应该选择一个库/框架/工具包,并坚持下去.充分利用其功能.这不是典型的做法吗?我见过的唯一一个抽象整个框架的项目是Freeswitch(它为APR提供了自己的接口.)

一个建议是我们彼此暴露的API和潜在客户应该没有POCO,但它会出现在实现中(这是有意义的.)

我们中没有人真正拥有这些设计决策的经验,并且它在当前的产品中显示出来.从我年轻的时候就一直在这里,我有一些直觉让我来到这里,但也没有实际经验.我真的想避免解决已经解决的问题.

我认为我的问题归结为:在构建产品时,我们是否应该a)选择一个支配大部分代码的主导框架,以及b)期望该框架与产品紧密结合?这不是框架的重点吗?(框架或库是否更适合POCO?)

c++ architecture frameworks software-design

6
推荐指数
2
解决办法
1078
查看次数

如何设计谷歌阅读器等新闻提要系统?

我正在准备一个系统设计面试,我在面试中被问到这样的问题,所以我想展示我的设计过程.另外,我想在这个过程中解决一些困难的最佳实践是什么.我想在可伸缩性方面考虑如何处理数据库上繁重的读写操作.如果我在任何想法中错了,请纠正我.

首先,我想构建一个函数subscribe/unsubscribe.对于用户,我想设计标记提要已读/未读.我该如何设计这样的系统?乍一看,我可以看到的第一个问题是,如果我将每个数据都放在数据库中,一旦成千上万的用户订阅/取消订阅某些来源或媒体来源(如CNN帖子每5次),就会对数据库进行大量的读/写操作. - 10分钟

显然,一旦用户进入某一点,数据库将成为瓶颈.我怎样才能解决这个问题?解决这个问题的想法是什么?虽然从这个角度来看数据库是一个瓶颈,但我们仍然需要拥有数据库但设计更好吗?我看到很多文章谈论非规范化数据.

问题:为每个来源存储订阅者的最佳方式是什么?

在数据库中,我可以认为一个表有"source_id""user_id",user_id订阅了source_id.这是一个好的设计还是坏的?如果大量用户订阅新源,那么数据库将成为负担.方法我可以想到这是使用Redis,它提供快速写入和快速读取. 优点:

  • 快速读写操作.
  • 提供多个数据结构而不是简单的键值存储.

缺点:

  • 数据需要适合内存⇒ 解决方案:分片.Sharding我可以使用twemproxy来管理集群.

  • 如果数据丢失,我们丢失数据⇒ 解决方案:复制,拥抱"主从"设置.写入主站,从从站读取并将数据备份到磁盘(数据持久性).此外,每小时拍摄一次快照.

现在我列出了迁移到redis集群的优缺点,如何在redis中存储源和订户之间的关系?如果我有一个散列图,将每个源和每个点存储到一个订户列表,这是一个好的设计.

例如,

Cnn⇒(sub1,sub2,sub3,sub4 ......)Espn⇒(sub1,sub2,sub3,sub4 ..)...

在可伸缩性方面,我们可以将每个源和用户分成每个专用的redis节点.
<< ==这至少是我现在能想到的.

此外,我们还可以在redis中存储用户信息(用户订阅的内容),并将shard用户存储到多个群集

User1⇒(source1,source2,source4 ..)User2⇒(source1,source2,source4 ..)...

对于来自单一来源的feed和post,我可以同时拥有数据库表和redis数据结构(基本上,我的想法是将所有内容存储在redis和数据库中作为备份,在这种情况下它是一个很好的设计考虑因素吗?也许不是一切,只有活动用户在redis或最近的feed中)

数据库:我希望尽可能简洁,只存储它的副本.feedID,sourceID,created_timestamp,data

Redis:存储feedID,source_id和内容,并根据source_id查找订阅者.

对于读/未读部分,我不清楚如何围绕这些限制进行设计.每个用户都有加入时间戳,如果用户没有读取,服务器将推送源(每个源最多10个源).用户是否读取数据的好设计是什么?我最初的想法是跟踪每个读取或未读取的用户.但是这张桌子可以线性增长到饲料的大小.在redis中,我可以设计类似的结构.

Userid,feedid,status User1,001,读取User1,002,读取User1,003,未读

此时,我最初设置数据结构的想法如上所述.Redis每小时运行"主从"设置并备份到磁盘.

现在我将考虑订阅/取消订阅功能的过程如何工作.用户单击媒体页面上的订阅按钮,例如CNN.Web服务器接收请求"用户X"订阅"源Y".在应用层逻辑上,找到具有用户X数据的机器,这可以通过在每个应用服务器上安装分片映射来实现.就像这个user_id mod shard = machineid一样工作.

一旦应用程序查找具有其(用户X)数据的服务器ip,应用程序服务器就会与redis节点通信并使用新的source_id更新用户结构.订阅功能是一回事.

对于用户X上的特定订阅源的读取/未读取,应用程序将查找redis节点并更新其结构,并且redis异步地对数据库进行更新.(这里我拥抱最终的一致性).

让我们考虑如何设计推/拉模型.对于推送通知,一旦有最近的提要,我可以用redis存储它最新的提要并仅更新活动用户(原因是尽可能避免对数据库进行尽可能多的写操作).

对于拉模型,只有在用户重新加载其主页面页面时才更新用户,这也避免了大量的磁盘搜索时间.

一些要点:

  • 仅将活动用户置于redis中(最近30天登录)
  • 如果用户在6个月内未处于活动状态,并且最近已重新登录并希望检查Feed.还有另一项服务从数据库重建数据并放入redis并为用户服务.
  • 将最近的Feed存储在redis中,此时仅向活动订阅者推送通知.这是为了避免数据库上的磁盘寻道时间.
  • 为了使Feed可排序,请在feedID中设计时间戳.例如,feedID的前10位是时间戳,并且我们还可以为ID中嵌入的sourceID另外10位.这使得饲料可以进行排序.
  • 应用程序服务器可以水平扩展并隐藏在负载均衡器后面.
  • 应用程序服务器连接到redis集群,数据库用于存储和重建数据(如非活动用户案例)
  • Redis应用"主从"设置.写入主站,从从站读取并异步复制数据.及时将数据备份到磁盘.还异步更新数据库.

问题:

  • 当新事件成为可行的解决方案时,是否使用redis异步更新数据库?或只是保持复制就足够了?

我知道这是一篇很长的帖子,想听听社区的回复.请纠正我,如果我错了或指出任何,所以我们可以讨论更多关于方法.

system software-design redis

6
推荐指数
0
解决办法
1568
查看次数

Java - 委托方法的正确方法

我的程序从外部源获取信息(可以是文件,数据库或我将来可能决定的任何其他内容).

我想定义一个具有我所有数据需求的接口,以及实现它的类(例如,一个用于从文件获取数据的类,另一个用于DB的数据等).

我希望我的项目的其余部分不关心数据的来源,也不需要创建任何对象来获取数据,例如调用"DataSource.getSomething();"

为此,我需要DataSource包含接口类型的变量,并使用其中一个具体实现对其进行初始化,并将其所有方法(来自接口)公开为静态方法.

因此,假设接口名称为K,具体实现为A,B,C.

我今天这样做的方式是:

public class DataSource  {
    private static K myVar = new B();

    // For **every** method in K I do something like this:

    public static String getSomething() {
          return myVar.doSomething();
    }

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

这是非常糟糕的,因为我需要复制接口的所有方法并使它们静态,因此我可以将它委托给myVar,以及许多其他明显的原因.

这样做的正确方法是什么?(也许它有一个设计模式?)

**注意 - 因为这将是许多其他项目的支柱,我将使用来自数千(如果不是数万)代码行的这些调用,我坚持像"DataSource.getSomething();"那样保持简单,我不要像"DataSource.getInstance().getSomething();"**

编辑:我在这里提供使用像Guice这样的DI框架,这是否意味着我需要在我的所有项目中的每个入口点(即"主"方法)中添加DI代码,或者有一种方法可以执行一次所有项目?

java design-patterns software-design

6
推荐指数
1
解决办法
4656
查看次数

如果没有logstash,我应该使用弹性搜索进行日志记录

我打算使用Elasticsearch记录我的所有应用程序活动(如审计日志).

考虑到我如何直接控制应用程序,我应该使用他们的REST API直接将数据推送到Elasticsearch,还是应该以某种方式使用Logstash将数据提供给Elasticsearch?

当我可以直接将数据推送到Elasticsearch时,有什么理由我应该使用Logstash吗?这是一个额外的管理层.

architecture software-design elasticsearch

6
推荐指数
1
解决办法
580
查看次数