首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >OOD与MVC;动态对象与数据库中的一切

OOD与MVC;动态对象与数据库中的一切
EN

Software Engineering用户
提问于 2020-06-10 00:20:29
回答 3查看 243关注 0票数 0

如何使内存高效的代码,但仍然有所有可能的代码很好地封装?

我感觉OO (面向对象)方法更直观,代码组织得很好,并且封装得很好,但它可以使用大量内存,因为内存中通常有许多活动对象实例。

相比之下,MVC (控制器、模型(数据库))方法代码封装得更少,但使用的内存却更少,因为内存中的对象只有当客户端请求时才会被处理。

我需要做一个内部健康监测系统,定期平ip摄像头。将有大约10,000个项目(相机)要监控,一个布尔状态-好/坏。

如果我走OO的道路-我将持有一个类为每个项目,它的ping结果,定时器,事件通知一些其他项目。因此,我将始终在内存中得到10000个实例。没有多少,但如果有100,000,000件呢?我更喜欢这种方式,因为它是直观的,对于我可能需要在具体的item类(计时器、事件、处理程序、订阅)中运行的任何代码,我都有一个完美的(封装的)位置。

如果我采用MVC模式,我将把所有的数据保存在数据库中,这样内存使用量就会降到最低。但是我将不得不临时想出一种触发代码执行的方法,比如周期性的定时器、事件、处理程序、订阅。那个代码-它会写在哪里?它会被很好地封装吗?另外,哪些代码将调用这些触发器?它也会被封装吗?例如,我可以制作定时器引擎,并为10000中的每一个保存一个定时器字典,但是代码将不会被封装。

EN

回答 3

Software Engineering用户

发布于 2020-06-10 04:45:44

OO

不管做什么都行。

甚至MVC也是一种面向对象的设计模式,最初是由SmallTalk (一种纯面向对象语言)引入的。

除非我们讨论的是像JavaScript这样的语言,否则大多数语言都支持一个紧密打包的数据结构。因此,OO做一些事情不会对内存效率产生很大影响。

当您引入诸如子类、混合和属性包之类的灵活性时,会出现一些警告。

MVC

我不认为你对MVC到底是什么有很好的理解。

我认为您所讨论的是活动记录集,或者类似的技术,其中数据库表本身是作为表公开给您自己的函数的。

现在可以使用活动记录作为MVC实现中的对象模型。在这种情况下,声明代码封装得较少是不公平的。

  • 有一个积极的选择是在一组事物的水平上工作,而不是用一件东西。
  • 有一个积极的选择,使用数据无关的,因此业务逻辑贫血表示。
  • 有一种选择是将业务逻辑放在外部。(否则,活动记录本身就会被对象包装)。

多少内存?

  • 布尔值的1字节
  • IPv4 +端口的6个字节( IPv6 +端口的18个字节)
  • GUID的16个字节
  • 最后检查滴答的8个字节
  • 轮询延迟的8个字节(如果每个摄像机可以在不同的频率上轮询)

这给了你:

  • 39字节(48字节填充到16字节对齐)用于IPv4
  • 51字节(64字节填充到16字节对齐)用于IPv6

1Gb内存(1024 * 1024 * 1024字节)

  • 22 369 621对齐IPv4摄像机实例(27 531 841个未对齐实例)
  • 16,777,216对齐IPv6摄像机实例(21,053,761个未对齐实例)

有了一些技巧,就有可能把这个压得更低。

困境

但是无论您做什么,这些数据都将存在于某个地方,无论是存储在数据库中,还是存储在程序本身中。

请注意,如果程序要求的内存比RAM中存储的内存多,那么它将被分页到磁盘,就像在数据库中发生的情况一样。

一台能够访问2GB内存的现代计算机和一个SSD,能够为您的100,000,000个实例编组所需的6GB内存空间,因为大多数64位应用程序中的可寻址空间目前约为2^40。在超出范围之前,您需要担心手动将数据从流程中交换出来,以便腾出空间进行进一步的工作。

