我对框架设计有一些一般性问题。
我正在为C#.NET(框架3.5)中的iPhone应用程序构建API,& SQL 2008(使用LINQ)。我遵循了Domain-Driven-Design模式(在一本书中)和 具有以下文件夹结构:
Core
- DataAccess
--Impl
-Domain
-Impl
Core是我的核心API库 - 我的DLL。 DataAccess包含数据访问接口 DataAccess.Impl包含存储库(DBQ的LINQ) 域包含我的大多数数据类型和属性。 Impl包含我的服务(即AccountService.cs,EmailService.cs)
现在,作为练习,我已经为此项目添加了Windows服务 并尝试从此服务中的DLL调用功能。 我的问题是,我应该向其他应用程序公开哪一层 什么应该隐藏?
当我开始阅读关于DDD时,我假设存储库是 隐藏和服务类访问,但我发现我需要打电话 来自我的客户端的功能。我设计错了吗?
我的另一个问题是命名空间命名。当Windows服务 从我的核心库调用功能,我必须做我的包括:
using Company.Product.ProductCore.Core.DataAccess.Impl
using Company.Product.ProductCore.Core.Domain
using Company.Product.ProductCore.Core.Impl
这似乎很罗嗦。看看微软的DLL,它们似乎与两层保持一致 约定 - (System.Linq,System.Text等)。拥有Company.Product.ProductCore.Core.Impl 看起来很乱,并没有真正告诉程序员这个命名空间做了什么(但它 是我读过的例子所建议的)。这里有最好的做法吗?
您的建议(和任何示例)都非常感谢。
感谢。
答案 0 :(得分:7)
在我看来,域名绝对不是您所需要的,也不是您的数据访问层。
根据我的拙见,如果我们考虑外观设计模式,暴露你的库子系统的特性和功能,那么必须暴露的内容还不存在,即静态类。 >
Façade设计模式解释:
所以最后,你的代码应该做什么?只要揭示您应该知道的必要内容,因为您是唯一了解您正在开发的系统的人。
简而言之,我经常使用Façade模式,这样我就可以在幕墙的引擎下隔离我的类,实现和几个相关的子系统。让我们考虑一下我们是一个全新的汽车经销商。这个外观将是伟大的窗户,让您看到在展示厅暴露的汽车。你必须想到这个外观所暴露的东西。它只暴露汽车吗?
在我看来,这个外观暴露了你可以购买的汽车,借钱购买,修理汽车,购买其他相关配件等等。然后配件被曝光,但只有什么需要。与汽车等其他项目相同。也就是说,您可能只希望公开一个接口,并为自己保留实现,这样当您需要返回ICar
或IAccessory
时,必须通过façade实例化它们。你的实现对象类,然后通过你的façade返回接口实例。也就是说,用户不需要知道引擎盖下发生了什么,但只有当他想要一辆车时,他必须通过你的外墙订购它。就像你不会去梅赛德斯奔驰购买马自达3。你会使用正确的外观。然后,不同的汽车经销商可能只是子系统,因此是某种工厂。然后你向外墙询问有这个和那个规格的汽车,并且外观应该知道返回什么ICar
实例以换取你要求它提供给你的东西。
希望无论如何都有帮助! =)
答案 1 :(得分:7)
如果我没弄错的话,你会问两个问题:
我的答案相当冗长 - 我冒昧地把它分成两个小圆。
这是第二个问题的答案:
<强> 2。那些长命名空间名称
怎么样?我认为长名称空间名称不一定是混乱的。 恕我直言,你的名字看起来很乱:
第一个改进可能是:
// The Domain objects go here;
MyCompany.MyProduct.Core.Domain;
// DataAccess interfaces go here:
MyCompany.MyProduct.Core.DataAccess;
// a Linq implementation of the DataAcces interfaces go here:
MyCompany.MyProduct.Core.DataAccess.LinqImpl;
// The Core service go here:
MyCompany.MyProduct.Core.Services;
// Some general purpose infrastructure goes here (e.g. emailing code)
Mycompany.MyProduct.Infra;
此外,我发现在代码结构中使用商业产品名称(例如MyProduct)是不好的(如果营销选择不同的名称会怎么样?);我喜欢使用逻辑子系统的名称。
让我们假设您的建筑汽车租赁系统。然后CarRental
将被视为此应用的核心功能。然后我将使用以下命名空间结构(Serra是我公司的名称):
// For classes Customer, Account, Car
Serra.CarRental.Domain;
// I use Dao as a general abbreviation for "Data Access Objects"
// Dao interfaces go here:
Serra.CarRental.Dao;
// Linq implementation for Dao interfaces
Serra.CarRental.Dao.Linq;
// For Services specific to the car rental domain:
// AccountService and RentalService and CarAvailabilityService
Serra.CarRental.Services;
// For UI objects (not relevant in you situation?)
Serra.CarRental.UI;
// general service code; ignorant of the CarRental domain (e.g. an EmailService)
Serra.Infra.Service;
答案 2 :(得分:0)
我怀疑您的应用程序的用户会看到这个。 首先,您需要的是功能。这就是你最后会卖的东西。
您还需要尽可能降低维护费用。以下是您的代码组织方式。 第二件事 - 尽量减少维护费用。
因此,要决定如何组织解决方案,您应该回答一些问题:
这是你的目标。但不是你要找的规则。 如果新开发人员理解它们,您可以选择任何名称。
可能(作为一种启发式方法,如果你使用像Resharper或Refactor!Pro这样的重构工具),你可以从单个程序集和单个名称空间开始。在开发过程中,您将看到如何更改项目结构以更好地满足您的需求。然后重构它。
在38:18-39:45(约1.5分钟)观看talk。如何回答一些问题有很好的做法。