Design Principles [closed] - oop

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 4 years ago.
Improve this question
What principles do you generally follow when doing class design?

Principles Of Object Oriented Class Design (the "SOLID" principles)
SRP: The Single Responsibility
Principle A class should have one,
and only one, reason to change.
OCP: The Open Closed Principle You
should be able to extend a classes
behavior, without modifying it.
LSP: The Liskov Substitution
Principle Derived classes must be
substitutable for their base
classes.
ISP: The Interface Segregation
Principle Make fine grained
interfaces that are client specific.
DIP: The Dependency
Inversion Principle Depend on
abstractions, not on concretions.
Source: http://butunclebob.com/ArticleS.UncleBob.PrinciplesOfOod
Video (Uncle Bob): Clean Coding By Robert C. Martin ( Uncle Bob )

Don't forget the Law of Demeter.

The S.O.L.I.D. principles.
Or at least I try not to steer away too much from them.

The most fundamental design pattern should be KISS (keep it simple stupid)
Which means that sometimes not using classes for some elements at all it the right solution.
That and CRC(Class, Responsibility, Collaborators) cards (write the card down in your header files, not on actual cards that way they because easy to understand documentation too)

As mentioned above, some of the fundamental Object Oriented Design principles are OCP, LSP, DIP and ISP.
An excellent overview of these by Robert C. Martin (of Object Mentor) is available here: OOD Principles and Patterns

The "Resource Acquisition Is Initialization" paradigm is handy, particularly when writing in C++ and dealing with operating system resources (file handles, ports, etc.).
A key benefit of this approach is that an object, once created, is "complete" - there is no need for two-phase initialization and no possibility of partially-initialized objects.

loosely coupled, highly cohesive.
Composition over inheritance.

Domain Driven Design is generally a good principle to follow.

Basically I get away with programming to interfaces. I try to encapsulate that which changes through cases to avoid code duplication and to isolate code into managable (for my brain) chunks. Later, if I need, I can then refactor the code quite easily.

SOLID principles and Liskov's pattern, along with Single responsibility pattern.

A thing which I would like to add to all this is layering, Define layers in your application, the overall responsibility of a layer, they way two layers will interact. Only classes which have the same responsibility as that of the layer should be allowed in that layer. Doing this resolves a lot of chaos, ensures exceptions are handled appropriately, and it makes sure that new developers know where to place their code.
Another way to design is by designing your class to be configurable creating a mechanism where the configuration can be plugged in your class, rather than overriding methods in sub classes, identify what changes, see if that can be made configurable and ensures that this functionality is derived from configurations

I usually try to fit the class into one of the oo design patterns.

Related

