I have problem to find a good namespace design and class order.
Imagine we have the following namespace hierarchy:
MyCompany.Hardware
- ClassA
MyCompany.Hardware.DeviceType1
- ClassB : ClassA
MyCompany.Hardware.DeviceType2
- ClassC : ClassA
MyCompany.Hardware.Reader
- ReaderClassC : Reader
Questions:
Should I put the base classes always in the parent namespace? Or in the child namespace and the concret implementations in the parent?
Should the ReaderClassC be in a separate or in the same namespace MyCompany.Hardware.DeviceType2? Or should I prefer the parent namespace for 'fast' access?
Forget all the namespaces and put all into one (MyCompany.Hardware)?
Hoppefully you understand what I try to get out. It would be great if you can tell me about your namespace design.
As usual it's a matter of taste.
I prefer to use your fourth approach since it's a little cleaner (for me). I mean, if I'm using a Reader then I depend on using that namespace.
Of course you can give a look to the Namespace Naming Guidelines and particularly:
A nested namespace should have a dependency on types in the containing
namespace. For example, the classes in the System.Web.UI.Design depend
on the classes in System.Web.UI. However, the classes in System.Web.UI
do not depend on the classes in System.Web.UI.Design.
This is all just my ad-hoc advice assuming your relatively new to object oriented programming. I think your question touches an area of design that is subject to debate and programming style choices.
That said,
One of the main goals of namespaces is to group up your types so they can easily be reused by other "clients" or programs that reference their containing class library.
With that in mind, you could start out with just one namespace for simplicity and introduce namespaces when they add value.
One place they might not add value in your example is DeviceType1 and DeviceType2. In my experience these would belong in the same namespace.
namespace Acme.Hardware {
class Product
{
public int Price { get; set; }
public bool InStock { get; set; }
}
class Hammer : Product
{
}
class ScrewDriver : Product
{
}
}
As an example of how coding style and namespaces intersect, notice how I used the very generic name Product as opposed to HardwareProduct. I went with a generic name here because I knew that name would be used by an inclusion of using Acme.Hardware or fully qualified Acme.Hardware.Product. In either case, there is contextual information near by.
In general I'd focus on classes first (i.e. their functionality and implementation) and namespaces secondarily, thinking of them as just a useful way to group up classes.
It depends on other definitions - namespaces are useful when you've got lots of types around, so if your, let's say, ClassB is accompanied with lots of stuff related to Hardware1 then it makes perfect sense to have inner namespace for this.
Ideally, you should just follow the logical grouping. You asked about ReaderC, if it relates to DeviceType2 and not to others, then it should not be in parent namespace, and if ClassA is base for all hardware types, then it needs to be in parent namespace as well.
Related
I have this abstract class:
using TypeLib=some.type.library;
namespace someSpace
{
abstract class Creator
{
abstract public TypeLib.SomeObject createObject();
}
}
Here's a concrete class:
using TypeLib=some.type.library;
namespace someSpace
{
class SpecialCreator:Creator
{
override public TypeLib.SomeObject createObject()
{
doSomethingSpecial();
return new TypeLib.SomeObject();
}
}
}
Because I will want to implement Creator several different ways, all of which require importing some.type.library because they need to return a TypeLib.someObject, is there a way that I can just have the using statement at some high level and have it be inherited by all the implementations? When I didn't include the using statement in SpecialCreator(), it didn't have access to TypeLib.
EDIT: I think this is different than the duplicate directives question. I'm not trying to consolidate different using statements into one master using that I will then add to many classes; instead, I want to put one using statement in a parent class/header file/static class/etc so that it can be accessible to many classes without having to add the same line of code to each class. Let me know if I've misunderstood the duplicate directives question.
It depends. If TypeLib is only used in base class functionality there is no reason to include 'using TypeLib;' in the files that contain the concrete implementations.
If the desired architecture is intended to encapsulate TypeLib in the abstract base class, the need to have the using statement is an indicator that encapsulation has been broken.
Martin Fowler may say the requirement to 'use' TypeLib in all the concrete implementations is the smell of tight coupling between the class tree under the base class and TypeLib. Using an adapter class may reduce the coupling by putting all TypeLib uses into the adapter.
Not unless you define all classes within a single file.
It depends on what you are trying to do.
If you are just trying to avoid having to add this in each and every page of your derived class, your'd be better off using Visual Studio's Export Template (under the File menu). Pick the Item Template and your added template will show up in the Add > New Item List. I think this would be cleanest.
Of course, there is a sneaky way to do avoid the using itself altogether, but I don't think it's good design. Notice I changed the namespace.
namespace some.type.library;
{
class SpecialCreator:Creator
{
override public SomeObject createObject()
{
doSomethingSpecial();
return new SomeObject();
}
}
}
You could also instead, derive a class in your someSpace namespace from TypeLib.SomeObject (no body for the class) and use this new class wherever you were using TypeLib.SomeObject
using is just a syntactic sugar to save you from typing fully qualified type names each time you type them. It's a hint for compiler for places where to look for type names.
So unless you actually use types from TypeLib you don't have to add using statement in each implementation even if some base class of that concrete implementation uses it in some way (i.e. derives from it). And even if your concrete implementation use types from TypeLib you can avoid using statement by specifying fully qualified type names from that library each time.
You could "alias" the type by creating a child class of it for internal use. For example:
namespace Remote.Namespace
{
public class TypeLib
{
public class SomeObject
{
}
}
}
namespace Internal.Namespace
{
public class InternalTypeLibObject : Remote.Namespace.TypeLib.SomeObject
{
}
}
And now you can use InternalTypeLibObject without having to alias the namespace and cast it to TypeLib.SomeObject.
Now for the drawbacks:
If you want to use the constructors in the parent class, you will need to provide mirror constructors and call the base constructor with constructor chaining. Also, if the parent class is sealed, this won't work.
Honestly though you shouldn't be concerned too much about a little typing. Hiding classes like this can add to confusion and should probably be avoided unless you have a reason to extend the type.
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 classes 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.
I'm trying to design a class library for a particular engineering application and I'm trying to ensure that my class & namespace naming conventions make sense.
I have the following situation:
namespace Vehicle{
class Wheel{...} //base class for Wheel objects
class Engine{...} //base class for Engine objects
...
namespace Truck{
class Wheel: Vehicle.Wheel{...} //Truck specific Wheel object
class Engine: Vehicle.Engine{...} //Truck specific Engine object
...
}
namespace Car{
class Wheel: Vehicle.Wheel{...} //Car specific Wheel object
class Engine: Vehicle.Engine{...} //Car specific Engine object
...
}
...
}
The code gets used in ways that all of these classes will need to be referenced from within the same scope. The following situation would be likely:
...
Vehicle.Wheel.DoSomething();
Vehicle.Truck.Wheel.DoSomething();
Vehicle.Car.Wheel.DoSomething();
...
Under these circumstances, am I better off giving the classes more specific names
namespace Car{
class CarWheel: Vehicle.Wheel{...} //Car specific Wheel object
...
}
or leave the naming as shown in the first example and rely on the information that is encoded in the namespace for clarity? Under the latter approach, I assume I would want to utilize alaising for clarity in the code that makes use of this library, corret?
It seems redundent to have:
Vehicle.Car.CarWheel
or
Vehicle.Truck.TruckEngine
but I also want to have very descriptive and specific class names.
Philosophically, what I'm asking is whether or not to include the namespace as a part of the class name when considering if a class name is descriptive enough.
Typically namespaces are pluralized, so as not to collide with class names (e.g. it is likely you would want classes named Vehicle and Car) so I'd be inclined to use namespaces as follows:
namespace Vehicles;
namespace Vehicles.Cars;
namespace Vehicles.Trucks;
As for the names of classes, it would be typical to prefix the class name with the specialization, especially if they are likely to be used together, so you'd end up with something like:
class CarWheel : Wheel
class TruckWheel : Wheel
You can see this type of 'redundancy' everywhere in the .NET Framework, for example in the System.Xml namespace virtually all classes are prefixed with Xml, or in the System.Data.SqlClient namespace most classes are prefixed with Sql. It means that you can import namespaces with the using directive and then not have to fully-qualify class names throughout your code, e.g. which of the following is more readable?
Vehicles.Cars.Wheel wheel = new Vehicles.Cars.Wheel();
or
CarWheel wheel = new CarWheel();
It's obvious what both are doing, but the second is considerably shorter.
Note that if you do include the specialization in the name, then you may find that you don't need all the nested namespaces (.Cars, .Trucks, etc.) which can become painful if they are usually used together, and so every file using them would have to import all the namespaces, e.g.
using Vehicles;
using Vehicles.Cars;
using Vehicles.Trucks;
using Vehicles.SomethingElse;
using Vehicles.YetAnotherThing;
If you find this same stack of using directives is at the top of each file, then collapse the classes down into a single namespace. You typically include all related functionality that is expected to be used together in a single namespace, and only use nested ones for functionality that extends the base namespace but is less frequently used.
I would try to avoid reusing names across different namespaces, particularly if a client may want to use both in the same program.
Do you really need a namespace for Car, Truck etc? All these namespaces sound more like they ought to be classes than namespacese. Perhaps in your real situation it makes more sense though...
Can I expose a class from another .net namespace as a class in my namespace? I use a class - antlr.collections.AST - as the return type for a function belonging to a class in my namespace; as a result, the user has to have
using antlr.collections;
using myNamespace;
at the top of their files in order to use my function. Can I make myNamespace.AST an alias for antlr.collections.AST, such that the user only has to have
using myNamespace;
at the top of their files?
Bear in mind that the consumers of your code won't actually need to have using statements. Those are there to make their lives easier, so they don't have to type antlr.collections.Foo and antlr.collections.Bar all over their source.
The bigger "impact" (if indeed there really is a severe one) is that the consumer of your code will need a hard reference to the assembly where antlr.collections is defined.
However, if that's documented up front, I honestly don't see it being that big of a problem. It's no different than the consumer of a SubSonic-generated DAL needing references both to the generated DAL assembly and the original SubSonic assembly. (And, quite possibly, using statements as well.)
Dependencies are what they are. There's a reason classes are broken into namespaces -- primarily for organization and to reduce naming conflicts. Not knowing what classes are in the namespace you mention, I don't know how likely such a conflict actually is in your scenario ... But attempting to move the class from one namespace to another, or to hide the fact that such is needed by deriving a blank class from it, is probably not the best idea. It won't kill the consumers of your class to have another reference and using statement.
How about deriving a class using the same name in the new namespace? I meant:
namespace MyForms {
class Class1 : Some.Other.Namespace.Class1 {
// ...
}
}
create a new class that inherits the class in your new namespace. It's not ideal, but it's useful for unit testing and the like.
You should think about why you are doing this though, classes are broken up into namespaces for a reason.
No, you can't.
The full path to and name of a class is part of its identity.
If you derive from the class and return your derived class, you'll make yourself responsible for providing all of the documentation for the return type.
I think you'll be doing the developers who use your library a disservice because they won't necessarily know that what they're really working with is a type from antir.collections (not that I even know what that is, but that's not the point). If the developer comes to StackOverflow.com searching for information on that return type, are they more likely to find information if the type is from a "common" library, or from yours?
The only solution is to hide the whole dependency to the type antlr.collections.AST.
You can use an Adapter fot that purpose.
I've got a group of inter-related classes that are all overridden together to create a particular implementation. I'm wondering if it is a good idea to enclose the interrelated subclasses in a namespace.
For example purposes, consider the following namespaces and classes:
namespace Protocol
{
public abstract class Message { }
public abstract class Driver { }
}
namespace Protocol.Tcp
{
public class TcpMessage : Message { }
public class TcpDriver : Driver { }
}
namespace Protocol.Ftp
{
public class FtpMessage : Message { }
public class FtpDriver : Driver { }
}
What is the best way to structure the namespaces? It seems unavoidable to expose the inheritance in the namespace since the base classes don't really belong in either the Protocol.Tcp namespace or the Protocol.Ftp namespace.
I think you are perhaps worrying too much!
Does it make sense logically? Do you know where to find your code within the namespaces?
I would much rather see a codebase like the above with a small number of classes, relevant to the name with a hierarchy, than one large namespace where everything is interrelated..
Remember, namespacing is there for precisely this, to organise your codebase logically
What you have seems logical :)
EDIT:
As an example:
using System.Data;
using System.Data.Sql;
;)
The original tags show that this post is about C# - therefore multiple inheritance is an irrelevancy - you can't multiply inherit in C#.
Maybe you should consider defining some interfaces that define what the basic contracts of a Message and a Driver are and then you may feel a little free-er to use the namespace structure to mimic the technology differences.
If this were me, I would define 2 namespaces:
Protocol
and
Protocol.Driver
Dividing the namespace like this separates your "library code" vs your "executable / test code."
I also create my namespaces to match the directory structure; it will give logic to your programs structure and codefiles. (maybe you already do this...)