- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
首先,这似乎是一个很长的问题。我不认为它是......代码只是我目前正在做的事情的概述。感觉不对,所以我正在寻找建设性的批评和警告,以寻求对我可以做什么的陷阱和建议。
我有一个包含业务对象的数据库。
我需要访问父对象的属性。
我需要通过业务对象维护某种状态。
如果您查看类,我认为访问修饰符不正确。我认为它的结构不是很好。大多数关系都是用公共(public)属性建模的。 SubAccount.Account.User.ID <-- 所有这些都是公开的..
有没有比这更好的方法来模拟类之间的关系,使其不那么“公开”?
这个问题的另一部分是关于资源的:
如果我要创建一个返回 List 的 User.GetUserList() 函数,并且我有 9000 个用户,当我调用 GetUsers 方法时,它将创建 9000 个用户对象,并在其中创建 9000 个新的 AccountCollection 对象。我该怎么做才能使这个项目不那么耗费资源?
请找到下面的代码并将其撕成碎片。
public class User {
public string ID {get;set;}
public string FirstName {get; set;}
public string LastName {get; set;}
public string PhoneNo {get; set;}
public AccountCollection accounts {get; set;}
public User {
accounts = new AccountCollection(this);
}
public static List<Users> GetUsers() {
return Data.GetUsers();
}
}
public AccountCollection : IEnumerable<Account> {
private User user;
public AccountCollection(User user) {
this.user = user;
}
public IEnumerable<Account> GetEnumerator() {
return Data.GetAccounts(user);
}
}
public class Account {
public User User {get; set;} //This is public so that the subaccount can access its Account's User's ID
public int ID;
public string Name;
public Account(User user) {
this.user = user;
}
}
public SubAccountCollection : IEnumerable<SubAccount> {
public Account account {get; set;}
public SubAccountCollection(Account account) {
this.account = account;
}
public IEnumerable<SubAccount> GetEnumerator() {
return Data.GetSubAccounts(account);
}
}
public class SubAccount {
public Account account {get; set;} //this is public so that my Data class can access the account, to get the account's user's ID.
public SubAccount(Account account) {
this.account = account;
}
public Report GenerateReport() {
Data.GetReport(this);
}
}
public static class Data {
public static List<Account> GetSubAccounts(Account account) {
using (var dc = new databaseDataContext()) {
List<SubAccount> query = (from a in dc.Accounts
where a.UserID == account.User.ID //this is getting the account's user's ID
select new SubAccount(account) {
ID = a.ID,
Name = a.Name,
}).ToList();
}
}
public static List<Account> GetAccounts(User user) {
using (var dc = new databaseDataContext()) {
List<Account> query = (from a in dc.Accounts
where a.UserID == User.ID //this is getting the user's ID
select new Account(user) {
ID = a.ID,
Name = a.Name,
}).ToList();
}
}
public static Report GetReport(SubAccount subAccount) {
Report report = new Report();
//database access code here
//need to get the user id of the subaccount's account for data querying.
//i've got the subaccount, but how should i get the user id.
//i would imagine something like this:
int accountID = subAccount.Account.User.ID;
//but this would require the subaccount's Account property to be public.
//i do not want this to be accessible from my other project (UI).
//reading up on internal seems to do the trick, but within my code it still feels
//public. I could restrict the property to read, and only private set.
return report;
}
public static List<User> GetUsers() {
using (var dc = new databaseDataContext()) {
var query = (from u in dc.Users
select new User {
ID = u.ID,
FirstName = u.FirstName,
LastName = u.LastName,
PhoneNo = u.PhoneNo
}).ToList();
return query;
}
}
}
最佳答案
这个答案最终包含了很多流行词标题。希望我解释每一个以及为什么它适用于此。我认为我在下面介绍的每个概念都值得考虑 - 它们并不总是适用,但我发现它们都是我个人认为在考虑系统结构时有值(value)的东西。
首先考虑每个对象的责任 - 它的工作是什么?通常,一旦您为每个类(class)决定了一项工作,您就会找到更好的设计。目前,您的许多类都做得太多,持有本应作为服务真正存在的逻辑。
上面的第一个例子是你的用户类:
public class User {
public string ID {get;set;}
public string FirstName {get; set;}
public string LastName {get; set;}
public string PhoneNo {get; set;}
public AccountCollection accounts {get; set;}
public User {
accounts = new AccountCollection(this);
}
public static List<Users> GetUsers() {
return Data.GetUsers();
}
}
为什么要提供从数据源中获取用户的方法呢?该功能应该移出到用户服务中。
另一个关键示例是 SubAccount 上的 GenerateReport 方法 - 不要让您的报告生成逻辑与 SubAccount 对象紧密相关。将其拆分出来将为您提供更大的灵 active ,并减少对您的 SubAccount 的更改更改会破坏报告逻辑。
再次查看您的用户类 - 为什么它在实例化时加载所有用户帐户?每次与用户合作时,是否总是要使用这些对象?
引入延迟加载通常会更好 - 只在需要时检索帐户。当然,有时您需要预先加载(如果您知道很快就会需要该对象,所以不想减少数据库访问),但您应该能够针对这些异常进行设计。
这种从惰性加载点和单一职责点开始的后续。您有很多对数据类等内容的硬编码引用。这使您的设计更加严格 - 重构您的数据访问以引入延迟加载,或者更改用户记录的检索方式变得更加困难,因为许多类都直接访问数据访问逻辑。
向 Cade Roux 致敬 - 我从未听说过 Digest 对象这个词,通常称它们为轻量级 DTO。
正如 Cade 所说,如果您所做的只是显示绑定(bind)到唯一 ID 的用户名组合框,则没有理由检索包含功能齐全的用户对象的丰富列表。
引入一个只存储最基本用户信息的轻量级用户对象。
这又是引入服务/存储库抽象和某种依赖注入(inject)的另一个原因。当您将数据检索与实际对象封装在一起,并且您没有紧密绑定(bind)到数据访问实现时,更改从数据存储检索的对象类型会变得容易得多。
您的对象对彼此的内部结构了解得太多了。允许通过用户向下钻取到帐户,然后再向下钻取到子帐户混淆了每个对象的责任。您可以在不应该的情况下从用户对象设置子帐户信息。
我一直在为这个原则而苦恼,因为钻取层次结构似乎很方便。问题是它会阻止你深入思考每个对象的封装和作用。
也许不要向用户公开您的 Account 对象 - 而是尝试引入公开 Account 对象相关成员的属性和方法。查看 GetAccount 方法而不是帐户属性,这样您就可以强制自己使用帐户对象而不是将其视为用户的属性。
关于c# - 业务对象之间过度可访问且极度耗费资源的关系。我怎样才能解决这个问题?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2564767/
关闭。这个问题是opinion-based 。目前不接受答案。 想要改进这个问题吗?更新问题,以便 editing this post 可以用事实和引文来回答它。 . 已关闭 4 年前。 Improv
PowerShell Web Access 允许您通过 Web 浏览器运行 PowerShell cmdlet。它显示了一个基于 Web 的控制台窗口。 有没有办法运行 cmdlet 而无需在控制台窗
我尝试在无需用户登录的情况下访问 Sharepoint 文件。 我可以通过以下任一方式获取访问 token 方法一: var client = new RestClient("https://logi
我目前正在尝试通过 Chrome 扩展程序访问 Google 服务。我的理解是,对于 JS 应用程序,Google 首选的身份验证机制是 OAuth。我的应用目前已成功通过 OAuth 向服务进行身份
假设我有纯抽象类 IHandler 和派生自它的类: class IHandler { public: virtual int process_input(char input) = 0; };
我有一个带有 ThymeLeaf 和 Dojo 的 Spring 应用程序,这给我带来了问题。当我从我的 HTML 文件中引用 CSS 文件时,它们在 Firebug 中显示为中止。但是,当我通过在地
这个问题已经有答案了: JavaScript property access: dot notation vs. brackets? (17 个回答) 已关闭 6 年前。 为什么这不起作用? func
我想将所有流量重定向到 https,只有 robot.txt 应该可以通过 http 访问。 是否可以为 robot.txt 文件创建异常(exception)? 我的 .htaccess 文件: R
我遇到了 LinkedIn OAuth2: "Unable to verify access token" 中描述的相同问题;但是,那里描述的解决方案并不能解决我的问题。 我能够成功请求访问 toke
问题 我有一个暴露给 *:8080 的 Docker 服务容器. 我无法通过 localhost:8080 访问容器. Chrome /curl无限期挂断。 但是如果我使用任何其他本地IP,我就可以访
我正在使用 Google 的 Oauth 2.0 来获取用户的 access_token,但我不知道如何将它与 imaplib 一起使用来访问收件箱。 最佳答案 下面是带有 oauth 2.0 的 I
我正在做 docker 入门指南:https://docs.docker.com/get-started/part3/#recap-and-cheat-sheet-optional docker-co
我正在尝试使用静态 IP 在 AKS 上创建一个 Web 应用程序,自然找到了一个带有 Nginx ingress controller in Azure's documentation 的解决方案。
这是我在名为 foo.js 的文件中的代码。 console.log('module.exports:', module.exports) console.log('module.id:', modu
我试图理解访问键。我读过https://docs.aws.amazon.com/general/latest/gr/aws-sec-cred-types.html#access-keys-and-se
我正在使用 MGTwitterEngine"将 twitter 集成到我的应用程序中。它在 iOS 4.2 上运行良好。当我尝试从任何 iOS 5 设备访问 twitter 时,我遇到了身份验证 to
我试图理解访问键。我读过https://docs.aws.amazon.com/general/latest/gr/aws-sec-cred-types.html#access-keys-and-se
我正在使用以下 API 列出我的 Facebook 好友。 https://graph.facebook.com/me/friends?access_token= ??? 我想知道访问 token 过
401 Unauthorized - Show headers - { "error": { "errors": [ { "domain": "global", "reas
我已经将我的 django 应用程序部署到 heroku 并使用 Amazon s3 存储桶存储静态文件,我发现从 s3 存储桶到 heroku 获取数据没有问题。但是,当我测试查看内容存储位置时,除
我是一名优秀的程序员,十分优秀!