谁会看,可以男人主动告诉我他喜欢的类型这是什么类型的贫血吗?

老婆贫血,谁能告诉我吃什么能补血?_百度知道
老婆贫血,谁能告诉我吃什么能补血?
答题抽奖
首次认真答题后
即可获得3次抽奖机会,100%中奖。
季諾管理丶結呠
季諾管理丶結呠
采纳数:76
获赞数:52
擅长:暂未定制
补血从食补和药补双管齐下,效果最佳。平时饮食补铁应多吃黑木耳、紫菜、发菜、荠菜、黑芝麻、莲藕粉、红枣、当归、阿胶、黑米、黑豆等食物,这些都是最好的补血食物。
药补方面可以考虑体恒健牌铁之缘片,除了含有现代补铁制剂乳酸亚铁外,还将传统的中药阿胶添加进去,性温和,达到养血补气的功效;添蛋白锌提高人体的免疫力,三效合一全面调理人体的健康。补铁时一起补充第三代蛋白锌,非常有利于铁和其他微量元素的吸收,彻底解决贫血症状。15年临床验证,品质值得信赖! ——淘宝商城“ 体恒健保健食品专营”为您解答,希望能够给您帮助,同时也希望您能采纳,谢谢!!麻烦采纳,谢谢!
采纳数:69
获赞数:61
擅长:暂未定制
贫血是指血液中缺少红细胞或红细胞的主要成分血红蛋白。造成贫血的原因主要有红细胞过度破坏,造血不良和失血。
贫血在祖国医学属“虚证”范畴,虚证常见有血虚、气虚、阴虚、阳虚等。患者可根据自己的病情,选择适宜的食疗方法进行调治:
1、龙眼肉15克,红枣3-5枚,粳米100克。同煮成粥,热温服。
功效:养心补脾,滋补强壮。&&女性补血的食疗菜单
2、新鲜羊骨2斤(1000克),粳米200克。
羊骨洗净捶碎,加水熬汤,去渣后,入粳米共煮成粥。食用时中适量调米温服,10-15天为一疗程。
功效:补肾壮骨。
3、糙糯米100克,薏苡仁50克,红枣15枚。同煮成粥。食用时加适量白糖。
功效:滋阴补血。女性贫血该怎么补?
4、制首乌60克,红枣3-5枚,粳米100克。先以制首乌煎取浓汁去渣,加入红枣和粳米煮粥,将成,放入红糖适量,再煮一二沸即可。热温服。首乌忌铁器,煎汤煮粥时需用少锅或搪瓷锅。
功效:补肝益肾,养血理虚。&&女性必学的五大养血法
5、鸡蛋2个,取蛋黄打散,水煮开先加盐少许,入蛋黄煮熟,每日饮服2次。
功效:补铁,适用于缺铁性贫血。
临床观察表明,许多贫血患者,血红蛋白低下是由于身体内某一造血原料不足引起的。只要根据不同类型的贫血,补充相应的造血原料,贫血就能纠正。而补充原料,大部分患者只要注意饮食就能办到。
(1)缺铁性贫血.需补充含铁丰富的食物。这类食物有:猪肝、牛肝、鸡鸭肝、猪腰、猪肚、牛腰、牛肺、牛肉汁、蛋黄粉、银鱼干、黄鱼干、鱿鱼、海蛰、虾米与虾仁等荤菜;菠菜、油菜、荠菜、金针菜、韭菜、芹菜、豆腐皮、豆腐干,以及桃、橘、枣等。以上食物以猪肝、牛肝、鸡鸭肝最佳。
(2)叶酸和维生素B12缺乏性贫血,应补充动物肝及肾、瘦肉、绿叶蔬菜等。
(3)蛋白质供应不足引起的贫血,应补充瘦肉、鸡、鸭、牛羊肉,以及豆类制品。
需要说明的是,贫血患者的胃肠功能一般处于低下状态,补充食物时应逐渐增加,以免加重胃肠道负担,引起消化吸收不良。 贫血是指血液中红血球数量太少,血红素不足。贫血分成几种不同的情形,其中一种是缺铁性贫血,所谓的缺铁性贫血就是红血球中铁质含量太少,这也是所有贫血情形中最常见的一种。要预防缺铁性贫血,首先要注意饮食,要均衡摄取红肉、肝脏、蛋黄、榖类等富含铁值的食物。如果饮食中摄取的铁质不足或是缺铁严重,则必须补充铁剂。维他命C可以帮助铁质的吸收,也能帮助制造血红素,所以维他命C的摄取量也要充足。要注意的是,牛奶及一些中和胃酸地药物会阻碍铁质的吸收,所以尽量不要和含铁的食物一起食用。
只要是女性就比较容易患上缺铁性贫血,这是因为女性每个月生理期会固定流失血液。所以平均大约有20%的女性、50%的孕妇都会有贫血的情形。 如果贫血不十分严重,就不必去吃各种补品,只要调整饮食就可以改变贫血的症状。 比如首先要注意饮食,要均衡摄取肝脏、蛋黄、谷类等富含铁质的食物。如果饮食中摄取的铁质不足或是缺铁严重,就要马上补充铁剂。维他命C可以帮助铁质的吸收,也能帮助制造血红素,所以维他命C的摄取量也要充足。其次多吃各种新鲜的蔬菜。许多蔬菜含铁质很丰富。如黑木耳、紫菜、发菜、荠菜、黑芝麻、莲藕粉等。 推荐几样家常的补血食物: 黑豆:我国古时向来认为吃豆有益,多数书上会介绍黑豆可以让人头发变黑,其实黑豆也可以生血。黑豆的吃法随各人喜好,如果是在产后,建议用黑豆煮乌骨鸡。 发菜:发菜的颜色很黑,不好看,但发菜内所含的铁质较高,用发菜煮汤做菜,可以补血。 胡萝卜:胡萝卜含有很高的维生素B、C,同时又含有一种特别的营养素-胡萝卜素,胡萝卜素对补血极有益,用胡萝卜煮汤,是很好的补血汤饮。不过许多人不爱吃胡萝卜,我个人的做法是把胡萝卜榨汁,加入蜂蜜当饮料喝。 面筋:这是种民间食品。一般的素食馆、卤味摊都有供应,面筋的铁质含量相当丰富。而补血必须先补铁。 菠菜:这是最常见的蔬菜。也是有名的补血食物,菠菜内含有丰富的铁质胡萝卜素,所以菠菜可以算是补血蔬菜中的重要食物。如果不爱吃胡萝卜,那就多吃点蔬菜吧。 金针菜:金针菜含铁数量最大,比大家熟悉的菠菜高了20倍,铁质含量丰富,同时金针菜还含有丰富的维生素A、B1、C、蛋白质、脂肪及秋水仙醉碱等营养素。 龙眼肉:龙眼肉就是桂圆肉,任何一家超市都有售。龙眼肉除了含丰富的铁质外还含有维生素A、B和葡萄糖、蔗糖等。补血的同时还能治疗健忘、心悸、神经衰弱和失眠症。龙眼汤、龙眼胶、龙眼酒之类也是很好的补血食物。 萝卜干:萝卜干本来就是有益的蔬菜,它所含的维生素B极为丰富,铁质含量很高。所以它是最不起眼最便宜但却是最好的养生食物,它的铁质含量除了金针菜之外超过一切食物。 需要注意的是:贫血者最好不要喝茶,多喝茶只会使贫血症状加重。因为食物中的铁,是以3价胶状氢氧化铁形式进入消化道的。经胃液的作用,高价铁转变为低价铁,才能被吸收。可是茶中含有鞣酸,饮后易形成不溶性鞣酸铁,从而阻碍了铁的吸收。其次,牛奶及一些中和胃酸的药物会阻碍铁质的吸收,所以尽量不要和含铁的食物一起食用
采纳数:64
获赞数:152
擅长:暂未定制
天然阿胶 还有黄芪,当归,党参,川芎各10g 阿胶(一小块的三分之一量啊10g左右)这个益气补血的
为你推荐:
其他类似问题
您可能关注的内容
个人、企业类
违法有害信息,请在下方选择后提交
色情、暴力
我们会通过消息、邮箱等方式尽快将举报结果通知您。已解决问题
我家宝贝9个半月了,今天查出缺铁性贫血,宝儿正在发高烧,告诉我该怎么办?
宝贝从昨天下午开始发烧,从低烧到高烧38.9度,吃药不退,今天去医院做了血常规,缺铁性贫血,该怎么办?
浏览次数:302
用手机阿里扫一扫
最满意答案
你好治疗原则  治疗IDA的原则是:①根除病因;②补足贮铁。病因治疗  婴幼儿、青少年和妊娠妇女营养不足引起的IDA,应改善饮食。补铁治疗  治疗性铁剂有无机铁和有机铁两类。无机铁以硫酸亚铁为代表,有机铁则包括右旋糖酐铁、葡萄糖酸亚铁、山梨醇铁、富马酸亚铁和多糖铁复合物等。无机铁剂的副反应较有机铁剂明显。疾病预防  重点放在婴幼儿、青少年和妇女的营养保健。对婴幼儿,应及早添加富含铁的食品,如蛋类、肝、菠菜等
答案创立者
以企业身份回答&
正在进行的活动
生意经不允许发广告,违者直接删除
复制问题或回答,一经发现,拉黑7天
快速解决你的电商难题
店铺优化排查提升2倍流量
擅长&nbsp 店铺优化
您可能有同感的问题
扫一扫用手机阿里看生意经
问题排行榜
当前问题的答案已经被保护,只有知县(三级)以上的用户可以编辑!写下您的建议,管理员会及时与您联络!
server is ok我缺铁性贫血,有人告诉我这情况可以一直吃叶酸到生,会缓解一下贫血。想问一下是不是这样真的行?
来自妈妈帮社区:
两种都是造血原料,可以吃
补血药配点维生素c,促进吸收
我觉得可以喝点铁原
和我一样,我才33,今天去抽血差点晕了,医生也是给我开的那个药,他说多吃黑色,红色,瘦肉之类的
补血药配点维生素c,促进吸收
现在就是在吃补铁药加维c
和我一样,我才33,今天去抽血差点晕了,医生也是给我开的那个药,他说多吃黑色,红色,瘦肉之类的
我没有你那么严重,就是没怀孕之前冬天总是手脚冰冷。有时候蹲下起来有点点眼花。其他倒是没有什么症状了,我觉得我就算是贫血也应该是轻微的。
我也查了缺铁,但是我缺的不厉害,不贫血,医生没让我吃药,让多吃动物肝脏!
我16周开始缺铁性贫血,大夫让我吃力蜚能,但是和爱乐维还有补钙的不能一起吃,中间要隔两个小时
妈妈帮百科热门内容
微信服务号
礼包领取指南NO.1
关注妈妈帮服务号
即送育儿百宝箱
还有海量免费试用不要白不要!
礼包领取指南NO.2
第1步:扫码成功下载后,首页即可领取新人专属礼包。
第2步:填写收货信息,轻松领取帮宝适新生礼盒,更有机会获得?198帮Box大礼盒!
&&手机客户端&&备孕&&相同预产期&&同龄宝宝2018年2017年2016年2015年2014年2013年2012年2011年&&同城(21个)(11个)(13个)&&妈妈兴趣&&宝宝兴趣&&特别关注&&非常有用&&微专题
||||||
上海丫丫信息科技有限公司版权所有
沪B2- 沪ICP备号在论坛看到一个好帖:
最近taowen同学连续发起了两起关于贫血模型和领域模型的讨论,引起了大家的广泛热烈的讨论,但是讨论(或者说是争论)的结果到底怎样,我想值
得商榷。问题是大家对贫血模型和领域模型都有自己的看法,如果没有对此达到概念上的共识,那么讨论的结果应该可想而知,讨论的收获也是有的,至少知道了分
歧的存在。为了使问题具有确定性,我想从一个简单例子着手,用我对贫血模型和领域模型的概念来分别实现例子。至于我的理解对与否,大家可以做评判,至少有
个可以评判的标准在这。一个例子
我要举的是一个银行转帐的例子,又是一个被用滥了的例子。但即使这个例子也不是自己想出来的,而是剽窃的&&POJOs in Action&&中的例子,原谅我可怜的想像力
。当钱从一个帐户转到另一个帐户时,转帐的金额不能超过第一个帐户的存款余额,余额总数不能变,钱只是从一个账户流向另一个帐户,因此它们必须在一个事务内完成,每次事务成功完成都要记录此次转帐事务,这是所有的规则。
我们首先用贫血模型来实现。所谓贫血模型就是模型对象之间存在完整的关联(可能存在多余的关联),但是对象除了get和set方外外几乎就没有其它的方
法,整个对象充当的就是一个数据容器,用C语言的话来说就是一个结构体,所有的业务方法都在一个无状态的Service类中实现,Service类仅仅包
含一些行为。这是Java
Web程序采用的最常用开发模型,你可能采用的就是这种方法,虽然可能不知道它有个&贫血模型&的称号,这要多
亏Martin Flower(这个家伙惯会发明术语!)。
在讨论具体的实现之前,我们先来看来贫血模型的包结构,以便对此有个大概的了解。
贫血模型的实现一般包括如下包:
dao:负责持久化逻辑
model:包含数据对象,是service操纵的对象
service:放置所有的服务类,其中包含了所有的业务逻辑
facade:提供对UI层访问的入口
先看model包的两个类,Account和TransferTransaction对象,分别代表帐户和一次转账事务。由于它们不包含业务逻辑,就是一个普通的Java Bean,下面的代码省略了get和set方法。
String accountId;
Account() {}
Account(String accountId, BigDecimal balance) {
.accountId = accountId;
.balance =
public class Account {
private String accountId;
private BigD
public Account() {}
public Account(String accountId, BigDecimal balance) {
this.accountId = accountId;
this.balance =
// getter and setter ....
TransferTransaction {
String fromAccountId;
String toAccountId;
TransferTransaction() {}
TransferTransaction(String fromAccountId, String toAccountId, BigDecimal amount, Date timestamp) {
.fromAccountId = fromAccountId;
.toAccountId = toAccountId;
.timestamp =
public class TransferTransaction {
private String fromAccountId;
private String toAccountId;
private BigD
public TransferTransaction() {}
public TransferTransaction(String fromAccountId, String toAccountId, BigDecimal amount, Date timestamp) {
this.fromAccountId = fromAccountId;
this.toAccountId = toAccountId;
this.amount =
this.timestamp =
// getter and setter ....
这两个类没什么可说的,它们就是一些数据容器。接下来看service包中TransferService接口和它的实现
TransferServiceImpl。TransferService定义了转账服务的接口,TransferServiceImpl则提供了转账服
务的实现。
TransferService {
TransferTransaction transfer(String fromAccountId, String toAccountId, BigDecimal amount)
AccountNotExistedException, AccountUnderflowE
public interface TransferService {
TransferTransaction transfer(String fromAccountId, String toAccountId, BigDecimal amount)
throws AccountNotExistedException, AccountUnderflowE
TransferServiceImpl
implements
TransferService {
AccountDAO accountDAO;
TransferTransactionDAO transferTransactionDAO;
TransferServiceImpl(AccountDAO accountDAO,
TransferTransactionDAO transferTransactionDAO) {
.accountDAO = accountDAO;
.transferTransactionDAO = transferTransactionDAO;
TransferTransaction transfer(String fromAccountId, String toAccountId,
BigDecimal amount) throws
AccountNotExistedException, AccountUnderflowException {
Validate.isTrue(amount.compareTo(BigDecimal.ZERO) & 0
Account fromAccount = accountDAO.findAccount(fromAccountId);
(fromAccount ==
AccountNotExistedException(fromAccountId);
(fromAccount.getBalance().compareTo(amount) &
AccountUnderflowException(fromAccount, amount);
Account toAccount = accountDAO.findAccount(toAccountId);
(toAccount ==
AccountNotExistedException(toAccountId);
fromAccount.setBalance(fromAccount.getBalance().subtract(amount));
toAccount.setBalance(toAccount.getBalance().add(amount));
accountDAO.updateAccount(fromAccount);
accountDAO.updateAccount(toAccount);
transferTransactionDAO.create(fromAccountId, toAccountId, amount);
public class TransferServiceImpl implements TransferService {
private AccountDAO accountDAO;
private TransferTransactionDAO transferTransactionDAO;
public TransferServiceImpl(AccountDAO accountDAO,
TransferTransactionDAO transferTransactionDAO) {
this.accountDAO = accountDAO;
this.transferTransactionDAO = transferTransactionDAO;
public TransferTransaction transfer(String fromAccountId, String toAccountId,
BigDecimal amount) throws AccountNotExistedException, AccountUnderflowException {
Validate.isTrue(amount.compareTo(BigDecimal.ZERO) & 0);
Account fromAccount = accountDAO.findAccount(fromAccountId);
if (fromAccount == null) throw new AccountNotExistedException(fromAccountId);
if (fromAccount.getBalance().compareTo(amount) & 0) {
throw new AccountUnderflowException(fromAccount, amount);
Account toAccount = accountDAO.findAccount(toAccountId);
if (toAccount == null) throw new AccountNotExistedException(toAccountId);
fromAccount.setBalance(fromAccount.getBalance().subtract(amount));
toAccount.setBalance(toAccount.getBalance().add(amount));
accountDAO.updateAccount(fromAccount);
// 对Hibernate来说这不是必须的
accountDAO.updateAccount(toAccount);
// 对Hibernate来说这不是必须的
return transferTransactionDAO.create(fromAccountId, toAccountId, amount);
TransferServiceImpl类使用了AccountDAO和TranferTransactionDAO,它的transfer方法负责整个
转帐操作,它首先判断转帐的金额必须大于0,然后判断fromAccountId和toAccountId是一个存在的Account的
accountId,如果不存在抛AccountNotExsitedException。接着判断转帐的金额是否大于fromAccount的余额,如
果是则抛AccountUnderflowException。接着分别调用fromAccount和toAccount的setBalance来更新它
们的余额。最后保存到数据库并记录交易。TransferServiceImpl负责所有的业务逻辑,验证是否超额提取并更新帐户余额。一切并不复杂,对
于这个例子来说,贫血模型工作得非常好!这是因为这个例子相当简单,业务逻辑也不复杂,一旦业务逻辑变得复杂,TransferServiceImpl就
贫血模型的优点是很明显的:
被许多程序员所掌握,许多教材采用的是这种模型,对于初学者,这种模型很自然,甚至被很多人认为是java中最正统的模型。
它非常简单,对于并不复杂的业务(转帐业务),它工作得很好,开发起来非常迅速。它似乎也不需要对领域的充分了解,只要给出要实现功能的每一个步骤,就能实现它。
事务边界相当清楚,一般来说service的每个方法都可以看成一个事务,因为通常Service的每个方法对应着一个用例。(在这个例子中我使用了facade作为事务边界,后面我要讲这个是多余的)
其缺点为也是很明显的:
所有的业务都在service中处理,当业越来越复杂时,service会变得越来越庞大,最终难以理解和维护。
将所有的业务放在无状态的service中实际上是一个过程化的设计,它在组织复杂的业务存在天然的劣势,随着业务的复杂,业务会在service中多个方法间重复。
当添加一个新的UI时,很多业务逻辑得重新写。例如,当要提供Web Service的接口时,原先为Web界面提供的service就很难重用,导致重复的业务逻辑(在贫血模型的分层图中可以看得更清楚),如何保持业务逻辑一致是很大的挑战。
接下来看看领域驱动模型,与贫血模型相反,领域模型要承担关键业务逻辑,业务逻辑在多个领域对象之间分配,而Service只是完成一些不适合放在模型中的业务逻辑,它是非常薄的一层,它指挥多个模型对象来完成业务功能。
领域模型的实现一般包含如下包:
infrastructure: 代表基础设施层,一般负责对象的持久化。
domain:代表领域层。domain包中包括两个子包,分别是model和service。model中包含模型对
象,Repository(DAO)接口。它负责关键业务逻辑。service包为一系列的领域服务,之所以需要service,按照DDD的观点,是因为领域中的某些概念本质是一些行为,并且不便放入某个模型对象中。比如转帐操作,它是一个行为,并且它涉及三个对
象,fromAccount,toAccount和TransferTransaction,将它放入任一个对象中都不好。
application: 代表应用层,它的主要提供对UI层的统一访问接口,并作为事务界限。
现在来看实现,照例先看model中的对象:
String accountId;
OverdraftPolicy overdraftPolicy = NoOverdraftPolicy.INSTANCE;
Account() {}
Account(String accountId, BigDecimal balance) {
Validate.notEmpty(accountId);
Validate.isTrue(balance == null
|| balance.compareTo(BigDecimal.ZERO) &=
.accountId = accountId;
.balance = balance ==
? BigDecimal.ZERO :
String getAccountId() {
accountId;
BigDecimal getBalance() {
debit(BigDecimal amount)
AccountUnderflowException {
Validate.isTrue(amount.compareTo(BigDecimal.ZERO) & 0
(!overdraftPolicy.isAllowed(
, amount)) {
AccountUnderflowException(
, amount);
balance = balance.subtract(amount);
credit(BigDecimal amount) {
Validate.isTrue(amount.compareTo(BigDecimal.ZERO) & 0
balance = balance.add(amount);
public class Account {
private String accountId;
private BigD
private OverdraftPolicy overdraftPolicy = NoOverdraftPolicy.INSTANCE;
public Account() {}
public Account(String accountId, BigDecimal balance) {
Validate.notEmpty(accountId);
Validate.isTrue(balance == null || balance.compareTo(BigDecimal.ZERO) &= 0);
this.accountId = accountId;
this.balance = balance == null ? BigDecimal.ZERO :
public String getAccountId() {
return accountId;
public BigDecimal getBalance() {
public void debit(BigDecimal amount) throws AccountUnderflowException {
Validate.isTrue(amount.compareTo(BigDecimal.ZERO) & 0);
if (!overdraftPolicy.isAllowed(this, amount)) {
throw new AccountUnderflowException(this, amount);
balance = balance.subtract(amount);
public void credit(BigDecimal amount) {
Validate.isTrue(amount.compareTo(BigDecimal.ZERO) & 0);
balance = balance.add(amount);
与贫血模型的区别在于Account类中包含业务方法(credit,debit),注意没有set方法,对Account的更新是通过业务方法来更新
的。由于“不允许从帐户取出大于存款余额的资金”是一条重要规则,将它放在一个单独的接口OverdraftPolicy中,也提供了灵活性,当业务规则
变化时,只需要改变这个实现就可以了。
TransferServiceImpl类:
TransferServiceImpl
implements
TransferService {
AccountRepository accountR
TransferTransactionRepository transferTransactionR
TransferServiceImpl(AccountRepository accountRepository,
TransferTransactionRepository transferTransactionRepository) {
.accountRepository = accountR
.transferTransactionRepository = transferTransactionR
TransferTransaction transfer(String fromAccountId, String toAccountId,
BigDecimal amount) throws
AccountNotExistedException, AccountUnderflowException {
Account fromAccount = accountRepository.findAccount(fromAccountId);
(fromAccount ==
AccountNotExistedException(fromAccountId);
Account toAccount = accountRepository.findAccount(toAccountId);
(toAccount ==
AccountNotExistedException(toAccountId);
fromAccount.debit(amount);
toAccount.credit(amount);
accountRepository.updateAccount(fromAccount);
accountRepository.updateAccount(toAccount);
transferTransactionRepository.create(fromAccountId, toAccountId, amount);
public class TransferServiceImpl implements TransferService {
private AccountRepository accountR
private TransferTransactionRepository transferTransactionR
public TransferServiceImpl(AccountRepository accountRepository,
TransferTransactionRepository transferTransactionRepository) {
this.accountRepository = accountR
this.transferTransactionRepository = transferTransactionR
public TransferTransaction transfer(String fromAccountId, String toAccountId,
BigDecimal amount) throws AccountNotExistedException, AccountUnderflowException {
Account fromAccount = accountRepository.findAccount(fromAccountId);
if (fromAccount == null) throw new AccountNotExistedException(fromAccountId);
Account toAccount = accountRepository.findAccount(toAccountId);
if (toAccount == null) throw new AccountNotExistedException(toAccountId);
fromAccount.debit(amount);
toAccount.credit(amount);
accountRepository.updateAccount(fromAccount); // 对Hibernate来说这不是必须的
accountRepository.updateAccount(toAccount);
// 对Hibernate来说这不是必须的
return transferTransactionRepository.create(fromAccountId, toAccountId, amount);
与贫血模型中的TransferServiceImpl相比,最主要的改变在于业务逻辑被移走了,由Account类来实现。对于这样一个简单的例子,领域模型没有太多优势,但是仍然可以看到代码的实现要简单一些。当业务变得复杂之后,领域模型的优势就体现出来了。
其优点是:
领域模型采用OO设计,通过将职责分配到相应的模型对象或Service,可以很好的组织业务逻辑,当业务变得复杂时,领域模型显出巨大的优势。
当需要多个UI接口时,领域模型可以重用,并且业务逻辑只在领域层中出现,这使得很容易对多个UI接口保持业务逻辑的一致(从领域模型的分层图可以看得更清楚)。
其缺点是:
对程序员的要求较高,初学者对这种将职责分配到多个协作对象中的方式感到极不适应。
领域驱动建模要求对领域模型完整而透彻的了解,只给出一个用例的实现步骤是无法得到领域模型的,这需要和领域专家的充分讨论。错误的领域模型对项目的危害非常之大,而实现一个好的领域模型非常困难。
对于简单的软件,使用领域模型,显得有些杀鸡用牛刀了。
这部分我将提出一些可能存在争议的问题并提出自己的看法。
理解软件分层、明晰每层的职责对于理解领域模型以及代码实现是有好处的。软件一般分为四层,分别为表示层,应用层,领域层和基础设施层。软件领域中另外一个著名的分层是TCP/IP分层,分为应用层,运输层,网际层和网络接口层。我发现它们之间存在对应关系,见下表:
TCP/IP分层
负责向用户显示信息。
负责处理特定的应用程序细节。如FTP,SMTP等协议。
定义软件可以完成的工作,指挥领域层的对象来解决问题。它不负责业务逻辑,是很薄的一层。
两台主机上的应用程序提供端到端的通信。主要包括TCP,UDP协议。
负责业务逻辑,是业务软件的核心。
处理分组在网络中的活动,例如分组的选路。主要包括IP协议。
网络接口层
操作系统中的设备驱动程序和计算机中对应的网络接口卡。它们一起处理与电缆(或其他任何传输媒介)的物理接口细节。
基础设施层
为上层提供通用技术能力,如消息发送,数据持久化等。
对于TCP/IP来说,运输层和网际层是最核心的,这也是TCP/IP名字的由来,就像领域层也是软件最核心的一层。可以看出领域模型的包结构与软
件分层是一致的。在软件分层中,表示层、领域层和基础设施层都容易理解,难理解的是应用层,很容易和领域层中Service混淆。领域Service属于
领域层,它需要承担部分业务概念,并且这个业务概念不易放入模型对象中。应用层服务不承担任何业务逻辑和业务概念,它只是调用领域层中的对象(服务和模
型)来完成自己的功能。应用层为表示层提供接口,当UI接口改变一般也会导致应用层接口改变,也可能当UI接口很相似时应用层接口不用改变,但是领域层
(包括领域服务)不能变动。例如一个应用同时提供Web接口和Web Service接口时,两者的应用层接口一般不同,这是因为Web
Service的接口一般要粗一些。可以和TCP/IP的层模型进行类比,开发一个FTP程序和MSN聊天程序,它们的应用层不同,但是可以同样利用
TCP/IP协议,TCP/IP协议不用变。与软件分层不同的是,当同样开发一个FTP程序时,如果只是UI接口不同,一个是命令行程序,一个是图形界
面,应用层不用变(利用的都是FTP服务)。下图给出领域模型中的分层:
Repository接口属于领域层
可能有人会将Repository接口,相当于贫血模型中的DAO接口,归于基础设施层,毕竟在贫血模型中DAO是和它的实现放在一起。这就涉及
Repository
接口到底和谁比较密切?应该和domain层比较密切,因为Repository接口是由domain层来定义的。用TCP/IP来类比,网际层支持标准
以太网、令牌环等网络接口,支持接口是在网际层中定义的,没有在网际层定义的网络接口是不能被网际层访问的。那么为什么在贫血模型中DAO的接口没有放在
model包中,这是因为贫血模型中DAO的接口是由service来定义的,但是为什么DAO接口也没有放在service包中,我无法解释,按照我的
观点DAO接口放在service包中要更好一些,将DAO接口放在dao包或许有名称上对应的考虑。对于领域模型,将Repository接口放入
infrastructure包中会引入包的循环依赖,Repository依赖Domain,Domain依赖Repository。然而对于贫血模
型,将DAO接口放入dao包中则不会引入包循环依赖,只有service对DAO和model的依赖,而没有反方向的依赖,这也导致service包很
不稳定,service又正是放置业务逻辑的地方。JDepend这个工具可以检测包的依赖关系。
贫血模型中Facade有何用?
我以前的做一个项目使用的就是贫血模型,使用了service和facade,当我们讨论service和facade有什么区别时,很少有人清
楚,最终结果facade就是一个空壳,它除了将方法实现委托给相应的service方法,不做任何事,它们的接口中的方法都一样。Facade应该是主
要充当远程访问的门面,这在EJB时代相当普遍,自从Rod Johson叫嚷without
EJB之后,大家对EJB的热情降了很多,对许多使用贫血模型的应用程序来说,facade是没有必要的。贫血模型中的service在本质上属于应用层
的东西。当然如果确实需要提供远程访问,那么远程Facade(或许叫做Remote
Service更好)也是很有用的,但是它仍然属于应用层,只不过在技术层面上将它的实现委托给对应的Service。下图是贫血模型的分层:
从上面的分层可以看出贫血模型实际上相当于取消掉了领域层,因为领域层并没有包含业务逻辑。
DAO到底有没有必要?
贫血模型中的DAO或领域模型中的Repository到底有没有必要?有人认为DAO或者说Repository是充血模型的大敌,对此我无论如
何也不赞同。DAO或Repository是负责持久化逻辑的,如果取消掉DAO或Repository,将持久化逻辑直接写入到model对象中,势必
造成model对象承担不必要的职责。虽然现在的ORM框架已经做得很好了,持久化逻辑还是需要大量的代码,持久化逻辑的掺入会使model中的业务逻辑
变得模糊。允许去掉DAO的一个必要条件就是Java的的持久化框架必须足够先进,持久化逻辑的引入不会干扰业务逻辑,我认为这在很长一段时间内将无法做
到。在rails中能够将DAO去掉的原因就是rail中实现持久化逻辑的代码很简洁直观,这也与ruby的表达能力强有关系。DAO的另外一个好处隔离
数据库,这可以支持多个数据库,甚至可以支持文件存储。基于DAO的这些优点,我认为,即使将来Java的持久化框架做得足够优秀,使用DAO将持久化逻
辑从业务逻辑中分离开来还是十分必要的,况且它们本身就应该分离。
在这篇文章里,我使用了一个转帐例子来描述领域模型和贫血模型的不同,实现代码可以从附件中下载,我推荐你看下附件代码,这会对领域模型和贫血模型
有个更清楚的认识。我谈到了软件的分层,以及贫血模型和领域模型的实现又是怎样对应到这些层上去的,最后是对DAO(或Repository)的讨论。以
上只是我个人观点,如有不同意见欢迎指出。
争论的焦点到了DAO上啊,呵呵。确实,实践中很多项目最终实施DDD的结果就是把所有的DAO重命名为Repository。但是我认为DAO和Repository很像,但是不是一个东西,因为它们出发点不同。
为什么要有DAO?
因为之前,很早之前,我们对于框架中立性还很受用。DAO给了我们可以随时把Hibernate换成ibatis的幻觉,所以我们要有一个地方隔离了框架。
而且DAO集中了所有的查询,方便了性能调优人员。同时也鼓励了查询的重用,同样方便了调优。
为什么要有Repository?
在我看来,与其说PublicationRepository,不如说Publications。Repository是一个集合对象,它封装了集合的逻辑。因为它具有封装性,所以它应该负责保持这个集合的状态,比如拒绝一些非法的的修改
PublicationRepository {
save(Publication pub) {
(hasSameName(pub)) {
InvalidPublicationException();
dao.save(pub);
class PublicationRepository {
public void save(Publication pub) {
if (hasSameName(pub)) {
throw new InvalidPublicationException();
dao.save(pub);
另外,Repository只应该负责Aggregate Root。对于被Aggregate的对象,应该用Navigation,也就是在关系之间游走来获取。所以不是所有的查询都必须由Repository来完成,比如说:
List&ContactNote& contactNotes =
ArrayList&ContactNote&();
contactedBy(User accountManager, DateTime time){
ContactNote contactNote = new
ContactNote(
, accountManager, time);
(isDuplicated(contactNote)) {
InvalidContactNote();
contactNotes.add(contactNote);
isDuplicated(ContactNote contactNote) {
class Contact {
private List&ContactNote& contactNotes = new ArrayList&ContactNote&();
public void contactedBy(User accountManager, DateTime time){
ContactNote contactNote = new ContactNote(this, accountManager, time);
if (isDuplicated(contactNote)) {
throw new InvalidContactNote();
contactNotes.add(contactNote);
private boolean isDuplicated(ContactNote contactNote) {
// 查询contactNotes
现状是,对象之间的关联不可查询导致了,很多这样的查询必须通过xxxDao,xxxRepository来完成。其实它们都不应该插手。
理想情况下,只有业务开始的时候用repository加载对象,在结束的时候用repository把对象存储回去,中间都是领域对象在互相作
用。而DAO,可以以Generic Query Builder的形式存在,不过和它之前被发明出来的意图已经不是一个东西了。
DAO原本的作用就是隔离数据库的影响,没有业务逻辑。而Repository更抽象,从概念上来说是一个可以全局访问的集合,从这个意义上来讲对你所举
PublicationRepository,使用add(Publication
pub)作为方法签名要更好一些。Repository也负责保持完整对象的完整性,PublicationRepository的例子也说明了这一点,
另外一个例子,但从数据库重建一个对象时,由于外部原因,对象已经变得不完整,将它恢复为一个完整的对象或者直接抛异常也是Repostory的责任,它
可以将这种保证对象完整性的责任委托给别的对象(如Factory)。将Repository和DAO联合起来用应该很有用,谢谢你的提醒!
List&ContactNote& contactNotes =
ArrayList&ContactNote&();
contactedBy(User accountManager, DateTime time){
ContactNote contactNote = new
ContactNote(
, accountManager, time);
(isDuplicated(contactNote)) {
InvalidContactNote();
contactNotes.add(contactNote);
isDuplicated(ContactNote contactNote) {
相信很多人跟我一样,一开始在使用贫血模式的三层结构:抽象出来一个贫血的实体封装,然后把对模型的所有操作,分离出来,分离到BLL层去,然后DALL层负责把这些操作和数据库产生映射,负责读写删改的操作。
...
难过了,不要告诉别人,别人永远都不可能明白在你的立场上的感受。难过了,静静的蹲下来抱着自己,让眼泪尽情的洒落。难过了,拿着镜子看看此刻的自己,让真实浮现眼前。...
  领域模型是对领域内的概念类或现实世界中对象的可视化表示。又称概念模型、领域对象模型、分析对象模型。它专注于分析问题领域本身,发掘重要的业务领域概念,并建立业务领...
一、领域模型
领域模型是领域内的概念类或现实世界中对象的可视化表示,又称为概念模型或分析对象模型,它专注于分析问题领域本身,发掘重要的业务领域概念,并建立业务领域概念之间的关系。
贫血vs富血
我们来回顾一下。在企业架构模式中,业务层的实现一般有两种模式:一种是事务角本模式(Transaction
script),另一种是领域模型模式(Domain Model)。这...
转自: http://www.uml.org.cn/mxdx/.asp
在当前的开发者社区,广泛流行一种被Martin Fowler称为贫血领域模型的构架模式。该模式由...
之前分享过DDD,到底与微服务的关系如何?很多人还是觉得很虚幻,DDD那么复杂的理论,聚合根、值对象、事件溯源,到底我们该怎么入手呢?
实际上DDD和面向对象设计、设计模式等等理论有千丝万缕的联系,如...
业务对象是指那些从实际业务场景中抽象出来的对象,这些对象在代码中对应的就是一些业务对象类。
在常见的SSH框架的开发中,一般的做法是将每一个业务对象对应一个POLO,当然这是为了方便使用ORM框架。...
为了补大家的遗憾,在此总结下ROBBIN的领域模型的一些观点和大家的补充,在网站和演讲中,robbin将领域模型初步分为4大类:
1,失血模型
2,贫血模型
3,充血模型
4,胀血模型
没有更多推荐了,

我要回帖

更多关于 贫血分几种类型 的文章

 

随机推荐