Abstraction in OOP: multiple, yet rather distinct, contexts? [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 5 years ago.
Improve this question
I've been doing some research on OOP concepts and am having a bit of an issue in trying to understand what exactly Abstraction is. I've gone over numerous Stack Overflow posts on the topic but haven't really been able to pinpoint a satisfying answer.
I've seen a lot of discussions on the differences between Abstraction and Encapsulation, and naturally started started thinking about Abstraction in terms of hiding how a particular class works and providing abstraction through the class API. Here are some posts that steered me in this direction:
Best voted answer refers to functions being Abstract. The very next answer starts talking about abstract classes...
Best voted answer seems to refer to exposing through the class API while the next two goes off in an Inheritance setting. Third answer even suggests Composition and Aggregation is considered an Abstraction
However, as I read through more posts, I noticed answers portraying Abstraction in an Inheritance context, specifically using interfaces and abstract classes to provide an Abstraction of a certain entity (class). I assumed Abstraction given in this manner would allow developers to extend new objects appropriately according to the "guidelines" outlined by this Abstraction. Here are some posts that lead me in this direction:
First couple of answers talk about Abstraction in an abstract class/interface setting, while some down the line start talking about exposing classes through APIs
Top two voted answers refer to abstract classes/interfaces
I'm not sure if I'm just completely missing the point here, but it's getting pretty confusing because every answer seems to add a slight variation to the mix. I definitely see why both contexts are crucial in Object Oriented Programming, but I really wanted a clear-cut definition of what Abstraction is.
Which brings me to my point: does Abstraction work in multiple contexts? Does Abstraction portray both of these concepts?
Hiding away "unnecessary details" as done through interfaces and
abstract classes
Providing an abstraction on a class to be created through interfaces and abstract classes. We can provide an interface of IPet which would act as an abstraction of a Dog class. Additionally, we could provide an Animal base class as an abstract class to provide a higher level abstraction. This could let us use Polymorphism and allow different classes that fall under our Animal abstraction to interact with one another.
Abstracting the implementation of a class by exposing it through the class API
given a Dog class, we just need to know that it has a feed() function as part of its API, and call that function to feed it without knowing how the feeding is actually done. This provides abstraction on the Dog class and lets us easily interact with the class
One of the links I've included above contains the following quote by Matthew Watson that says:
"The problem is that there are no precise definitions for these concepts, and the words themselves have multiple meanings even within the context of object orientation."
Is it just that Abstraction is so abstract, even the definition is abstract :P? Thanks for any guidance in advance!
Edit: I'm rather new to SO and am not really aware of what the "primarily opinion based" flag entails. I don't see how this question is any less valid than the slew of questions regarding Abstraction on SO. I think it would be considered less opinion-based as I'm actually pinpointing two different contexts in which I think Abstraction makes sense in. I've seen many questions that just ask what Abstraction is, which I'd think is an even broader question than what I have here.
To me, abstraction is one of the most beautiful concepts of oo, which is actually what makes the program language very close to human thinking: we, humans always want to classify. Think of a car: your car. And let's approach that car in the context of a banker asking about your assets in the context of a loan: you will say you have assets (highest level of abstraction): an expensive car, a family car, a house, a boat, etc. They all have a specific value. Then suppose the context of the conversation switches to the banker having a personal interest in that car, given he's a car freak him selves. Now the cars will be described in more detail, and you can see different abstraction levels being defined: sport car with brand names, and lots more characteristics.
During the design time, your interest is about the levels of abstraction: What you want to do with it, i.e. its context. So, we will have the levels of abstraction: Asset, Car (and Boat and House), SportCar, FamilyCar. And so on. The context should never have more details than it needs, and this is what you're concerned about during design phase.
During the implementation phase, you will implement these levels of abstraction by encapsulating the properties that belong at these levels. E.g. Asset has a value, where Car has colour and SportCar might have some specific characteristics that a FamilyCar doesn't have.
So, key difference is: design time vs implementation time.
This blog post described the difference in much detail:
http://javarevisited.blogspot.be/2017/04/difference-between-abstraction-and-encapsulation-in-java-oop.html
Here's another post at stackoverflow: What's the difference between abstraction and encapsulation?
Hope this helps.
As for me, the abstraction is when you solve a problem without going into the details at all. If you need to output list of cars, then I do not think "take a list of cars, walk through them, get their data, print them", I rather think "I need a set of objects, preferably cars, that can display data about themselves in the format that I need.". It's more about way of thinking.

Information hiding is abstraction or encapsulation?

The title says it all, I am bit confused as I was asked a question that Information handling in term of OOP is abstraction or encapsulation?
I opted for abstraction but still I am confused because in encapsulation we also hide the fields and in abstraction we hide the details.
Any help in this regard
It may help if you think of encapsulation as one of the tools used to create abstraction. See the wikipedia entry for encapsulation here http://en.wikipedia.org/wiki/Encapsulation_(object-oriented_programming)
Abstraction generally hides information, while Encapsulation separates the changeable data from the unchanged one. In this way, Encapsulation helps to achieve the Open Closed Principle.
Here is a nice answer that I think it clears the confusion
Encapsulation has two faces; data
abstraction and information hiding.
Data abstraction is a type seen from
the outside. Information hiding is a
type seen from the inside.
Abstraction focuses on the outside view of an object (i.e. the interface)
Encapsulation (information hiding ) prevents clients from seeing its
inside view, where the behavior of the
abstraction is implemented
Encapsulation = Hiding the Complexities / information
Abstraction = A (somewhat) defined way to handle complexities, using encapsulation

Why encapsulation is an important feature of OOP languages? [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
I came across different interview where question was asked to me why encapsulation is used? Whose requirement actually is encapsulation? Is it for users of program? Or is it for co-workers? Or is it to protect code from hackers?
Encapsulation helps in isolating implementation details from the behavior exposed to clients of a class (other classes/functions that are using this class), and gives you more control over coupling in your code. Consider this example, similar to the one in Robert Martin's book Clean Code:
public class Car
{
//...
public float GetFuelPercentage() { /* ... */ };
//...
private float gasoline;
//...
}
Note that the client using the function which gives you the amount of fuel in the car doesn't care what type of fuel does the car use. This abstraction separates the concern (Amount of fuel) from unimportant (in this context) detail: whether it is gas, oil or anything else.
The second thing is that author of the class is free to do anything they want with the internals of the class, for example changing gasoline to oil, and other things, as long as they don't change its behaviour. This is thanks to the fact, that they can be sure that no one depends on these details, because they are private. The fewer dependencies there are in the code the more flexible and easier to maintain it is.
One other thing, correctly noted in the underrated answer by utnapistim: low coupling also helps in testing the code, and maintaining those tests. The less complicated class's interface is, the easier to test it. Without encapsulation, with everything exposed it would be hard to comprehend what to test and how.
To reiterate some discussions in the comments:
No, encapsulation is not the most important thing in OOP. I'd dare even to say that it's not very important. Important things are these encouraged by encapsulation - like loose coupling. But it is not essential - a careful developer can maintain loose coupling without encapsulating variables etc. As pointed out by vlastachu, Python is a good example of a language which does not have mechanisms to enforce encapsulation, yet it is still feasible for OOP.
No, hiding your fields behind accessors is not encapsulation. If the only thing you've done is write "private" in front of variables and then mindlessly provide get/set pair for each of them, then in fact they are not encapsulated. Someone in a distant place in code can still meddle with internals of your class, and can still depend on them (well, it is of course a bit better that they depend on a method, not on a field).
No, encapsulation's primary goal is not to avoid mistakes. Primary goals are at least similar to those listed above, and thinking that encapsulation will defend you from making mistakes is naive. There are just lots of other ways to make a mistake beside altering a private variable. And altering a private variable is not so hard to find and fix. Again - Python is a good example for sake of this argument, as it can have encapsulation without enforcing it.
Encapsulation prevents people who work on your code from making mistakes, by making sure that they only access things they're supposed to access.
At least in most OO languages, encapsulation is roughly equivalent to the lock on the door of a bathroom.
It's not intended to keep anybody out if they really insist on entering.
It is intended as a courtesy to let people know that entering will lead mostly to:
embarrassment, and
a stinking mess.
Encapsulation allows you to formalize your interfaces, separating levels of abstraction (i.e. "application logic accesses IO code only in this and this way").
This in turn, allows you to change the implementation of a module (the data and algorithms inside the module) without changing the interface (and affecting client code).
This ability to modify modules independently of each other, improves your ability to measure your performance and make predictions in a project's deadlines.
It also allows you to test modules separately and reuse them in other projects (because encapsulation also lowers inter-dependencies and improves modularity of your code).
Not enforcing encapsulation tends to lead to a project's failure (the problem grows with the complexity of the project).
I architected a fast-track project. Encapsulation reduces the propagation of change through the system. Changes cost time and money.
When code is not encapsulated, a person has to search many files to find where to make the change(s). Adversely, there is the question of "Did I find all the places?" and the other point "what effect to the entire system to do all of these scatter changes have?"
I'm working on an embedded medical device and quality is imperative. Also, all changes must be documented, reviewed, unit tested and finally a system test performed. By using encapsulation, we can reduce the number of changes and their locality, reducing the number of files that must be retested.

Maintainability in a class

How to ensure maintainability in a class? Can it simply be done by creating class using design patterns or is there something else involved? Also, what are the characteristics of a good method?
You won't do badly by following the SOLID and DRY principles.
SOLID is:
SRP Single responsibility principle
the notion that an object should have only a single responsibility.
OCP
Open/closed principle
the notion that “software entities … should be open for extension, but closed for modification”.
LSP
Liskov substitution principle
the notion that “objects in a program should be replaceable with instances of their subtypes without altering the correctness of that program”. See also design by contract.
ISP
Interface segregation principle
the notion that “many client specific interfaces are better than one general purpose interface.”[5]
DIP
Dependency inversion principle
the notion that one should “Depend upon Abstractions. Do not depend upon concretions.”[5]
Dependency injection is one method of following this principle.
And DRY stands for Don't Repeat Yourself, meaning you should strive to remove any duplication in your code.
Put in a lot of effort to make sure you have a good interface. Once you have that, you can completely rewrite the class, if you want, without affecting any other code in the project. If your class is so big that you can't easily rewrite it, then that is an issue too.
Although Oded's answer is good for ensuring the maintainability of a program or library, this question is about class maintainability and for that, there are only two requirements... a good interface, and strong cohesion.

OO & Application Objects [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
In OO apps, it's common to have an Application class which holds your top-level managers or whatever. This makes it hard to avoid having a theApp global object, or using a Singleton or something.
Does it matter? Should we seek to make this as OO as possible, or accept that OO principles break down sometimes?
Does it matter? Should we seek to make this as OO as possible, or accept that OO principles break down sometimes?
Sometimes OO theory meets the real world, and you should strive to make things work for your customers first and foremost. A singleton here or there is not a problem for your customer, or for maintainability.
OOP is mainly there to make code easier to maintain, reuse and understand. As long as those goals are met, there is no need to refactor for purity reasons only.
Having a global theApp object singleton doesn't necessarily violate OO principles, so long as data tied to it is properly encapsulated and whatnot.
There's also the situation that few OS's actually have an OO core, meaning that the Application Loader isn't Object Oriented to begin with.
In any case, absolutism on this point is dangerous; some programming languages have an (IMO) overly zealous approach to the whole thing, dictating every function be a method or the like, even when this doesn't make a lick of sense. (System.Math.sin(x), anyone?)
The most effective approach is usually mixing the two methodologies, using functions for functions, and methods for methods; and by extension, using Singletons for things that truly are singular; such as the application object or interfaces to some system services.
Edit: On System.Math.sin(x), it should be made clear that sin(x) is a function in quite literally every sense of the word, and putting it as a method on a singleton is wildly irresponsible, or at least a bit silly. In the comments a case could exist where another class wanted to use the name sin() for a method, but as methods and functions reside in separate namespaces in any case, this really isn't relevant.
I think the goal should be to design as well as possible. I don't want to have a mindset of seek "badges" or stamps of approval, so I'm not interested being as as "OO as possible", rather I seek to make concious trades-off. We favour concepts such as de-coupling and single-responsibility not because it's OO or because we can claim to be using a Design Pattern, but because we increase the ease of development, maintainability, testability and so on. We also favour simplicity because that too increases mainatainability and testability - the "You ain't gonna need it" principle leads us sometimes to leave things a little mre tightly coupled because we don't need flexibility right now.
So, to consider you example, there may well be a singleton in the sense that yes, there is only one of something (a thread pool or some such) but does the code using it need to know that it's a singleton? With a bit of care, use of factories or injection we can limit the knowledge of the n-gleton-ness.
There is no breakdown of OO by having a "theApp" object.