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 8 years ago.
Improve this question
I reading some code written by some other programmer, He made some design for application, application classes derived each other like that:
public interface IABase
{
}
class BBase : IABase
{
}
class CDesktop : BBase
{
}
class Report : CDesktop
{
}
class Sample : Report
{
}
This kind of design is anti pattern? I have to tell first, its realy hard to understand relationship of class and logic of application, this is my 2 cents. What else you can say?
There's a bit of general advice floating around to prefer composition over inheritance. The advantage often touted are that it's more flexible, and discourages tight coupling more. (see where-does-this-concept-of-favor-composition-over-inheritance-come-from, DeepClassHierarchies, deep-class-inheritance-hierarchy-bad-idea, long-inheritance-hierarchy amongst many others for discussions on this matter).
Specifically for C#, it's worth noting that composition can require considerable boilerplate - after all, if you want to expose much of the functionality of the component/base-class, then you'll need to manually expose that; inheritance (by contrast) makes it very easy to just expose everything.
It's probably a good idea to use inheritance sparingly when in doubt because it's easy to create lots of tightly coupled spagetti-monsters otherwise. But there are cases where classical dynamic dispatch and all that is wanted; and there are also cases where even though your concepts better map to a has-a relationship than an is-a relationship the wordiness of composition is a considerable burden.
So while this kind of code is harder to maintain, it might still be worth it on occasion. Your specific example looks like the hierarchy is unnecessarily deep; however, it's normal for old code to grow a few warts - if this is the worst of it, consider yourself lucky.
Related
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 3 years ago.
Improve this question
I like the DI feature of ASP.NET Core, but am finding that some of my classes end up with huge constructor parameter signatures...
public class Foo {
private IBar1 _bar1;
private IBar2 _bar2;
// lots more here...
public Foo(IBar1 bar1, IBar2 bar2, lots more here...) {
_Bar1 = bar1;
_Bar2 = bar2;
// ...
}
public DoSomething() {
// Use _bar1
}
}
In case this looks like a code smell, it's worth pointing out that any controller is going to use AutoMapper, an email service and 2 or 3 managers related to ASP.NET Identity, so I have 4 or 5 dependencies before I start injecting a single repository. Even if I only use 2 repositories, I can end up with 6 or 7 dependencies without actually violating any SOLID principles.
I was wondering about using a parameter object instead. I could create a class that has a public property for every injected dependency in my application, takes a constructor parameter for each one, and then just inject this into each class instead of all the individual Bars...
public class Foo {
private IAllBars _allBars;
public Foo(IAllBars allBars) {
_allBars = allBars;
}
public DoSomething() {
// Use _allBars.Bar1
}
}
The only disadvantage I can see is that it would mean that every class would have every dependency injected into it via the parameter object. In theory, this sounds like a bad idea, but I can't find any evidence that it would cause any problems.
Anyone any comments? Am I letting myself into potential trouble by trying to make my constructor code neater?
What you're describing sounds like the service locator pattern, and while it seems tempting to simplify your code by eliminating all those constructor parameters, it usually ends up hurting maintainability in the long run. Check out Mark Seemann's post Service Locator violates encapsulation for more details about why it should be avoided.
Generally, when you find yourself with a class with dozens of constructor parameters, it means that class might have too many responsibilities. Can it be decomposed into a number of smaller classes with narrower goals? Rather than introducing a "catch-all" class that knows about everything, maybe there's a complex part of your application that you can abstract behind a facade.
Sometimes, you do end up with large coordinator classes that have many dependencies and that's okay in certain circumstances. However, if you have many of these it's usually a design smell.
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 7 years ago.
Improve this question
Simple example:
public class Food
{
public virtual void Eat()
{
StuffInMouth();
}
}
public class Fruit : Food
{
// Nothing here yet, but likely could be in the future
// Is this bad from a .NET/C# style guidelines perspective?
}
public class Apple : Fruit
{
public virtual void Eat()
{
Clean();
base.Eat();
}
}
public class Orange : Fruit
{
public virtual void Eat()
{
Peel();
base.Eat();
}
}
As simple as I can put it, it is called Speculative Generality.
Reasons for the Problem: Sometimes code is created "just in case" to support anticipated future features that never get implemented. As a result, code becomes hard to understand and support.
As Steve McConnell points out in Code Complete - 2,
Programmers are notoriously bad at guessing what functionality might be needed someday.
1. Requirements aren't known, so programmer must guess: Wrong guesses will mean the code must be thrown away.
2. Even a close guess will be wrong about the details: These intricacies will undermine the programmer's assumptions - the code must be (or should be) thrown away.
3. Other/future programmers may assume the speculative code works better or is more necessary than it is: They build code on the foundation of speculative code, adding to the cost when the speculative code must be removed or changed.
4. The speculative generality adds complexity and requires more testing and maintenance: This adds to the cost and slows down the entire project.
Credits: Code Complete - 2 | Pluralsight course on refactoring.
Imho It is an extra abstraction layer with no added value.
It adds unnecessary complexity, so in my opinion it's bad practice and an example of YAGNI.
yeah, it is important to realize that while it can save time to do things like this (if it is used) it is typically better to code for the immediate future, or at least understand when you are coding for the future that will never come.
There is also maintenance overhead of implementing things too early.
No one said a class must have any members. A class represents a category of objects, so in case they have no useful properties (not in the language's meaning) it's perfectly fine to have it empty. So what's important is whether the class does represent a meaningful category of objects your code needs to work with or not.
In your case, should your code generally operate on food, having a common Food ancestor makes sense. However, a better concept may be introducing an IFood interface, effectively decoupling the food contract from actual inheritance hierarchies. For example, a meaningful hierarchy may start with an Animal class, but not every animal is considered food (disclaimer: this is rough example).
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
Original Questions: I know the question sounds pretty "thin", since generic classes (interfaces) and collections go hand in hand. Out of curiosity and a desire to 'cover all the bases' ... are there uses for these generics other than as collections?
The response is that there are too many possibilities to make for a good thread, so let me try to clarify the question because I ( and probably others) will definitely benefit.
My revised question is:
What are applications of instantiated generics (not methods!) in addition to collections? So, now I know there are many ... however, classified by use... what are they?
A concise format for answers is:
Use: Short description or example
(ie) Collections: The generic allows for collections of objects and with a where T: constraint gives access to methods on all members of the collection. (link or reference).
I'm really eager to hear responses.
You can create not only generic types but also generic methods. Though the most common use of generics is for creating collections they are also used for many other purposes such as containers or algorithms.
class Point<T>
{
T x;
T y;
};
class Math<T>
{
T Add(T a, T b);
};
You should also have a look at this discussion: What is cool about generics, why use them?.
I've used generics for a "EventHandler" (with a restriction on the generic that the parameter implemented my BaseEvent class) when sending events via WCF to another piece of the system.
As the comments note, the answer is unequivocally yes. You use generics whenever multiple types (and ideally all types) should have the same behavior (and occasionally state). Collections are an easy example of this, but there are many, many other situations where this holds true and generics are a good choice.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 9 years ago.
Improve this question
I've read some things about this, I even found similar question, but it didn't really answer this. For me it seems that privatizing something only makes my life so much harder when I need to find a private variable in a class to use it elsewhere. So what is would the problem be if everything was public? Would it somehow slow the program itself?
You must consider the maintainability of the code. Accessing all the variables everywhere in your solution is good only if you are the only one in the project and you will be the only one that maintain and use the code. If someone else's entered into project and do completely different things they will be able to access your methods/variables and set the things to unexpected variables. You should think as a OOP design and design your classes like that.
FYI I don't believe you are supposed to ask discussion-based questions like this on SO... But the simplistic answer is this: don't limit your thinking to the logic of the code. We all know there are ten thousand ways to accomplish the same thing. You can probably rewrite a bunch of your code to avoid encapsulation. However, data encapsulation provides a few benefits when you start working on larger projects or with larger teams that go beyond just writing functional code:
(1) organization by concept: if you're coding a bike you would code a class for the wheel, a class for the frame, a class for the handlebars, etc., and you'd know where to go to resolve an issue, perhaps even after months of time away from the code;
(2) separation of implementation and interface: you can tell the world about your public interface and handle the actual implementation privately, so people don't have to know how things work in your code, they just know that it works, like a black box; and if later you have to change your private implementation you can do so freely as long as the public interface still works;
(3) simplification for humans: remember, humans read your code, so would you like to slam them with every bit of data and logic in your project? that would just make for a bunch of angry programmers.
So that's a gentle introduction to encapsulation.
This comes from the fact that, a class should not expose its members directly but must provide a proxy through which the members must be accessed. (Like getters/setters or Properties)
See this question for more info: Why it is recommended to declare instance variables as private?
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 9 years ago.
Improve this question
Before down-voting let me explain my question. I have a little experience in designing architectures and try to progress. Ones, when I was fixing a bug, I came up with a conclusion that we need to make our private method to be public and than use it. That was the fastest way to make my job done, and have a bug fixed. I went to my team-leader and said it. After I've got a grimace from him, I was explained that every public method is a very expensive pleasure. I was told that every public method should be supported throughout the lifetime of a project. And much more..
I was wondering. Indeed! Why it wasn't so clearly when I was looking in the code. It wasn't also so evidently when I designed my own architectures. I remember my thoughts about it:
Ahh, I will leave this method public, who knows, maybe it will come usefull when the system grows.
I was confused, and thought that I made scaleable systems, but in fact got tons of garbage in my interfaces.
My question:
How can you explain to yourself if a method is really important and worthy to be public? Are any counterexamples for checking it? How you get trained to make private/public choise without spending hours in astral?
I suggest you read up on YAGNI http://c2.com/cgi/wiki?YouArentGonnaNeedIt
You should write code to suit actual requirements because writing code to suit imagined requirements leads to bloated code which is harder to maintain.
My favourite quote
Perfection is achieved, not when there is nothing more to add, but
when there is nothing left to take away.
-- Antoine de Saint-Exupery French writer (1900 - 1944)
This question need a deep and thorough discussion on OOP design, but my simple answer is anything with public visibility can be used by other classes. Hence if you're not building method for others to use, do not make it public.
One pitfall of unecessarily making private method public is when other classes did use it, it makes it harder for you to refactor / change the method, you have to maintain the downstream (think if this happen to hundreds of classes)
But nevertheless maybe this discussion will never end. You should spend more time reading OOP design pattern books, it will give you heaps more idea
There are a few questions you can ask yourself about the domain in which the object exists:
Does this member (method, property, etc.) need to be accessed by other objects?
Do other objects have any business accessing this member?
Encapsulation is often referred to as "data hiding" or "hiding members" which I believe leads to a lot of confusion. Inexperienced developers would rightfully ask, "Why would I want to hide anything from the rest of my code? If it's there, I should be able to use it. It's my code after all."
And while I'm not really convinced with the way in which your team leader worded his response, he has a very good point. When you have too many connection points between your objects, you end up with too many connections. Objects become more and more tightly coupled and fuse into one big unsupportable mess.
Clearly and strictly maintaining a separation of concerns throughout the architecture can significantly help prevent this. When you design your objects, think in terms of what their public interfaces would look like. What kind of outwardly-visible attributes and functionality would they have? Anything which wouldn't reasonably be expected as part of that functionality shouldn't be public.
For example, consider an object called a Customer. You would reasonably expect some attributes which describe a Customer, such as:
Name
Address
Phone Number
List of orders processed
etc.
You might also expect some functionality available:
Process Payment
Hold all Orders
etc.
Suppose you also have some technical considerations within that Customer. For example, maybe the methods on the Customer object directly access the database via a class-level connection object. Should that connection object be public? Well, in the real world, a customer doesn't have a database connection associated with it. So, clearly, no it should not be public. It's an internal implementation concern which isn't part of the outwardly-visible interface for a Customer.
This is a pretty obvious example, of course, but illustrates the point. Whenever you expose a public member, you add to the outwardly-visible "contract" of functionality for that object. What if you need to replace that object with another one which satisfies the same contract? In the above example, suppose you wanted to create a version of the system which stores data in XML files instead of a database. If other objects outside of the Customer are using its public database connection, that's a problem. You'd have to change a lot more about the overall design than just the internal implementation of the Customer.
As a general rule it's usually best to prefer the strictest member visibilities first and open them up as needed. Combine that guideline with an approach of thinking of your objects in terms of what real-world entities they represent and what functionality would be visible on those entities and you should be able to determine the correct course of action for any given situation.