C# 我应该在分部类中分离属性和方法吗?

C# 我应该在分部类中分离属性和方法吗?,c#,oop,C#,Oop,我正在为一个应用程序编写基础类,并希望为长期的可维护性正确地构造它们。为此,我正在研究要实现哪些设计模式、接口的使用、抽象类以及将持久性与活动分离。我的脑子里充满了模式、范例和原则 我有一个类Product,我为它创建了一个接口ipproduct。我认为我需要生成产品和抽象类,因为它的任何实例都必须是属性类别的六个值之一。那么,我的第一个问题是:以下是合适的方法吗 abstract class Product : IProduct { // Fields // Propertie

我正在为一个应用程序编写基础类,并希望为长期的可维护性正确地构造它们。为此,我正在研究要实现哪些设计模式、接口的使用、抽象类以及将持久性与活动分离。我的脑子里充满了模式、范例和原则

我有一个类
Product
,我为它创建了一个接口
ipproduct
。我认为我需要生成
产品
和抽象类,因为它的任何实例都必须是属性
类别
的六个值之一。那么,我的第一个问题是:以下是合适的方法吗

abstract class Product : IProduct
{
    // Fields
    // Properties
    // Methods
}

interface IProduct
{
    // Properties
}

public class Model : IProduct
{
    public Model()
    {
        Category = "Model";
    }

    // Model-specific fields
    // Model-specific properties
    // Model-specific methods
}
我读过的文章,包括之前在这里回答的问题,表明我应该在设计时分离属性和方法(持久性和活动)。为此,上面的代码真的应该是这样吗

abstract class Product : IProduct
{
    // Fields
    // Properties
    // Methods
}

interface IProduct
{
    // Properties
}

public partial class Model : IProduct
{
    public Model()
    {
        Category = "Model";
    }

    // Model-specific fields
    // Model-specific properties
}

public partial class Model : IProduct
{
    // Model-specific methods
}
abstract class Product : IProduct
{
    // Fields
    // Properties
}
abstract class Product : IProduct
{
    // Methods
}
当然,这假设我第一部分是对的,但也许答案会启发我该如何做事

最后,如果分离属性和方法是一件好事,并且
Product
有一些方法适用于它的所有具体版本,那么我应该将它们移动到一个单独的抽象类中吗

abstract class Product : IProduct
{
    // Fields
    // Properties
    // Methods
}

interface IProduct
{
    // Properties
}

public partial class Model : IProduct
{
    public Model()
    {
        Category = "Model";
    }

    // Model-specific fields
    // Model-specific properties
}

public partial class Model : IProduct
{
    // Model-specific methods
}
abstract class Product : IProduct
{
    // Fields
    // Properties
}
abstract class Product : IProduct
{
    // Methods
}

我在保留
partial
类时看到的唯一用途是当两个单独的系统更新这两个文件时。例如,当使用VisualStudio设计器(例如Windows窗体设计器)更新自己的类文件时,情况就是如此。对于您拥有的另一个自动生成的类,另一种情况可能是正确的。一个由系统维护,一个由您维护


我从来没有感觉到有两个独立的
部分
类文件是我自己维护的。我通常使用
#region
指令来分割方法和属性。

就我个人而言,我更喜欢结合基于语义和基于可见性的方法来对类中的成员进行排序。事实上,我不知道是谁“发明”了一条规则,根据语言实体的类型(即组中的字段、组中的属性等)对成员进行排序,这在可读性方面几乎没有任何意义

最好使用
#region
指令将它们分开。此外,我倾向于使用水平线(
-------…
)来提高代码的可读性

例如:

public class SomeClass : ParentClass, ISomeInterface
{
    #region ------ Large feature 1 ----------------------------
    … // any non-private members related to 'Large feature 1' go here
    #endregion

    #region ------ Large feature 2 ----------------------------
    … // any non-private members related to 'Large feature 2' go here
    #endregion

    #region ------ Implementation of ISomeInterface -----------
    … // ISomeInterface implementation goes here, comments are *not* repeated
    #endregion

    #region ------ ParentClass overrides ----------------------
    … // parent class members' overrides go here, comments are *not* repeated
    #endregion

    #region ------ Internals ----------------------------------
    … // any private members, i.e. the actual implementation
    #endregion
}
没有理由过度使用部分声明,除非您确实需要将它们放在单独的文件中。一个很好的理由是当类的一部分自动生成时。然而,仅为了分离成员而使用部分声明远不如一致使用区域可读性和可维护性

另外,我不喜欢分离属性声明和相应的支持字段声明(以防不能使用自动属性)。以下内容更易于维护和阅读:

public int SomeProperty
{
    get { … return someProperty; }
    set { someProperty = value; … }
}
private int someProperty;

我个人从未觉得有必要创建多个分部类来分离属性和方法。我不明白。您可以更进一步,开始在更多的部分类中分离公共接口和私有接口。我认为这只会增加一些无用的认知开销,从而使代码更难维护。只是为了了解给定函数的流程,在文件/多行之间进行有趣的跳跃。只要在类定义中保持逻辑上的分离并保持一致。“持久性和活动”-我认为这是处理它的“java方式”:拥有实体(哑数据结构)和服务(使用实体)。在C#中,我从未将它们分开——最后,如果您想调用
user.Save()
userService.Save(user),这只是个人偏好一切取决于你在追求什么。它的目标是基于用户界面的应用程序,还是“基础”,你指的是像代码库这样的框架?我不太理解上面的代码片段。您使用抽象
产品
类的目的是什么?您似乎创建了一个抽象类来实现
IProduct
所需的一些成员,然后完全忽略它,在具体的
模型
类中从头开始实现接口。由于C#没有多重继承,一旦您在具体类中从头开始实现了
ipproduct
中的所有内容,就无法将
Product
工作到继承层次结构中。您应该这样做吗?不,但这是我的意见。设计合同(接口)并实现具体版本(类)。fin最好避免使用
#region
s:@WillMarcouiller我同意在方法内部使用region,但在类中我看不出问题。@WillMarcouiller我使用region来分隔属性、方法和构造函数。我不在代码块中使用它们,只是在类级别上,它有助于导航大型代码文件,并且不像在方法中使用区域那样是一种反模式(如果它们太大,则应该将方法拆分为单独的方法)。@mason这些代码片段中的每一个只需要一个新的行分隔符。这应足以表明意图。每个人都能识别什么是字段,什么是方法,什么是属性,为什么要为它添加一些无用的代码?@WillMarcouiller不是你不能识别它。这是一个有组织的东西,它可以帮助你快速找到你想要的东西。如果您打开一个文件,并且您知道您正在寻找一个构造函数,那么能够简单地扩展构造函数区域,而不必检查所有的方法,这是很好的。如果你有很多类似的方法,你甚至可以把它们分成不同的组。这不是什么大事,但它有助于保持整洁。我不喜欢不整洁的代码。如果你把那些“大特性”放在一个自己的类中,遵循SRP:@WillMarcouiller H,肯定会简单得多,代码也会更干净