需要有关OOP理念的建议

我正试图在C#中开启一个大型项目。 我之前的经验是在Delphi中,默认情况下,每个表单都是在应用程序启动时创建的,并且表示在(gasp)全局变量中保存的引用。 因此,我正在努力使我的思维适应100%面向对象的环境,而我的头脑正在旋转一点点。

我的应用程序将有大量的类集合这些类中的大多数只需要一个实例。 所以我在想:静态类。 我不太确定为什么,但我在这里读到的大部分内容都表明,如果我的class级要持有一个状态,我将其视为任何属性值,我应该使用单例结构。 好的。 但是有些人因为逃避我的理由而认为单身人士也是邪恶的。

除了这个程序之外,这些类都没有被用在任何地方的危险。 所以它们当然可以作为常规对象(与单例或静态类)一起工作

然后是对象之间的交互问题。 我很想创建一个充满公共静态属性的Global类,引用许多这些类的单个实例。 我还考虑过制作MainForm的属性(静态或实例,不确定哪个)。 然后我会让每个class级都知道MainForm作为所有者。 然后各种对象可以作为所有者互相引用。 对象1 ,所有者。 对象2

我担心我的电子墨水耗尽了,或者至少让任何一个人的耐心都受到了这么长时间的困扰。 我希望我已经清楚地解释了我完全混乱的状态。 我只是在寻找一些关于我的最佳实践的建议。 所有输入都受到欢迎和赞赏。

在此先感谢David Jennings

你可以尝试一下,看看它是怎么回事。 考虑使用NUnit进行开发; 如果你这样做,你会发现你的代码将保持足够的灵活性,使得架构改变不会太难。

我的偏好是避免使用静态类和静态数据,但有时它只对短期问题有意义。 在那,我的建议是考虑实际拥有各种forms的东西。 通常情况下,似乎人们想要将主要forms作为“主要应用程序”,但也许实际上有更好的所有者。

无论如何 – 除了谈论和思考可能是什么之外,我建议你继续尝试一些选择并看看他们做了什么。 写完后不要害怕更改软件!

从程序或其他非OOP语言开始并想“每个XYZ一个巨大的静态类”是很正常的,这通常意味着你并没有真正考虑过被表示的OBJECTS,因为一个类应该代表OBJECTS被操纵。

因此,您需要退后一步,查看DATA和DATA代表的内容。 你可能会说,“好吧,它是DATA!它代表了NUMBERS!”,但你必须抽象出数据代表的含义。 数据表示的“事物”是对象。 您对“事物”所代表的数据执行的操作将成为您的方法。

静态类和单例有着相同的缺点:

  • 与许多其他课程紧密相连
  • 隐藏依赖项(很难说出其他类使用它们)
  • 测试困难
  • 基本上是全球数据
  • 对于单身人士,多重责任(无论他们做什么+终身管理)

许多(并非所有!)情况下的解决方案是dependency injection (DI),基于依赖性倒置原则 (@CodeToGlory提到的SOLID原则之一)。 这可以手动完成,也可以使用DI Container框架完成 。

Mark Seemann有一本关于.NET中的dependency injection的优秀书籍; 我强烈推荐。

单身人士通常是我们通常在设计中看到的许多问题的根源。 但是我考虑创建单例和全局变量作为一种手段,将它作为代码气味传递给应用程序。

我觉得让自己获得SOLID原则的入门书会很好。 关于这个主题还有几个关于你应该观察和理解的视角。

我推荐的另一本实用书是Kent Beck的Implementation Patterns。 理解OOP是一回事,在现实世界中实现是另一回事。

查看Windows Presentation Foundation,这是用于构建Windows客户端应用程序的下一代演示系统。

我想我用足够的信息轰炸了你,但是放轻松,一步一步走。 我觉得你应该在这里跟踪几首曲目,以达到你想要的目的。 微软提供了一些原型 ,您可以从中学习,然后使用OOP进行即兴创作。

关于此的一些随机想法可能有用也可能没用:

  • 从数据开始而不是程序结构。 分析数据并找出您在概念上试图表达的内容,然后将其客观化。

  • 我的经验是,使用prodedural代码,你在想“我现在在做什么?” 但是有了OO代码,你会想“有一天我想做什么?”

  • 始终至少有一个主对象,即使这是Application对象本身。 即使它很诱人,也不要在这个物体上放太多。 您在概念上相关的对象中表示的数据,状态和行为越多,应用程序就越容易为新开发人员学习和维护。

  • 做一个原型。 构建您知道将丢弃的应用程序的缩小版本,然后当您到某一点检查您的代码时,确定哪些对象运行良好,哪些对象没有,然后重新开始。

至于整个单身人士的事情 – 而且不想挑衅 – 忽视反对者。 有时候Singleton设计模式非常有用,就像EAV数据模型完美无缺,MVC是世界上最糟糕的事情一样。 如果需要拧入螺丝,请使用螺丝刀。

在阅读你的解释时,我认为如果你有许多你认为应该是静态或单身的课程,你可能仍在考虑使用Delphi类型的范例。 我不知道我是否遇到过只有大多数物体之一的项目。 所以我的倾向是你的物体分解可能有缺陷。

真的,你应该开始考虑你在你的程序中代表什么。 问问自己,如果你有很多只有一个实例的对象,为什么只有一个实例呢? 是因为您以奇怪的方式保存数据,就像拥有索引匹配的多个数组一样。

这就是说C#确实有一些很好的单例内置语义,因为你不必在实例方法中进行空值检查

public class SingletonClass{ private static SingletonClass _instance; private SingletonClass(){} public static Instance { get { if(_instance == null){ _instance = new SingletonClass(); } } } } 

在C#中可以写成:

 public class SingletonClass{ private static SingletonClass _instance = new SingletonClass(); private SingletonClass(){} public static Instance { get { return _instance; } } } 

因此,如果您坚持使用该模式,我建议您倾向于使用Singletons。 单身人士,就像一切都有时间和地点一样,我不会写一个完整的应用程序,其中大多数对象是单身人士。

我强烈建议你想一想为什么你有一个静态方法或单身的全局状态。