创建命名空间 - >类 - >嵌套类?要么

时间:2011-09-06 14:36:10

标签: c# class namespaces nested-class

我正在阅读有关创建类和嵌套类的内容,以确定哪种方法适合我的需求,但我找不到类似于我需要的东西(或者无法理解;)。

我会给你们一个(几乎)真实的例子:

假设我拥有一家生产各种车辆的工厂。所以,我的命名空间是Factory我想。

现在,让我们说工厂生产汽车,船只和飞机。因此,我将使用这些名称向我的Factory命名空间添加三个类。

我的问题在于理解其他方法:

我在三种类型的车辆之间有一些共同点。例如,它们都有一个引擎(可能是不同的HP或我理解的形状是引擎的属性,但它们都有引擎)。此外,汽车和飞机有门(有时船也有)。另一方面,它们也有一些独特的东西(例如飞机有螺旋桨可能有不同的尺寸或形状)。

有人可以在代码中描述我所说的内容,以便了解它们之间的区别吗?

6 个答案:

答案 0 :(得分:7)

你的问题有点模糊。我会回答两个相关的问题,而不是试着回答它。

  

命名空间的目的是什么?

命名空间的主要目的是将组织类型声明组织到层次结构中,以便用户可以轻松找到它们。

命名空间的第二个目的是提供一种消除名称冲突消除歧义的机制。也就是说,如果XYZ Corp有类型Vehicle且ABC Inc有类型Vehicle,并且PQR有限公司想同时使用来自XYZ和ABC的代码,那么PQR程序员需要一种方法来告诉编译器实际上哪种类型的“车辆”是指。

您建议命名您的命名空间“Factory”。这可能是一个坏主意。工厂可能是一个类,而不是命名空间。工厂是一种东西,而不是组织事物的方式。我倾向于将我的命名空间命名为“Dementic.Manufacturing”并让它包含一个Factory类。现在,事情的组织方式有两种:第一种是由公司Dementic Incorporated生产代码,以及与代码相关的,即制造。并且您的任何竞争对手也不太可能创建名为Dementic.Manufacturing的名称空间。

  

我应该何时制作嵌套类型而不是顶级类型?

当嵌套类型是外部类型的实现细节时,创建嵌套类型。一般认为制作公共嵌套类型是一种不好的做法,尽管偶尔会这样做。

一个常见的例子是枚举器类;它通常是可枚举集合的私有实现细节。

答案 1 :(得分:2)

您可以将所有这些都粘贴在Factory命名空间中。

车辆类别将包含共享组件,并且您的特定车辆类型的类将继承自车辆类......您所问的是什么?

public class Engine
{
   public int HorsePower {get;set;}
}

public class Vehicle
{
    public Vehicle() { }

    public Engine Engine;
    public int Doors;
}

public class Airplane : Vehicle
{
    public Airplane () { }

    public string PropellerModel;
}

public class Boat : Vehicle
{
    public Boat () { }

    public string RudderModel;
}

答案 2 :(得分:2)

如果你想尽可能通用,你可以这样做:

namespace Factory
{
    public interface IDoor { }
    public interface IEngine { }
    public interface IPropeller { }

    public abstract class Vehicle
    {
        public ICollection<IDoor> Doors { get; protected set; }
        public ICollection<IEngine> Engines { get; protected set; }
    }

    public class Airplane : Vehicle
    {
        public ICollection<IPropeller> Propellers { get; protected set; }
    }
}

然后让具体的具体类型为超类型属性提供相关的集合。

这有点像黑客,但是将任何真实世界的对象建模为编程语言中的类迟早会崩溃。

请注意,我也将引擎属性设置为集合。这是为了支持Prius类,它将有两个引擎。

另一种方法是根据界面定义车辆,如下所示:

namespace Factory
{
    public interface IDoor { }
    public interface IEngine { }
    public interface IPropeller { }

    public interface IDoorProvider
    {
        ICollection<IDoor> Doors { get; }
    }

    public interface IEngineProvider
    {
        ICollection<IEngine> Engines { get; }
    }

    public interface IPropellerProvider
    {
        ICollection<IPropeller> Propellers { get; }
    }

    public abstract class Vehicle { }

    public class Car : Vehicle, IDoorProvider, IEngineProvider
    {
        public ICollection<IDoor> Doors { get; protected set; }
        public ICollection<IEngine> Engines { get; protected set; }
    }

    // And so on...
}

这种方法的优点是您不必在Vehicle本身上定义太多,但这也意味着您无法轻松地在所有类中共享这些成员的定义。但是,这会阻止您在基类型上定义与具体类型无关的成员。

答案 3 :(得分:2)

您对命名空间的概念有错误。命名空间与此无关。

我认为你的遗产和工厂也很混乱。同样,这些是非常独立的想法。

首先考虑使用提供对象基本结构的公共基类创建类heirarchy,然后提供提供特定详细信息的专用子类。除非它确实有效,否则小心不要使用继承。如果没有意义,不要强迫你的模型进入继承层。

然后您可以担心创建一个或多个工厂来创建这些对象的实例。

对于名称空间,名称空间只是一种以逻辑,有意义的方式将相关代码片段组合在一起的方法。您可能拥有工厂命名空间,但您也可以拥有“工厂”命名空间或“车辆”命名空间或与您的域相关的完全不同的东西。

答案 4 :(得分:1)

由于提出问题的人实际上可能从中得到一些价值,所以我的意思是:

如果您的软件以某种方式处理现实世界的对象,请不要尝试根据现实世界对代表应用程序核心的类进行建模。相反,请让软件的要求指导您的对象的外观。

例如,这是订单管理系统吗? 在这种情况下,某些可订购物品具有与其直接相关的其他可订购物品可能更相关。对于船只,您可以订购某些零件,引擎等。也就是说,表达可订购物品之间的关系而不是将它们作为具体类型提供可能更为重要。

例如,它是绘制新船,飞机,螺旋桨等的工具吗?然后一个更相关的基类可能是一个形状。是否更多关于计算发动机的功率或螺旋桨的效率?那么你可能需要一些数学主体的概念,并且需要在不同的对象之间定义额外的物理关系和特征。

最后,根据经验,您可以将继承视为一种有些被高估的概念,因为它是初学者在触摸OO时首先想到的。自然界中重用的主要概念是构图 - 最终所有自然事物都由具有非常清晰界面的小物品组成。理想情况下,您将尝试以类似的方式组合您的OO应用程序。

答案 5 :(得分:0)

我宁愿选择VehicleFactory名称空间,将Factory作为一个类(有很多设计模式可以解决创建对象的问题,通常这需要是一个类,或者至少(通常是非目标编程)函数。不会为你提供这个。