Software architecture design: Number of classes [closed] - c#

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
I will try to explain my question more clearly because the title is a little bit blurry. I have base class that has some properties. Let's say something like this:
public class BaseClas
{
public int Property1 { get; set; }
public bool Property2 { get; set; }
..............................
}
And I have approximately 70 classes that inherit from the base class, most of these classes just add one or two fields, for example:
public class DerivedClas1 : BaseClass
{
public bool PropertyNew1 { get; set; }
}
public class DerivedClas2: BaseClass
{
public bool PropertyNew2 { get; set; }
}
My problem is that I have 70 classes that each of which has just one new field of type bool or int or datetime, etc. My question is: Is it a good architecture design to combine these classes somehow? And if so how should I combine them? I could use some kind of Dictionary<string,object> but this is not such a good idea. Any suggestions?
(I am using .Net 2.0)
Edit: These classes are used for filtering queries for reporting purposes.Base class defines base filters and every class defines filters specific for the report.

It all depends on your Architecture. I can think of at least one class in the core framework that has dozens, possibly hundreds of derived classes, many of which only add one or two fields, and many which don't even do that and only subclass in order to provide a nicer name or a base class for it's own application-specific abstractions. The name of this class? System.Exception
Another Example could be System.Web.Mvc.Controller, although that's stretching it even more than System.Exception (and I purposely left out System.Object and System.ValueType already).
You don't provide any real examples, so the answer is that yes, it can be appropriate, but maybe it isn't. If you are trying to do a generic data entry where you have "Manager" and "Employee" which derive from "Person", which in turn derives from "DataObject", that may be appropriate, but I would look at other ways, e.g. getting rid of "DataObject" and having multiple, specialized Services that provide database operations, but again, it depends on the picture as a whole.
Edit: You just clarified it's for filtering. In this case, can't you use a system where you only define the types of filters?
public abstract class Filter {
}
public class OrFilter : Filter {
public string Clause1 {get; set;}
public string Clause2 {get; set;}
}
public class ItemMustExistFilter : Filter {
public string ItemName {get; set;}
}
public class Report {
// For the sake of the example, I know that public setters on Lists are not
// best practice
public IList<Filter> Filters {get;set;}
}
That way, you only need concrete classes for Filters itself, and each report would have a list of them. Combine that with the use of Generics (see ram's answer) and you should have a pretty 'lightweight' system. Shame you're on .net 2, otherwise Dynamic LINQ would be useful. Sure that you can't use .net 3.5, which still runs on the 2.0 CLR?

Don't know the exact nature of your problem. It is not a question of whether you need 70 classes, its more a question of accurate description of the problem at hand, good design and maintainability. Does generics help ?
public class BaseClass
{
/* some basic properties go here*/
}
public class BaseClass<T>:BaseClass
{
T SomeSpecificProperty {get;private set;}
}
So when you need a "specific" class, you will have
var myObj = new BaseClass<Bool>();
You should also look into Decorator pattern if you want to "Decorate" your classes. Take a look at DoFactory Example
My 2 cents, hope it helps

What you are describing sounds fine to me - each of your reports has a class that describes the filters specific to that report and so if you have 70 reports then you are going to have 70 classes.
Like you say the alternative would be to do something like having a dictionary instead, which has its own set of drawbacks (to start with it isn't strongly typed).
Its tricky to suggest other alternatives without knowing more about the archetecture (does each report have its own class for displaying / retrieving the report? If so perhaps you could refactor so the properties are on that class instead, using attributes to identify filter parameters).
In short - if you don't have an alternative then it can't be bad design! :-)

Related

Dictionary with a string mapped to function [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 4 years ago.
Improve this question
I'm relatively new to C#. I was working on a few console app projects that rely on user input and fire off different functions depending on their input.
I thought that it might be simpler and a bit more flexible to map the possible inputs to a function in a dictionary.
I was told this may be a bad design choice, but wasn't given a clear explanation why.
class Request<T> : IRequest<T>
{
string Route { get; set; }
T Body { get; set; }
}
class Response<T> : IResponse<T>
{
string Route { get; set; }
T Body { get; set; }
}
class Router : IRoutable
{
Dictionary<string, Func<IRequest<T>, IResponse<T>> Routes { get; set; }
}
Can this make my design worse / more fragile? If so, why?
I was told this may be a bad design choice, but wasn't given a clear explanation why.
You should ask that person for clarification.
Can this make my design worse / more fragile? If so, why?
(I assume that your interfaces, which you have not shown, have the same surface area as the classes which implement them. If that's not the case, then you've omitted key details from your question and should update the question.)
Yes, absolutely. Your design allows anyone to change any aspect of the system at any time for any reason! That's a security nightmare.
Also, it exposes what ought to be an implementation detail in the interface. Suppose someone wanted to use a concurrent dictionary? Or an immutable lookup? Nope, they cannot; they are required to use a dictionary in your interface.
Let's step back. What are the basic parts?
A route is represented by a string
A request has a body and a route
A response has a body and a route
A server takes a request and returns a response
A router takes a route and returns a server.
So let's write those.
interface IRoute
{
string Route { get; }
}
interface IRequest<T>
{
IRoute Route { get; }
T Request { get; }
}
interface IResponse<T>
{
IRoute Route { get; }
T Response { get; }
}
interface IServer
{
IResponse<T> Process<T>(IRequest<T> request);
}
interface IRouter
{
IServer GetServer(IRoute route);
}
Remember, interfaces represent the bare minimum contract you need to expose to their clients. Is there any reason why you need to know that IRouter is implemented with a Dictionary? No. Then don't expose that. A router takes a route and gives you a server, end of story. Let the implementer decide whether they want to use a dictionary or not.
Is any possible string a route? Can any route be used as a string? If not, then don't represent routes as strings in the interface. Is it ever possible that someone mistakes a string expression that does not represent a route for one that does? Make the type system catch that bug! Make a type representing routes.
Similarly, don't let anyone write anything that they don't have business writing. Every property should be read-only in the interface unless it is a by-design feature of the type that the property be mutable by anyone.
Another question is: why interfaces at all? Are you going to have three or more implementations of each? If not, consider making them sealed classes or structs instead, preferably immutable types.

Is it better to name C# properties exactly as property type or take a shorter string? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 6 years ago.
Improve this question
Consider following code
class ProductDefinition {}
A:
class Product { public ProductDefinition Definition {get;set}}
B:
class Product { public ProductDefinition ProductDefinition {get;set}}
(B) will result in slight redundancy when using this property such as
product.ProductDefinition.Price
vs
product.Definition.Price
However it seems to be something that programmers are used to see.
Are there any further elaborations on this topic?
I prefer to use class Product { public ProductDefinition ProductDefinition {get;set}}.
Because maybe in the future you wish to add another Definition to your class, and then you could have incongruencies in your property naming, because you would have one Definition and one FooDefinition. I think it is better to have FooDefinition and BarDefinition.
It makes absolutely no sense to name your property ProductDefinition if your class is named Product. A property named Definition is of course the definition of Product (of what else?), so ProductDefinition would be redundand. And there is no practice of naming the proiperty like its type. C# allows that, but it does not mandate it.
The line...
product.Definition.Price
... is 100% clear and free of any redundancies. It's the price of the product's definition.
I would go with Microsoft recommended guidelines
✓ CONSIDER giving a property the same name as its type. For example,
the following property correctly gets and sets an enum value named
Color, so the property is named Color:
public enum Color {...}
public class Control {
public Color Color { get {...} set {...} }
}
So, in this case, I would structure it as:
class ProductDefinition {}
class Product { public ProductDefinition ProductDefinition { get; set; } }
EDITED:
Another point which I would take into consideration is having some other property which gives another definition to the Product object. For example (ProductOwnerDefinition):
class ProductDefinition { }
class ProductOwnerDefinition { }
class Product
{
public ProductDefinition ProductDefinition { get; set; }
public ProductOwnerDefinition ProductOwnerDefinition { get; set; }
}
Here the usage of Definition can lead to confusion. So it is better to name the Property as the name of the type.
Let's also consider another scenario, where we are using static code analysis tools like StyleCop. In this case, if we are not following the recommended patterns it will give suggestion on making modifications. This is not a big deal as we can suppress these rules. But, something to consider moving forward.

Should I use an interface, inheritance or just add more logic to base class [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 6 years ago.
Improve this question
I have a program where the user creates a list of Child objects.
After they have added all the children they can click on the child and decide if that child is naughty and if so create a list who they can't sit with.
Should I add a boolean IsNaughty and a list to the base class, or should I create another class called NaughtyChild that inherits from Child, and implements an ICantSitWith Interface containing a list. I'd then have to turn every Child that is Naughty into the derived class.
What I have so far
public class Child
{
private static int IdCount = 0;
public string Name { get; set; }
public int Id{ get; }
public Child(string name)
{
Name = name;
IdCount++;
Id = IdCount;
}
public override string ToString()
{
return Name;
}
}
public class DisruptiveChild :Child , ICantSitWith
{
public List<Child> CantSitNextToo { get; set; }
public DisruptiveChild(string name, List<Child> cantSitNextToo):base(name)
{
CantSitNextToo = cantSitNextToo;
}
public DisruptiveChild(string name):base(name)
{
CantSitNextToo = null;
}
}
:)
I would go similar way as it is in reality. When you ask "Can this child sit with SomeOne?" the answer is "Yes, the child him-self can sit with AnyOne, the teacher does not want them to sit together". So it is an external need and I would not implement or incorporate it into model. I would implement it on the business level.
Unless you are modeling the classes strictly from the teacher's point of view, then of course the collection "ICantSitWith" should be a base stone on the base class ;)
You just want to add methods to the Child class.
There are lots of reasons, but the most compelling one is that you want the user to be able to change a nice Child into a naughty Child.
You can't change an object's class after it's constructed, so you can't change a non-naughty Child instance into a NaughtyChild instance. You could throw away the Child and create a new NaughtyChild, but that would lead to confusion and complication in an object-oriented program, where every reference to a thing is expected to be a reference to that thing until they're all thrown away.
Note that this is a simple concept -- an object's class determines only immutable characteristics of all instances of that class... just because it applies to all instances of the class and you can't change it. Pay no attention to the fuzzy-headed intuitive reasoning in other responses. If naughtiness is mutable then it is not determined by class in an object-oriented model.
In my openion you should prefer composition over inheritance so that later you don't end up with a complex inheritance hierarchy that will be difficult to manage. So you should be having two interfaces IChild and INaughtyChild. INaughtyChild should inherit from IChild Interface. Then you can implement the two interfaces in two separate classes where INaughtyChild implementation can use IChild implementation for common functionality.

Inherit from multiple classes [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 7 years ago.
Improve this question
How can I make 2 classes inherit from a single base class? I thought...
class Attributes : Student, Teacher
{
// insert code here
}
..would work, but doesn't. Any help?
There is no multiple inheritance in C#. You have to use composition and, optionally, interface inheritance.
If you need to "make 2 classes inherit from a single base class" and your base class is Attributes, then:
public class Student : Attributes
{
// insert code here
}
public class Teacher : Attributes
{
// insert code here
}
Multiple inheritance instead is not supported in C#.
Here some basics about inheritance in C#
Multiple responses:
c# java and the likes don't allow multiple inheritance.
But you can implement multiple interfaces.
the other thing is you
should not really need multiple inheritance.
I suggest you take a look at what you really need. as others pointed out composition or multiple interface implementation may be the answer.
Also, your question is confusing. The code sample shows a class (Attribute) inheriting two super classes (Teacher, Student). But the description asks whether you can do:
class Teacher : Attribute
{ }
and
class Student : Attribute
{ }
Think about what is common between Student and Teacher and put it in an interface
public interface IAttributes
{
public string Name { get; }
}
public class Student : IAttributes
{
}
public class Teacher : IAttributes
{
}
Alternatively you can encapsulate
public class Attributes
{
public Student Student { get; }
public Teacher Teacher { get; }
}
which is a completely different model than the first one.
C# does not support inheriting from multiple classes. In fact any fully object-oriented language like java also does not support multiple inheritance. The reason is, multiple inheritance leads to the diamond problem.
To avoid the problem, fully OO provide support for multiple interface inheritance.
public interface IStudent
public interface ITeacher
class Attributes :IStudent, ITeacher
One another way as others have pointed out is to use composition.
class student{}
class Teacher{}
Class Attributes
{
private Teacher teacher;
private Student student;
}

C# interface design guidelines, interfaces implementing interfaces [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 8 years ago.
Improve this question
Are there design guidelines for the use of interfaces in the scenario below?
I could declare IDescription in DerivedClass or in the interface ISomeInterface or both. 3 choices, what guidelines would help me decide which is best.
public interface IDescription
{
String Description { get; }
}
public interface ISomeInterface
{
String Name { get; }
String Description { get; }
}
public class DerivedClass : Base, ISomeInterface, IDescription
{
public String Description { get; private set; }
}
It depends on the concrete interfaces and their logical relations. There is no universal solution for every case. 2 options you mentioned will be right at some cirtumstances:
If interfaces are not related (for example IDisposable and IEnumerable), then it's better that class implement two unrelated interfaces.
If interfaces are related. For example IClientAPI and IAdminAPI, then admin interface may derive from client's interface, because administrator can do everything normal user can, plus some additional operations.
The case when interfaces derived and at the same time class implements both parent and children interface is rare if at all possible in well-written code. You can always avoid it. I don't see any problems if you specify interface second time for class itself. At the same time there is no profit as well. So better don't do it.
Important note: Don't build inheritance hierarchy based on just matching property names - they can be same by coincidence. Always think if this is coincidence or fixed relation before creating base class or interface. Otherwise you'll end up with tons of interfaces like IDescription, IName, IID, etc that doesn't mean anything and only complicates the code.
If the description property is meant to represent the same semantic object in both cases, I would have ISomeInterface implement IDescription for clarity. If they are not necessarily the same thing in your design, then no.
Design guidelines basically depend on the requirement in this case. If you declare the Description in ISomewhere, then you will be forced to implement its other properties(which in this case is Name) even in the classes, which do not need the Name property.
On the other hand, if the Name and Description properties are required by all the classes where you will use ISomewhere, then it will be better to use it in single place ISomeWhere.
To get more precise answer, you need to analyze the where these interfaces will be used.

Categories

Resources