开发者

Creating a Namespace -> Class -> Nested Class? or

I was reading about creating classes and nested classes to determine what is the best approach for my needs, but I couldn't find something similar to what I need ( or couldn't understand it ;) ).

I will give you guys a (almost) real-life example:

Let's say I own a factory which manufactures different kinds of vehicles. So, my namespace would be Factory I figure.

Now, lets say the factory manufactures cars, boats and airplanes. So I will add three classe开发者_JS百科s to my Factory namespace with those names.

Here is where my problem is with understanding the other methods:

I have some common things between the three types of vehicles. For example, they all have an engine (might be different HP or shapes which I understand are properties of the engine, but still they all have an engine). Also, cars and airplanes have doors (sometimes boats do too). On the other hand, they also have some unique things (airplanes have propellers for example that might come in different sizes or shapes).

Can someone please describe what I said in code so I could understand the differences between them?


Your question is a bit vague. Rather than try to answer it, I'll answer two related questions.

What is the purpose of a namespace?

The primary purpose of a namespace is to organize type declarations into a hierarchy so that they can be found by users easily.

The secondary purpose of a namespace is to provide a mechanism for disambiguating name collisions. That is, if XYZ Corp has a type Vehicle and ABC Inc has a type Vehicle, and PQR Ltd wants to use code from XYZ and ABC at the same time, the PQR programmers need a way to tell the compiler which type "Vehicle" actually refers to.

You suggest naming your namespace "Factory". That's probably a bad idea. A factory is probably a class, not a namespace. A factory is a kind of thing, not a way of organizing things. I would be inclined to name my namespace "Dementic.Manufacturing" and have it contain a Factory class. Now things are organized in two ways: first, by the company, Dementic Incorporated, that is producing the code, and by what the code is related to, namely, manufacturing. And it is unlikely that any competitor of yours will also make a namespace called Dementic.Manufacturing.

When should I make a nested type as opposed to a top-level type?

Make a nested type when the nested type is an implementation detail of the outer type. It is generally considered a poor practice to make a public nested type, though it is occasionally done.

A common example is an enumerator class; it is usually a private implementation detail of a enumerable collection.


You could stick all these in your Factory namespace.

A vehicle class would contain shared components, and classes for your specific vehicle types would inherit from the vehicle class... is that what you're asking?

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;
}


If you want to be as generic as possible, you can approach it something like this:

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; }
    }
}

Then have the specific concrete types provide the relevant collections to the supertype properties.

This is a bit of a hack, but modeling any real-world objects as classes in a programming language is going to break down sooner or later.

Note that I've made the engine property a collection too. This is to support, for example, the Prius class, which would have two engines.

An alternate approach would be to define the vehicles in terms of interfaces, somewhat like this:

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...
}

This approach has the advantage that you don't have to define much on Vehicle itself, but this also means that you can't easily share the definitions of these members across all of the classes. However, this prevents you from defining members on the base type that are not relevant to the concrete types.


You have the wrong concept of what namespaces are. Namespaces have nothing to do with this.

I think you're also confusing inheritance and factories. Again, those are very separate ideas.

First think about creating your class heirarchy with the common base class that provides the basic structure of your objects and then the specialized subclasses that provide the specific details. And be careful not to use inheritance unless it truly works. Don't force your model into an inheritance heirarchy if it doesn't make sense.

Then you can worry about creating one or more factories to create instances of these objects.

As for namespaces, a namespace is just a way to group related pieces of code together in a logical, meaningful way. You might have a factory namespace, but you could just as well have a "factories" namespace or a "vehicles" namespace or something completely different which is relevant to your domain.


Since the person asking the question might actually get some value out of it, here my take:

If your software deals in some ways with objects of the real world, don't try to model the set of classes that represent the core of your application according to the real world. Rather, let the requirements of the software guide as to how your objects will look like.

For example, is this an order management system? In that case it may be more relevant that certain orderable items have other orderable items directly associated with it. For a boat you can order certain parts, engines, etc. That is, it may more important to express the relationships between orderable items instead of having them available as concrete types.

For example, is it a tool to draw new boats, planes, propellers, etc.? Then a more relevant base class maybe that of a shape. Is it more about calculating the power of an engine or the efficiency of a propeller? Then you may need some concept of mathematical bodies and additional physical relationships and characteristics need to be defined between the different objects.

Lastly, as a rule of thumb you can think of inheritance as a somewhat overrated concept in that it is the first thing that starters think of when touching OO. The predominant concept of reuse in nature is composition - ultimately all natural things are composed of small items with very clear interfaces. Ideally, you will try and compose your OO application in a similar fashion.


I would rather go for VehicleFactory namespace, Factory as a class (there are many design patterns addresing the problem of creating objects and usually this needs to be a class, or at least (usually in non-objective programming) function. Namespace won't provide you this.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