20121008 P60-P85

 

 

 

public class Member {
public string LoginName { get; set; } // The unique key
public int ReputationPoints { get; set; }
}
public class Item {
public int ItemID { get; private set; } // The unique key
public string Title { get; set; }
public string Description { get; set; }
public DateTime AuctionEndDate { get; set; }
public IList<Bid> Bids { get; set; }
}
public class Bid {
public Member Member { get; set; }
public DateTime DatePlaced { get; set; }
public decimal BidAmount { get; set; }


An aggregate entity groups together several domain model objects. There is aroot entitythat’s used

to identify the entire aggregate, and it acts as the “boss” for validation and persistence operations. The

aggregate is treated as a single unit with regard to data changes, so we need to create aggregates that

represent relationships that make sense in the context of the domain model, and create operations that

correspond logically to real business processes; that is, we need to create aggregates by grouping objects

that are changed as a group.

每一个聚合实体(的跟对象)只能有一个子对象,不能有多个对象,聚合的一个好处就是简化对象之间的关系

  • DDD的作用

In general, aggregates add structure and accuracy to a domain model. They make it easier to apply
validation (the root entity becomes responsible for validating the state of all objects in the aggregate) and
are obvious units for persistence. And, because aggregates are essentially the atomic units of our domain
model, they are also suitable units for transaction management and cascade deletes from databases.

Persistence is not part of our domain model. It is an
independent or orthogonal concern in our separation of concerns pattern.


This means that we don’t want
to mix the code that handles persistence with the code that defines the domain model.
The usual way to enforce separation between the domain model and the persistence system is to
define repositories.

 

 

 

  • 定义仓库
public class MembersRepository {
public void AddMember(Member member) { /* Implement me */ }
public Member FetchByLoginName(string loginName) { /* Implement me */ }
public void SubmitChanges() { /* Implement me */ }
}
public class ItemsRepository {
public void AddItem(Item item) { /* Implement me */ }
public Item FetchByID(int itemID) { /* Implement me */ }
public IList<Item> ListItems(int pageSize,int pageIndex) { /* Implement me */ }
public void SubmitChanges() { /* Implement me */ }
}


第七章还会讲到

 

 

 

  • 下面是松耦合组件的介绍

In our ideal situation, each component knows nothing about any other component and deals with
other areas of the application only through abstract interfaces. This is known as loose coupling, and it
makes testing and modifying our application easier.

上面的方法存在的问题

public class PasswordResetHelper {
public void ResetPassword() {
IEmailSender mySender = new MyEmailSender();
...call interface methods to configure e-mail details...
mySender.SendEmail();
}
}

这样的话,把PasswoirdResetHelper和MyEmailSender联系起来了。

这样就有了相互关联。为了解决这个问题,引入下面的概念。

  • 利用依赖注入(DI)

DI的一种方法是使用构造方法,其中构造方法的参数是实现IEmailSender接口的对象。像下面的写法:

public class PasswordResetHelper {
private IEmailSender emailSender;
public PasswordResetHelper(IEmailSender emailSenderParam) {
emailSender = emailSenderParam;
}
public void ResetPassword() {
...call interface methods to configure e-mail details...
emailSender.SendEmail();
}
}

我们的类不创建上面实现接口的参数类,这个类是在实例化PasswordResetHelper时才被创建和传到PasswordResetHelper类里面。还有一种设置注入。

  • DIContainer

DI容器就是Unity.第六章还会提到。unity.codeplex.com
 

为了理解Unity,先来利用Ninject.。

单元测试和集成测试

单元测试用在算法和业务逻辑上面

集成测试可以模拟用户,然后可以检测出bug等,也称为回归测试。

Both kinds of testing can be extremely valuable in web applications. Unit tests, which are simple to
create and run, are brilliantly precise when you are working on algorithms, business logic, or other backend
infrastructure.
The value of integration testing is that it can model how a user will interact with the UI, and can
cover the entire technology stack that your application uses, including the web server and database.
Integration testing tends to be better at detecting new bugs that have arisen in old features; this is known
as regression testing.

以上是单元测试和集成测试的好处。

单元测试可以使用A/A/A,下面是例子:

[TestClass]
public class AdminControllerTest {
[TestMethod]
public void CanChangeLoginName() {
// Arrange (set up a scenario)
Member bob = new Member() { LoginName = "Bob" };
FakeMembersRepository repositoryParam = new FakeMembersRepository();
repositoryParam.Members.Add(bob);
AdminController target = new AdminController(repositoryParam);
string oldLoginParam = bob.LoginName;
string newLoginParam = "Anastasia";
// Act (attempt the operation)
target.ChangeLoginName(oldLoginParam, newLoginParam);
// Assert (verify the result)
Assert.AreEqual(newLoginParam, bob.LoginName);
Assert.IsTrue(repositoryParam.DidSubmitChanges);
}
private class FakeMembersRepository : IMembersRepository {
public List<Member> Members = new List<Member>();
public bool DidSubmitChanges = false;
public void AddMember(Member member) {
throw new NotImplementedException();
}
public Member FetchByLoginName(string loginName) {
return Members.First(m => m.LoginName == loginName);
}
public void SubmitChanges() {
DidSubmitChanges = true;
}
}
}


 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值