我正在学习 C#,并试图弄清楚什么时候使用类,什么时候不使用。
如果我正在为银行编写应用程序,我知道我会为客户使用类,其中包括他们的姓名、帐号、余额等。我会为将存款存入他们的账户、取款、更改的方法使用静态类吗?他们的地址等,因为我只需要写一次?
另外,我将使用什么来跟踪每个客户对象?拥有 2,000 名客户:
exampleName = new Customer();
在我的代码中似乎不正确。我还没到学习数据库的地步,只是在学习课程。
拥有一个数据库将是理想的,但同时您可以使用 IEnumerable 来保存您的 Customer 对象,如下所示:
List<Customer> myCustomers = new List<Customer>();
myCustomers.Add(new Customer {Name = "Bob", Address = "123 Anywhere St." });
然后你可以在需要的地方传递列表。
通常,您将在Customer
拥有帐户的类上拥有一个属性:
public class Customer
{
public Customer()
{
_accounts = new List<Account>();
}
public List<Account> Accounts
{
get { return _accounts; }
set { _accounts = value; }
}
private List<Account> _accounts;
}
等等。请注意,当您是初学者时,我会保持这种简单性并以更冗长和描述性的方式来做事。
以这种方式使用项目列表是一个很好的开始方式,因为当您开始使用数据库时,您会自然而然地使用它们;您将从数据库中检索结果集,然后将这些结果集转换为业务对象列表。
至于使用静态方法做业务逻辑,比如调整余额、更改地址等,对于现阶段的你来说无所谓。如果您使用的是 Resharper 之类的工具,它会用类似的建议来唠叨您,但在您的情况下,您可以放心地忽略那个特定的工具。您应该寻找的是尽可能保持一切自包含,避免数据泄漏和对象之间的责任泄漏 - 这只是良好的编码规则,也是防止由松散编码引起的错误的好方法。
一旦你确定了你的功能并开始工作,你可能希望将一些功能移动到静态的“帮助”样式类中。这绝对没问题,但要小心 - 辅助类很棒,如果你不遵守编码规则,一切都会很快变成反模式。
您无需使用静态类或静态方法,只需编写一次方法。这样做可能有意义,也可能没有意义,但这是编写方法而无需重复自己的一种完全有效的方式:
public class Customer
{
//properties, constructors, etc.
public virtual void Deposit(decimal amount) { }
public virtual void Withdraw(decimal amount) { }
//etc
}
这也允许您利用多态性,例如
public class BusinessCustomer : Customer
{
public override void Deposit(decimal amount) { //some other implementation }
}
当您不打算实例化对象时使用静态类。你得到了那个类的一个“实例”——你不能做这样的事情:
MyStaticClass m = new MyStaticClass();
m.SomeFunc();
当你有一个静态类时。相反,您可以通过使用类名本身来使用它。就像是:
MyStaticClass.SomeFunc();
至于您将使用什么来跟踪每个 Customer 对象?您可以使用某种集合来保存这些。诚然,在一个真实的系统中,会有某种持久性部件,可能是一个数据库,来保存数据。但是你可以做一些类似的东西:
IEnumerable<Customer> Customers = new List<Customer>();
然后将您的客户添加到该列表中
Customers.Add(new Customer() { ... });
回到关于静态方法的问题......
因此,这里的交易是您不会在静态方法中引用实例成员,因此您不会使用静态方法来更新特定客户的地址。假设您的 Customer 类看起来像:
public class Customer
{
public string Address { get; set; }
}
你不能使用像这样的静态方法
public static void SetAddress()
因为每个客户(大概)都有不同的地址。您无法访问那里的客户地址,因为它不是静态的。懂吗?相反,如果您想做一些不需要处理实例数据的事情,您将使用静态方法。我将静态方法用于实用程序功能之类的东西。
public static double ComputeSomething(double someVal) { ... }
在这里,任何人都可以调用 ComputeSomething 函数,例如:
var result = MyStaticClass.ComputeSomething(3.15);
这里的要点是静态类不用于实例化对象,而是将它们真正用作保存函数的方便容器。静态函数是可以在非静态类上但不能访问任何实例数据的函数。
使用静态函数的一个地方是单例模式。您将构造函数设置为非公开的,因此人们无法调用它,而是在类上提供一个静态方法来返回该类的唯一实例。就像是:
public class MySingleton
{
private static MySingleton instance;
private MySingleton() {}
public static MySingleton Instance
{
get
{
if (instance == null)
{
instance = new MySingleton();
}
return instance;
}
}
}
取款,存款等
那些将被称为Transactions。
这是对其他答案的补充。这是具有接口的多态性的示例。
public interface IDeposit {
void Deposit(decimal amount);
}
public interface IWithdraw {
void Withdraw(decimal amount);
}
public class Customer : IDeposit, IWithdraw {
public void Deposit(decimal amount) { throw new NotImplementedException(); }
public void Withdraw(decimal amount) { throw new NotImplementedException(); }
}
public class DepositOnlyATM : IDeposit {
public void Deposit(decimal amount) { throw new NotImplementedException(); }
}
保持概念分离,并允许实现多个接口,或者只实现一个。使用类继承方法,您只会得到一种,而您会得到全部。根据我的经验,你不可避免地会以意大利面结束,因为子类想要一些行为,但不是全部。
我建议您首先为您的银行示例写一些简单的用户故事,而不是立即进入实施细节。例如
正是在这个要求中,我们可以设想几个类(客户和帐户)。从那里只是在功能上分解客户应该做什么以及帐户应该做什么。
我发现“面向对象的思维过程”这本书是一本很好的读物,将有助于回答一些关于“我什么时候做这个和那个”的问题。
祝好运并玩得开心点!