可能已经多次提出类似的问题,但我认为每一个回答都有助于更好地理解DDD.我想描述一下我如何看待DDD的某些方面.我有一些基本的不确定性,如果有人可以提供一个坚实和实用的anwser,我将不胜感激.请注意,这些问题假设采用DDD的"经典"方法.这意味着使用ORM等.此处不考虑CQRS和事件采购等方法.
聚合和实体是实现域逻辑的主要对象.他们有国家和身份.在这种情况下,我将域逻辑视为改变该状态的所有命令的集合.那有意义吗?为什么域逻辑只与状态相关?对没有身份或没有状态的域对象进行建模是否合法?为什么域对象不能作为事务脚本实现?示例:考虑一个建议您成为约会网站合作伙伴的对象.那个对象没有真正的状态,但它确实有很多域逻辑?将其放入服务层意味着域模型不能涵盖所有逻辑.
访问其他域对象.聚合可以访问存储库吗?示例:当(有状态)域对象需要访问系统的所有"用户"以执行其工作时,它需要通过存储库访问它们.因此,ORM在加载对象时需要注入存储库(这在技术上可能更具挑战性).如果对象无法访问存储库,那么您将在何处放置此示例的域逻辑?在服务层?服务层不应该没有逻辑吗?
聚合体和实体不应该与外界交谈,它们只关心它们有限的背景.我们不应该将外部依赖项(如IPaymentGateway或IEmailService)注入域对象,这会导致域处理来自外部的异常.解决方案:基于事件的方法.你怎么发送事件呢?每次实例化域对象时,仍需要注入正确的"侦听器".ORM是关于恢复"数据",但主要不是为了注入依赖关系.我们需要DI-ORM混合物吗?
域对象和DTO.当您查询聚合根的状态时,它是否返回其状态(DTO)或域对象本身的投影?在我看到的大多数模型中,客户端可以完全访问域数据模型,从而引入与域的实际结构的深度耦合.我认为聚合背后的"对象图"是它自己的商业.这是封装,对吗?所以对我来说,聚合根应该只返回DTO.DTO通常在服务层中定义,但我的方法是在域本身中对其进行建模.服务层可能仍会添加另一个抽象级别,但这是一个不同的选择.这是一个很好的建议吗?
存储库处理聚合根级别的所有CRUD操作.其他查询怎么样?查询返回DTO而不是域对象.为了实现这一点,代表必须了解引入耦合的域的数据结构.我的建议与之前类似:使用事件来填充视图.因此,内部结构不公开,只有事件携带必要的数据来构建视图.
工作单位.系统边界处的控制器将实例化命令并将它们传递给服务层,服务层又加载适当的聚合并转发命令.控制器可能使用多个命令并将它们传递给多个服务.这完全由工作单元模式控制.这意味着,存储库,实体,服务 - 都参与同一个事务.你同意吗?
商业逻辑不是域逻辑.从商务角度来看,用例的实现可能涉及许多步骤:注册客户,发送电子邮件,创建存储帐户等.这整个过程可能不可能适合域聚合根.域对象需要访问所有类型的基础结构.解决方案:工作流程或传奇(或事务脚本).这是一个很好的建议吗?
谢谢
clojure reduced函数的目的是什么(在clojure 1.5中添加,https: //clojure.github.io/clojure/clojure.core-api.html#clojure.core/reduced )
我找不到任何例子.医生说:
以某种方式包装x,使得reduce将以值x终止.
还有一个reduced?熟悉它
如果x是对reduce的调用的结果,则返回true
当我尝试一下时,例如(reduce + (reduced 100)),我得到一个错误而不是100.当我事先知道结果时,为什么我会减少一些东西呢?由于它被添加可能有一个原因,但谷歌搜索clojure reduced仅包含reduce结果.
我无法弄清楚如何配置我的web.config以使web-site-admistration工具与visual studio 2012中的MVC 4项目一起工作.
以下是重现此行为的步骤
如果您打开mdf文件(在visual studio中),您将能够在服务器资源管理器窗口中浏览架构.
现在启动网站管理工具(project-> asp.net配置).尝试转到安全选项卡.你应该看到我这样的消息:
您选择的数据存储存在问题.这可能是由无效的服务器名称或凭据或权限不足引起的.它也可能是由未启用角色管理器功能引起的.单击下面的按钮可重定向到可以选择新数据存储的页面.以下消息可能有助于诊断问题:无法连接到SQL Server数据库.
我已经用谷歌搜索了我的问题的解决方案,但似乎大多数答案都针对的是旧版本的MVC/visual studio,所以我还没有成功.令我惊讶的是,当您使用标准MVC 4模板时,web.config中没有成员资格或roleManager部分(而如果您创建一个ASP.NET Forms应用程序,您将看到两个部分.不幸的是我得到了相同的错误ASP.NET WebForms模板,所以我没有继续调查.).此外,roleManager或成员资格配置部分通常定义来自System.Web.Provider程序集的提供程序.MVC 4模板甚至没有引用System.Web.Provider程序集,所以我想知道角色/成员在MVC 4中是如何工作的.它可能在新版本中已经过时但我没有找到关于这个主题的信息(系统) .Web.Security程序集似乎取代了System.Web.Provider).我的错误也可能与我只安装了LocalDB而没有其他SQL服务器实例的事实有关.
所以我的问题是:你能重现这个错误,你能解决它吗?这是什么原因?
任何帮助将不胜感激.
我正在阅读这个OM教程但是我不清楚何时使用OM组件与普通函数(特别是om /组件宏).
该教程写道:
第一个参数是一个函数,它接受应用程序状态数据和后备React组件,这里称为owner.此函数必须返回Om组件 - 即om/IRender接口的模型,如om.core/component宏生成
; here the function (fn [app owner]) indeed returns an OM component
(om/root
(fn [app owner]
(om/component (dom/h2 nil (:text app))))
app-state
{:target (. js/document (getElementById "app"))})
Run Code Online (Sandbox Code Playgroud)
在下一节中,我们找到以下列表的呈现循环示例:
; this one does not return an om component (or does it?). it returns a virtual dom
(om/root
(fn [app owner]
(apply dom/ul nil
(map (fn [text] (dom/li nil text)) (:list app))))
app-state
{:target (. js/document (getElementById "app0"))})
Run Code Online (Sandbox Code Playgroud)
在这里,我们基本上只是直接返回一个(虚拟)dom,而不是包含在OM组件中,所以问题是:为什么om/component宏存在?宏只是帮助我们验证IRender功能,但看起来我们也可以只使用普通函数.我会介绍具有生命周期状态的OM组件(或者需要所有者调用get-props)但是对于只需要创建虚拟dom的组件我宁愿选择简单的函数(所以我不需要构建/构建 - 创建我的虚拟dom的所有功能).我在这里错过了什么?为什么宏仍然有用(我没有看到它).
我无法让leiningen下载datomic-pro peer库.我有以下设置:
~/.lein/credentials.clj.gpg
{#"my\.datomic\.com" {:username "..."
:password "..."}}
Run Code Online (Sandbox Code Playgroud)
和项目
(defproject datomic-example "0.1.0-SNAPSHOT"
:repositories {"my.datomic.com" {:url "https://my.datomic.com/repo"
:creds :gpg}}
:dependencies [[org.clojure/clojure "1.6.0"]
[com.datomic/datomic-pro "0.9.4956"]])
Run Code Online (Sandbox Code Playgroud)
我安装gpg via brew install gpg,然后运行lein deps给我以下错误:
Could not decrypt credentials from /Users/.../.lein/credentials.clj.gpg
gpg: no valid OpenPGP data found.
gpg: decrypt_message failed: eof
See `lein help gpg` for how to install gpg.
(Could not transfer artifact com.datomic:datomic-pro:pom:0.9.4956 from/to my.datomic.com (https://my.datomic.com/repo): Not authorized , ReasonPhrase:Unauthorized.)
This could be due to a typo in :dependencies or network …Run Code Online (Sandbox Code Playgroud) 可以推荐使用clojure生态系统中的哪些技术来开发独立的桌面应用程序?我正在寻找的技术应该得到支持
我想到了以下替代方案:
Clojure的/跷跷板:
clojurescript/HTML5/CSS:
座
我的 docker-compose 文件中有以下配置:
fluentd:
build: ./fluentd
container_name: fluentd
expose:
- 24224
- 24224/udp
depends_on:
- "elasticsearch"
networks:
- internal
public-site:
build: ./public-site
container_name: public-site
depends_on:
- fluentd
logging:
driver: fluentd
options:
tag: public-site
networks:
- internal
networks:
internal:
Run Code Online (Sandbox Code Playgroud)
当我使用 启动应用程序时docker-compose up,网络服务器存在错误消息ERROR: for public-site Cannot start service public-site: failed to initialize logging driver: dial tcp 127.0.0.1:24224: connect: connection denied。
另一方面,当我从 fluentd ( ports: 24224:24224)发布端口时,它可以工作。问题是我不想在主机上发布这些端口,因为它绕过了 linux 防火墙(即它向所有人公开了 fluentd 端口,请参阅此处)。
这令人困惑,因为公开端口应该使其可用于网络中的每个容器。我使用的是fluentd 和网络服务器之间的内部网络,所以我希望 fluentd 的暴露端口就足够了(事实并非如此)。 …
这个问题是一个跟进如何在leiningen repl中预加载clojure文件?.
我~/.lein/profiles.clj看起来如下:
{
:user {:source-paths ["C:/Users/username/.lein/src"] }
}
Run Code Online (Sandbox Code Playgroud)
我的~/.lein/src/user.clj看法如下:
(ns user)
(println "user file loaded")
Run Code Online (Sandbox Code Playgroud)
当我lein repl在包含a的文件夹中运行时project.clj,则user.clj执行该文件,但是当我lein repl从另一个文件夹运行时,它不会加载我的用户配置文件.是否有针对此的解决方法或设计的这种行为?事实上,我知道Leinigen确实加载了我profile.clj(即使没有project.clj),因为里面还有其他东西(取自优秀的pimp我的repl文章).Leinigen只是遇到了我的额外源路径设置问题.
与此相关的另一个问题是我需要为我的user.clj文件指定文件夹的完整路径:"C:/Users/username/.lein/src".当我改变为"~/.lein/src"leiningen无法加载我的文件.
我对这个问题有以下小提琴:http://jsfiddle.net/jcb9xm44/
父div中有2个内联块div:
<div class="outer">
<div class="inner1">
Y
</div>
<div class="inner2">
X
</div>
</div>
Run Code Online (Sandbox Code Playgroud)
css为父div分配宽度,为子div分配2个宽度.
.outer {
width: 210px;
border: 1px solid red;
}
.inner1 {
width: 200px;
border: 1px solid orange;
display: inline-block;
}
.inner2 {
width: 50px;
position:relative;
left: -50x;
display: inline-block;
border: 1px solid lightblue;}
Run Code Online (Sandbox Code Playgroud)
我原以为两个div都出现在同一条线上.虽然父母的宽度不足以容纳两个孩子,但由于第二个孩子有负偏移,所以应该可以将它们放在同一条线上.它为什么打破界限?
我不明白为什么从以下两个例子中,第一个返回正确的值(1),而第二个返回().我已经预料(:key)到它无法找到解决方案的结果或异常,但不是空列表.
(l/run* [q]
(l/== {:key 1} {:key q}))
;; BUT IT DOESNT WORK
(l/run* [q]
(l/== {:key 1} {q 1}))
Run Code Online (Sandbox Code Playgroud)