如果这看起来太慢了,真正提高性能的最便宜的方法就是升级服务器内存。如今,16 is并不贵,甚至64 is的价格也是合理的。

如果由于某种原因,你的客户(大概能负担得起1亿台相机)负担不起几台服务器(每个服务器都在处理问题的子集),或者无法负担足够的资源将其全部存放在一台机器上,那么你就无能为力了。

数据库

这个数据库的用途是什么?

  • 它是否只是一种序列化格式,只需将程序中的所有数据保存到,然后再加载它?
  • 它是您正在实现的提供数据处理、内存管理和多个并发访问的算法和进程的一个组成部分吗?
票数 3
EN

Software Engineering用户

发布于 2020-06-10 07:42:00

当您反对OOD和MVC时,有一个根本的误解。

  • MVC出现在面向对象的领域,更确切地说是在小谈话环境中。
  • MVC模式中对象之间的职责分离实际上是为了改善复杂系统中对象之间的封装和干净协作,而不是消除它们。
  • 设计良好的对象不一定意味着内存密集型。

还有另一种误解,将MVC与内存中短路对象的数据库导向M联系起来。MVC不知道M是如何与数据库交互的。设计M的方法有很多,例如:

  • 事务脚本表模块使用到数据库的直接桥来实现该模型。
  • 域模型使用内存中的对象实现模型,这些对象使用一些存储库和其他中间对象与数据库进行交互。
  • 活动记录是域模型的变体,每个内存对象都保存在数据库中。

但是还有很多其他的变体。这并不是因为您会将几个域对象保存在内存中才会耗尽您的系统(加载的不是完整的数据库,而是所需的内容)。

如果你想在MVC中寻找一个不错的M设计,而不失去OOD的任何优点,并且了解不同选择的利弊,我可以推荐您Martin的伟大著作"企业应用体系结构模式“。有几个章节专门讨论这个问题。

票数 3
EN

Software Engineering用户

发布于 2020-06-10 09:37:26

您的假设,您必须有一个对象,为每一个ip相机,如果你做OOP,不支持。而且,您似乎是在假设ip摄像机对象需要在任何时候保存与它们相关的数据,或者每个ip摄像机对象都必须始终存在,这也不是事实。

我知道这是不幸的是,在许多项目中,OO是什么样子,但是对于OO来说,这两种假设都是不需要的。在OO中,你准确地模拟了你需要的东西。如果您只想显示当前值,为什么不这样做:

代码语言:javascript
复制
public interface IpCameras {
   UIComponent displayState();
}

如果这是您的用例,那么在OO中没有任何理由拥有更多的东西。所有的“模式”、"MVC“之类的东西都不重要。做适当的建模,大多数(如果不是所有的优化问题)都会有一个合适的地方去。

更新:有更多的要求。点击和计时:我假设调度代码已经在平台上了,所以我可能会这样做:

代码语言:javascript
复制
public interface IpCameras {
   UIComponent displayState();

   void pingAll();
}

pingAll()的电话通过所有的摄像头。这也可能是内部的,IpCameras可以在不公开此方法的情况下这样做,两者都很好。

为了通知一些事情,也许可以用一个参数来扩展这个方法:

代码语言:javascript
复制
void pingAll(PingClient client);

public interface PingClient {
   void onPinged(...ip camera...);

   void onFailed(...ip camera...);
}

然后,您可以有多个PingClient实现,将您想要使用这些信息执行的不同事情分开。一些实现可能是:PingClients (用于多个客户端)、RealTimeClients (用于在线应用程序)、NotificationsClients (用于电子邮件客户端或其他什么)、ThreeFailsClient (仅在连续3次失败注册时才使委托失败)等等。

同样,您可以在不为每个摄像机实例化对象的情况下完成所有这些操作,并且不需要在内存中保留任何多余的数据,同时完全保持封装。

票数 1
EN
页面原文内容由Software Engineering提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://softwareengineering.stackexchange.com/questions/411265

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档