How abstraction and encapsulation differ? - c#

I am preparing for an interview and decided to brush up my OOP concepts.
There are hundreds of articles available, but it seems each describes them differently.
Some says
Abstraction is "the process of identifying common patterns that have
systematic variations; an abstraction represents the common pattern
and provides a means for specifying which variation to use" (Richard
Gabriel).
and is achieved through abstract classes.
Some other says
Abstraction means to show only the necessary details to the client of
the object
and
Let’s say you have a method "CalculateSalary" in your Employee class,
which takes EmployeeId as parameter and returns the salary of the
employee for the current month as an integer value. Now if someone
wants to use that method. He does not need to care about how Employee
object calculates the salary? An only thing he needs to be concern is
name of the method, its input parameters and format of resulting
member,
I googled again and again and none of the results seem to give me a proper answer.
Now, where does encapsulation fit in all these?
I searched and found a stack overflow question. Even the answers to that questions were confusing
Here, it says
Encapsulation is a strategy used as part of abstraction. Encapsulation
refers to the state of objects - objects encapsulate their state and
hide it from the outside; outside users of the class interact with it
through its methods, but cannot access the classes state directly. So
the class abstracts away the implementation details related to its
state.
And here another reputed member says,
They are different concepts.
Abstraction is the process of refining away all the
unneeded/unimportant attributes of an object and keep only the
characteristics best suitable for your domain.
Now I m messed up with the whole concept. I know about abstract class, inheritance, access specifiers and all. I just want to know how should I answer when I am asked about abstraction and/or encapsulation in an interview.
Please don't mark it as a duplicate. I know there are several similar questions. But I want to avoid the confusion among the conflicting explanations. Can anyone suggest a credible link? A link to stackoverflow question is also welcome unless it creates confusion again. :)
EDIT: I need answers, a bit c# oriented

Encapsulation: hiding data using getters and setters etc.
Abstraction: hiding implementation using abstract classes and interfaces etc.

Abstraction means to show only the necessary details to the client of the object
Actually that is encapsulation. also see the first part of the wikipedia article in order to not be confused by encapsulation and data hiding. http://en.wikipedia.org/wiki/Encapsulation_(object-oriented_programming)
keep in mind that by simply hiding all you class members 1:1 behind properties is not encapsulation at all. encapsulation is all about protecting invariants and hiding of implementation details.
here a good article about that.
http://blog.ploeh.dk/2012/11/27/Encapsulationofproperties/
also take a look at the articles linked in that article.
classes, properties and access modifiers are tools to provide encapsulation in c#.
you do encapsulation in order to reduce complexity.
Abstraction is "the process of identifying common patterns that have systematic variations; an abstraction represents the common pattern and provides a means for specifying which variation to use" (Richard Gabriel).
Yes, that is a good definition for abstraction.
They are different concepts.
Abstraction is the process of refining away all the unneeded/unimportant attributes of an object and keep only the characteristics best suitable for your domain.
Yes, they are different concepts. keep in mind that abstraction is actually the opposite of making an object suitable for YOUR domain ONLY. it is in order to make the object suitable for the domain in general!
if you have a actual problem and provide a specific solution, you can use abstraction to formalize a more generic solution that can also solve more problems that have the same common pattern. that way you can increase the re-usability for your components or use components made by other programmers that are made for the same domain, or even for different domains.
good examples are classes provided by the .net framework, for example list or collection. these are very abstract classes that you can use almost everywhere and in a lot of domains. Imagine if .net only implemented a EmployeeList class and a CompanyList that could only hold a list of employees and companies with specific properties. such classes would be useless in a lot of cases. and what a pain would it be if you had to re-implement the whole functionality for a CarList for example. So the "List" is ABSTRACTED away from Employee, Company and Car. The List by itself is an abstract concept that can be implemented by its own class.
Interfaces, abstract classes or inheritance and polymorphism are tools to provide abstraction in c#.
you do abstraction in order to provide reusability.

Image source
Abstraction: is shown in the top left and the top right images of the cat. The surgeon and the old lady designed (or visualized) the animal differently. In the same way, you would put different features in the Cat class, depending upon the need of the application. Every cat has a liver, bladder, heart, and lung, but if you need your cat to 'purr' only, you will abstract your application's cat to the design on top-left rather than the top-right.
Encapsulation: is demonstrated by the cat standing on the table. That's what everyone outside the cat should see the cat as. They need not worry whether the actual implementation of the cat is the top-left one or the top-right one, or even a combination of both.
Another detailed answer here.

I will try to demonstrate Encapsulation and Abstraction in a simple way.. Lets see..
The wrapping up of data and functions into a single unit (called
class) is known as encapsulation. Encapsulation containing and hiding
information about an object, such as internal data structures and
code.
Encapsulation is -
Hiding Complexity,
Binding Data and Function together,
Making Complicated Method's Private,
Making Instance Variable's Private,
Hiding Unnecessary Data and Functions from End User.
Encapsulation implements Abstraction.
And Abstraction is -
Showing Whats Necessary,
Data needs to abstract from End User,
Lets see an example-
The below Image shows a GUI of "Customer Details to be ADD-ed into a Database".
By looking at the Image we can say that we need a Customer Class.
Step - 1: What does my Customer Class needs?
i.e.
2 variables to store Customer Code and Customer Name.
1 Function to Add the Customer Code and Customer Name into Database.
namespace CustomerContent
{
public class Customer
{
public string CustomerCode = "";
public string CustomerName = "";
public void ADD()
{
//my DB code will go here
}
Now only ADD method wont work here alone.
Step -2: How will the validation work, ADD Function act?
We will need Database Connection code and Validation Code (Extra Methods).
public bool Validate()
{
//Granular Customer Code and Name
return true;
}
public bool CreateDBObject()
{
//DB Connection Code
return true;
}
class Program
{
static void main(String[] args)
{
CustomerComponent.Customer obj = new CustomerComponent.Customer;
obj.CustomerCode = "s001";
obj.CustomerName = "Mac";
obj.Validate();
obj.CreateDBObject();
obj.ADD();
}
}
Now there is no need of showing the Extra Methods(Validate(); CreateDBObject() [Complicated and Extra method] ) to the End User.End user only needs to see and know about Customer Code, Customer Name and ADD button which will ADD the record.. End User doesn't care about HOW it will ADD the Data to Database?.
Step -3: Private the extra and complicated methods which doesn't involves End User's Interaction.
So making those Complicated and Extra method as Private instead Public(i.e Hiding those methods) and deleting the obj.Validate(); obj.CreateDBObject(); from main in class Program we achieve Encapsulation.
In other words Simplifying Interface to End User is Encapsulation.
So now the complete code looks like as below -
namespace CustomerContent
{
public class Customer
{
public string CustomerCode = "";
public string CustomerName = "";
public void ADD()
{
//my DB code will go here
}
private bool Validate()
{
//Granular Customer Code and Name
return true;
}
private bool CreateDBObject()
{
//DB Connection Code
return true;
}
class Program
{
static void main(String[] args)
{
CustomerComponent.Customer obj = new CustomerComponent.Customer;
obj.CustomerCode = "s001";
obj.CustomerName = "Mac";
obj.ADD();
}
}
Summary :
Step -1: What does my Customer Class needs? is Abstraction.
Step -3: Step -3: Private the extra and complicated methods which doesn't involves End User's Interaction is Encapsulation.
P.S. - The code above is hard and fast.
UPDATE:
There is an video on this link to explain the sample:
What is the difference between Abstraction and Encapsulation

Below is a semester long course distilled in a few paragraphs.
Object-Oriented Analysis and Design (OOAD) is actually based on not just two but four principles. They are:
Abstraction: means that you only incorporate those features of an entity which are required in your application. So, if every bank account has an opening date but your application doesn't need to know an account's opening date, then you simply don't add the OpeningDate field in your Object-Oriented Design (of the BankAccount class). †Abstraction in OOAD has nothing to do with abstract classes in OOP.
Per the principle of Abstraction, your entities are an abstraction of what they are in the real world. This way, you design an abstraction of Bank Account down to only that level of detail that is needed by your application.
Inheritance: is more of a coding-trick than an actual principle. It saves you from re-writing those functionalities that you have written somewhere else. However, the thinking is that there must be a relation between the new code you are writing and the old code you are wanting to re-use. Otherwise, nobody prevents you from writing an Animal class which is inheriting from BankAccount, even if it is totally non-sensical.
Just like you may inherit your parents' wealth, you may inherit fields and methods from your parent class. So, taking everything that parent class has and then adding something more if need be, is inheritance. Don't go looking for inheritance in your Object Oriented Design. Inheritance will naturally present itself.
Polymorphism: is a consequence of inheritance. Inheriting a method from the parent is useful, but being able to modify a method if the situation demands, is polymorphism. You may implement a method in the subclass with exactly the same signature as in parent class so that when called, the method from child class is executed. This is the principle of Polymorphism.
Encapsulation: implies bundling the related functionality together and giving access to only the needful. Encapsulation is the basis of meaningful class designing in Object Oriented Design, by:
putting related data and methods together; and,
exposing only the pieces of data and methods relevant for functioning with external entities.
Another simplified answer is here.
† People who argue that "Abstraction of OOAD results in the abstract keyword of OOP"... Well that is incorrect.
Example: When you design a University in an application using object oriented principles, you only design an "abstraction" of the university. Even though there is usually one cash dispensing ATM in almost every university, you may not incorporate that fact if it's not needed for your application. And now though you have designed only an abstraction of the university, you are not required to put abstract in your class declaration. Your abstract design of university will be a normal class in your application.

I think they are slightly different concepts, but often they are applied together. Encapsulation is a technique for hiding implementation details from the caller, whereas abstraction is more a design philosophy involving creating objects that are analogous to familiar objects/processes, to aid understanding. Encapsulation is just one of many techniques that can be used to create an abstraction.
For example, take "windows". They are not really windows in the traditional sense, they are just graphical squares on the screen. But it's useful to think of them as windows. That's an abstraction.
If the "windows API" hides the details of how the text or graphics is physically rendered within the boundaries of a window, that's encapsulation.

my 2c
the purpose of encapsulation is to hide implementation details from the user of your class e.g. if you internally keep a std::list of items in your class and then decide that a std::vector would be more effective you can change this without the user caring. That said, the way you interact with the either stl container is thanks to abstraction, both the list and the vector can for instance be traversed in the same way using similar methods (iterators).

One example has always been brought up to me in the context of abstraction; the automatic vs. manual transmission on cars. The manual transmission hides some of the workings of changing gears, but you still have to clutch and shift as a driver. Automatic transmission encapsulates all the details of changing gears, i.e. hides it from you, and it is therefore a higher abstraction of the process of changing gears.

Encapsulation: Hiding implementation details (NOTE: data AND/OR methods) such that only what is sensibly readable/writable/usable by externals is accessible to them, everything else is "untouchable" directly.
Abstraction: This sometimes refers specifically to a type that cannot be instantiated and which provides a template for other types that can be, usually via subclassing. More generally "abstraction" refers to making/having something that is less detailed, less specific, less granular.
There is some similarity, overlap between the concepts but the best way to remember it is like this: Encapsulation is more about hiding the details, whereas abstraction is more about generalizing the details.

Abstraction and Encapsulation are confusing terms and dependent on each other.
Let's take it by an example:
public class Person
{
private int Id { get; set; }
private string Name { get; set; }
private string CustomName()
{
return "Name:- " + Name + " and Id is:- " + Id;
}
}
When you created Person class, you did encapsulation by writing properties and functions together(Id, Name, CustomName). You perform abstraction when you expose this class to client as
Person p = new Person();
p.CustomName();
Your client doesn't know anything about Id and Name in this function.
Now if, your client wants to know the last name as well without disturbing the function call. You do encapsulation by adding one more property into Person class like this.
public class Person
{
private int Id { get; set; }
private string Name { get; set; }
private string LastName {get; set;}
public string CustomName()
{
return "Name:- " + Name + " and Id is:- " + Id + "last name:- " + LastName;
}
}
Look, even after addding an extra property in class, your client doesn't know what you did to your code. This is where you did abstraction.

As I knowit, encapsulation is hiding data of classes in themselves, and only making it accessible via setters / getters, if they must be accessed from the outer world.
Abstraction is the class design for itself.
Means, how You create Your class tree, which methods are general ones, which are inherited, which can be overridden,which attributes are only on private level, or on protected, how Do You build up Your class inheritance tree, Do You use final classes, abtract classes, interface-implementation.
Abstraction is more placed the oo-design phase, while encapsulation also enrolls into developmnent-phase.

I think of it this way, encapsulation is hiding the way something gets done. This can be one or many actions.
Abstraction is related to "why" I am encapsulating it the first place.
I am basically telling the client "You don't need to know much about how I process the payment and calculate shipping, etc. I just want you to tell me you want to 'Checkout' and I will take care of the details for you."
This way I have encapsulated the details by generalizing (abstracting) into the Checkout request.
I really think that abstracting and encapsulation go together.

Abstraction
In Java, abstraction means hiding the information to the real world. It establishes the contract between the party to tell about “what should we do to make use of the service”.
Example, In API development, only abstracted information of the service has been revealed to the world rather the actual implementation. Interface in java can help achieve this concept very well.
Interface provides contract between the parties, example, producer and consumer. Producer produces the goods without letting know the consumer how the product is being made. But, through interface, Producer let all consumer know what product can buy. With the help of abstraction, producer can markets the product to their consumers.
Encapsulation:
Encapsulation is one level down of abstraction. Same product company try shielding information from each other production group. Example, if a company produce wine and chocolate, encapsulation helps shielding information how each product Is being made from each other.
If I have individual package one for wine and another one for
chocolate, and if all the classes are declared in the package as
default access modifier, we are giving package level encapsulation
for all classes.
Within a package, if we declare each class filed (member field) as
private and having a public method to access those fields, this way
giving class level encapsulation to those fields

Let's go back 6 million years,
Humans are not fully evolved. To begin with, evolution created a hole next to each body part to inject nutrients, which you can decide on yourself.
However, as humans get older, the nutrient requirements for each body part change Humans don't know which body parts need how much of which nutrient.
Evolution realised that exposing the hole next to each body part was a mistake, so it corrected it by encapsulating the entire body in skin and exposing only one opening, later it was called as "mouth." 
Also, it abstracted the whole implementation of nutrient allocation through digestive system. All you have to do is keep eating through your mouth. The digestive system will take care of the body's nutrient composition changes to meet your needs. 
In the software world, requirements will keep changing.
Encapsulating the internal data and exposing only the required functions will help with better maintenance. As a result, you have greater control over what occurs within your class/module/framework. 
Abstraction makes it easier for the client to consume a class/module/framework. So clients don't have to do(know) 100 different steps to get the desired output. Exposed function/class will do all the work. In our example, you don't have to worry about which nutrients are required for which body part. Just eat it. 

Related

How to separate/decouple instance creation of children when creating core model in DDD

A course can have multiple activities, i.e. Training, Exam, Project, Book, Article, and Task.
Following are the requirements:
Allow the teacher to schedule a course.
Allow the teacher to schedule different activities in the said course.
Display list of activities to the student for a selected course, in a specified date range.
The above requirements lead me to create two aggregates.
CourseAggregate
ActivityAggregate
Why?
A course can be created without any activities, but only in draft state. A course can be scheduled on for a different set of students.
An activity can be created independent of course, and later on, linked to a course.
Activities can be fetched with a date range only for a given student.
protected abstract class Activity
{
public Guid Id {get; private set;}
}
protected class Training : Activity
{
..... Addiontal properties
}
protected class Exam : Activity
{
....Addiontal properties and behavior.
public bool AllowGrading => true;
}
.... Other childern of activity..hence more classes.
Questions:
Is it the right approach to go with inheritance?
Since I marked the constructor protected, so the client code will not use the new operator, and will not have direct knowledge of children. I am struggling to figure out how the client should create an instance of the activity. For example:
[Test]
public void ActivityFactoryShouldCreateCorrectActivityType(){
var activity= ActivityFactory.CreateActivity(activityType:"Training", title:"Training", DueDate: "date".......)
}
Problem is, each subtype might want to enforce different invariants for the entity to be correctly created. For example, Exam activity requires information about the scale of grading.
How to solve correctly implement it or which pattern suits better here?
That is one of the problem that frquently pops up when using a language like C# or Java. That is an implementational problem more than it is modeling issue.
The thing is that you do have these concepts: Exam, Training etc. that are concrete. On the other hand you can derive a common concept for them: Activity.
Here are couple of questions that we need to ask before we consider an implementation.
What it needs to do with these concepts?
How does it works with them?
How many parts of the system are interested in the concrete concepts Exam, Training etc. and how many of it is interested in the common concept of Activity?
Do you expect to add many more concepts that will be Activities? This will affect how you evolve your system.
Let's say that your system doesn't use the concept of Activity much and it wont have many more activities added. In this case we can just ignore Activity and just use concrete concepts. This say there is no problem in creating them.
Let's say that your system will use the concept of Activity and you need to add more types of activities.
This doesn't undermine the fact that your system will know of the different concrete types of activities. It will create them, work with them etc. Even when your system is working with the concept of activity it will probably still need to know the concrete type of the activity so it can do something with it.
This kind of logic shows a problem with the way that we think when we use an OOP language like C# of Java. We are trained as developers. usually people say that casting is bad. You sould somehow define a base class or an interface and let subclasses of interface implementers define a behavior and the other parts of the system shouldn't know the concrete type.
And this it true for some parts of the system and for come concepts. Take for example a Serializer. You can define an interface ISerializer with a method Serialize. The system that uses a serializer may use the interface without having to know the concrete type as each class that implements the ISerializer interface will add a different implementation of the same interface.
Not every problem is like that. Sometimes your system needs to know what it deals with. This is where i thing we can learn something from languages like JavaScript. There what you have is an object that is non specific and use can just attach properties to it. The object is what it's properties define it to be.
The concept of Duck Typing is interesting: "If it walks like a duck and it quacks like a duck, then it must be a duck"
If you system needs to work with Exam it should work with it not with an Activity. If it has an Activity it should be able to figure out it it's indeed an Exam because this is that it needs.
Now we live in the strong typed world and it has it's good parts. I love strong typing and what it gives you, but also some problems are more difficult to deal with.
You can use classes with inheritance to implement this. You also use interfaces instead of having classes to capture different concepts. Yet your system will need to do some casting to determine the concrete type of what is working with. We can make it's life a bit easier if we capture the fact that we have different types of Activities explicitly
Here's an example:
public enum ActivityType { Exam, Trainig, Project, Task }
public class Activity {
public Guid ID { get; private set; }
public abstract ActivityType Type { get; }
// other stuff
}
public class Exam : Activity {
public override ActivityType Type {
get { return ActivityType.Exam; }
}
// other stuff
}
public class SomeClass {
public void SomeAction(Activity activity) {
if(activity.Type == ActivityType.Exam) {
var examActivity = (Exam)activity;
// do something with examActivity
}
}
}
If creating your activities have some logic related to them you can use a Factory to create them by using their concrete types.
public class ExamFactory {
public Exam CreateSummerExam(string name, //other stuff) {
// Enfore constraints
return new Exam(new Guid(), name,....);
}
}
Or add a Factory to the concrete type:
public class Exam : Activity {
public static Exam CreateSummerExam() {
// Enfore constraints
return new Exam();
}
private Exam() { }
}
Or just use a public constructor if creating these objects is not complex.
If you realy want to hide the classes to allow yourself some freedom of implementation then use interfaces:
// **Domain.dll**
public enum ActivityType { Exam, Training }
public interface IActivity {
ActivityType Type { get; }
}
public interface IExam : IActivity { }
internal class Exam : IExam { }
public class ActivityFactory {
public IExam CreateExam() { return new Exam(); }
public ITraining CreateTraining() { return new Training(); }
// other concrete activities
}
This way you don't allow clien code to have access to classes. You can give them access to public interfaces and keep other implementation specific methods internal to your Domain.dll. Clients of these concepts can still use casting to use the appropriate type that they need, but this time they will use interfaces.
Here's a good article on this. In it Martin Fowler says:
With OO programs you try to avoid asking an object whether it is an
instance of a type. But sometimes that is legitamate information for a
client to use, perhaps for a GUI display. Remember that asking an
object if it is an instance of a type is something different than
asking it if it is an instance of a class, since the types
(interfaces) and the classes (implementations) can be different.
EDIT:
Another implementation of this is to treat an Activity as a container that you can attach different things to it. This will give you a more flexible system. Unfortunately this won't remove the need for switching and checking if various features are present in your entity. It's possible to some degree but depending on your concrete case you may need to process an Activity from some external component and will need to swith and check.
For example you may want to generate some report. You may need to get some activities, process them and then generate some report based on some data stored in them. This cannot happen with attaching components to one activity as this operation requires multiple activities not a single one.
There are a lot of systems that do this kind of thing. Here are some examples:
Computer Games use something that is called Entity Component System.These systems are data oriented where an Entity is comprised of different Components. Each system then checks to see if a Component is attached to an Entity. For example you have a Rendering system that renders your scene with all players and stuff. This system will check if an entity has attached 3D model component. If it has it will render it.
The same approach is used in Flow Based Programming. It is also data driven where you send Information Packets that are composed of different properties. These properties can be simple or complex. Then you have Processes that are connected and pass data between each other. Each Process will search for specific type of data in a IP to check if it's supported by it.
Unity also supports using Entity Component System. But it also supports another similar approach to having active components that contain behavior and logic instead of passive data that is processed from external systems.
Feature based programming. Uses the notion of features that you can add to an object. It's used in CAD/CAM system, banking systems and many more
It's a good approach to use when having dynamic data that needs to be processed. Unfortunately this won't remove the need to do some if/else and swich. As already mentioned, when you need to process collections of Activities you will need to do some checking.
Note that the systems above don't try to avoid this. On the contrary. They embrace this fact and use dynamic data. It's no different then having a type fo the activities and switching on it. It's just that their approach give a more flexible system at the expence of doing a lot of checks.
If you system doesn't require that kind of dynamic data you can just use concrete classes instead of data objects that can store unlimited number of things. This will simplify some parts of your application. If you do need to compose different objects then you can use one of the approaches above.
Thank for taking the time to answer the question in detail & with beautiful insights.
Consider we are developing https://coursera.org site. There are two major high-level goals which system has to achieve.
- Teacher/Course Creator should be able to create (schedule) a Course. From creator point of view, he/she want to add Exam, training or other activities to course. But he/she will refer to it as "I am scheduling an exam activity in this course for the following dates, with the following criteria of fail/pass" or "I am scheduling a training activity, in this course." Now, if we go with IActivity interface approach along with ActvityType Enum, all the client code, will be using switch or if/else to see what type of activity it is, and this will flow to top-level i.e. UI, or even controllers or consumer classes,
if(activity.type==exam){ ((Exam)IActivity).DoSomething();}
But this looks acceptable given there is no good alternative, but it really clutters your code.
- From a student perspective, he/she is only interested in the following
-- show me the list of all activities I have to perform, but tell me what type of activities they are
-- Once I attempt/do an activity, he/she expect different behavior as well, for example, Training does not have any grading attached to it, while exam does.
--- Exam is allowed to take only once.
--- Summary Exam grading is different than Full Exam.
--- Summary Exam Allow Late Submission while Exam does not have that feature at all.
Now again in order to call the correct behavior of IActivity, enum is helpful but it is cluttering the code base at all levels, where the decision has to be made. And IActivity does not know about the behavior Exam at all, and exam can be of multiple types, thus adding to the complexity so another enum to see what kind of exam it is since Summary Exam and Full Exam only differs in grading behavior, and everything else is same. Now with this, another switch statement or if/else on all consumer classes.
* Factories will help with this, but I am worried it will become too complex, having different methods in factories, since Exam can be in a valid state (draft) with a different combination of properties.
So the system is interested both in Activity and concrete types i.e. Exam, Training, etc but in different scope.
** Additional complexity, what if the teacher wants to create a new type of activity which is saying "Its Path activity, the exam is only available when the student takes this training." Now, the student is still interested to see a list of all activities, just want to know the type of it (as a label).
Lately, I have been thinking about composition instead of inheritance, where there is only one type, Activity, and it has a set of a feature collection. Each feature contains its own behavior in its own class. Have not done it before, not sure if this sort of approach exists or even beneficial.
Thanks again for the detailed answer again, would love to hear your thoughts.

How do I deal with two situations that could be candidates for a strategy pattern solution?

I am designing a client that will call methods based on certain inputs. I will be sending in a billing system enum and calling an endpoint to determine which billing system is appropriate for an existing patient. Once I get the billing system, I have to check to see what type of operation I need to perform and make an API call based on the billing system.
For example, if I need to update a patient record and the patient is in BillingSystemA, I need to call a PUT-based method of the API for BillingSystemA.
I need to have CRUD methods for each billing system.
Selecting between the two billing systems and allowing for future growth made me think that the strategy pattern was a good fit. Strategy seems to work for the billing system, but what about the CRUD operations?
I have a BillingStrategy abstract class that has Create, Update, Get and Delete methods, but I need those methods to work against a variety of types. Can I just make the methods generic, like T Create<T> or bool Update<T> or do I need a strategy within a strategy to manage this? I've analyzed myself into a corner and could use some advice.
Here's a rough illustration. I invented a lot of the specifics, and the names aren't so great. I tend to revisit names as I refactor. The main point is to illustrate how we can break up the problem into pieces.
This assumes that there are classes for Patientand Treatment and an enum for InsuranceType. The goal is to bill a patient for a treatment, and determine where to send the bill based on the patient's insurance.
Here's a class:
public class PatientBilling
{
private readonly IBillingHandlerByInsuranceSelector _billingHandlerSelector;
private readonly IBillingHandler _directPatientBilling;
public PatientBilling(
IBillingHandlerByInsuranceSelector billingHandlerSelector,
IBillingHandler directPatientBilling)
{
_billingHandlerSelector = billingHandlerSelector;
_directPatientBilling = directPatientBilling;
}
public void BillPatientForTreatment(Patient patient, Treatment treatment)
{
var billingHandler = _billingHandlerSelector.GetBillingHandler(patient.Insurance);
var result = billingHandler.BillSomeone(patient, treatment);
if (!result.Accepted)
{
_directPatientBilling.BillSomeone(patient, treatment);
}
}
}
and a few interfaces:
public interface IBillingHandler
{
BillSomeoneResult BillSomeone(Patient patient, Treatment treatment);
}
public interface IBillingHandlerByInsuranceSelector
{
IBillingHandler GetBillingHandler(InsuranceType insurance);
}
As you can see this will rely heavily on dependency injection. This class is simple because it doesn't know anything at all about the different insurance types.
All it does is
Select a billing handler based on the insurance type
try to submit the bill to the insurance
if it's rejected, bill the patient
It doesn't know or care how any of that billing is implemented. It could be a database call, an API call, or anything else. That makes this class very easy to read and test. We've deferred whatever isn't related to this class. That's going to make it easier to solve future problems one at a time.
The implementation of IBillingHandlerByInsuranceSelector can be an abstract factory that will create and return the correct implementation of IBillingHandler according to the patient's insurance. (I'm glossing over that but there's plenty of information on how to create abstract factories with dependency injection containers.)
In a sense we could say that the first part of this problem is solved (although we're likely to refactor some more.) The reason why is that we can write unit tests for it, and any of the work specific to one insurance type or another will be in different classes.
Next we can write those insurance-specific implementations. Suppose one of the insurance types is WhyCo, and now we need to create an IBillingHandler for them. We're essentially going to repeat the same process.
For the sake of illustration, let's say that submitting a bill to WhyCo is done in two steps. First we have to make a request to check eligibility, and then we have to submit the bill. Maybe other insurance APIs do this in one step. That's okay, because no two implementations have to have anything in common with each other. They just implement the interface.
At this point we're dealing with the specifics of one particular insurance company, so somewhere in here we'll need to convert our Patient and Treatment information into whatever data they expect to receive.
public class WhyCoBillingHandler : IBillingHandler
{
private readonly IWhyCoService _whyCoService;
public WhyCoBillingHandler(IWhyCoService whyCoService)
{
_whyCoService = whyCoService;
}
public BillSomeoneResult BillSomeone(Patient patient, Treatment treatment)
{
// populate this from the patient and treatment
WhyCoEligibilityRequest eligibilityRequest = ...;
var elibility = _whyCoService.CheckEligibility(eligibilityRequest);
if(!elibility.IsEligible)
return new BillSomeoneResult(false, elibility.Reason);
// create the bill
WhyCoBillSubmission bill = ...;
_whyCoService.SubmitBill(bill);
return new BillSomeoneResult(true);
}
}
public interface IWhyCoService
{
WhyCoEligibilityResponse CheckEligibility(WhyCoEligibilityRequest request);
void SubmitBill(WhyCoBillSubmission bill);
}
At this point we still haven't written any code that talks to the WhyCo API. That makes WhyCoBillingHandler easy to unit test. Now we can write an implementation of IWhyCoService that calls the actual API. We can write unit tests for WhyCoBillingHandler and integration tests for the implementation of IWhyCoService.
(Perhaps it would have been better if translating our Patient and Treatment data into what they expect happened even closer to the concrete implementation.)
At each step we're writing pieces of the code, testing them, and deferring parts for later. The API class might be the last step in implementing WhyCo billing. Then we can move on to the next insurance company.
At each step we also decide how much should go into each class. Suppose we have to write a private method, and that method ends up being so complicated that it's bigger than the public method that calls it and it's hard to test. That might be where we replace that private method with another dependency (abstraction) that we inject into the class.
Or we might realize up front that some new functionality should be separated into its own class, and we can just start off with that.
The reason why I illustrated it this way is this:
I've analyzed myself into a corner
It's easy to become paralyzed when our code has to do so many things. This helps to avoid paralysis because it continually gives us a path forward. We write part of it to depend on abstractions, and then that part is done (sort of.) Then we implement those abstractions. The implementations require more abstractions, and we repeat (writing unit tests all the way in between.)
This doesn't enforce best practices and principles, but it gently guides us toward them. We're writing small, single-responsibility classes. They depend on abstractions. We're defining those abstractions (interfaces, in this case) from the perspective of the classes that need them, which leads to interface segregation. And each class is easy to unit test.
Some will point out that it's easy to get carried away with all the abstractions and create too many interfaces and too many layers of abstraction, and they are correct. But that's okay. At every single step we're likely to go a little off balance one way or the other.
As you can see, the problems that occur when we have to deal with the difference between billing systems becomes simpler. We just create every implementation differently.
Strategy seems to work for the billing system, but what about the CRUD operations?
The fact that they all have different CRUD operations is fine. We've made components similar where they need to be similar (the interfaces through which we interact with them) but the internal implementations can be as different as they need to be.
We've also sidestepped the question of which design patterns to use, except that IBillingHandlerByInsuranceSelector is an abstract factory. That's okay too, because we don't want to start off too focused on a design pattern. If this was a real application, I'd assume that a lot of what I'm doing will need to be refactored. Because the classes are small, unit tested, and depend on abstractions, it's easier to introduce design patterns when their use becomes obvious. When that happens we can likely isolate them to the classes that need them. Or, if we've just realized that we've gone in the wrong direction, it's still easier to refactor. Unless we can see the future that's certain to happen.
It's worth taking some time up front to understand the various implementation details to make sure that the way you have to work with them lines up with the code you're writing. (In other words, we still need to spend some time on design.) For example, if your billing providers don't give you immediate responses - you have to wait hours or days - then code that models it as an immediate response wouldn't make sense.
One more benefit is that this helps you to work in parallel with other developers. If you've determined that a given abstraction is a good start for your insurance companies and maybe you've written a few, then it's easy to hand off other ones to other developers. They don't have to think about the whole system. They can just write an implementation of an interface, creating whatever dependencies they need to.

Multiple Inheritance?

I have looked on line for information that would help me solve a design issue that is confusing me. I am new to complicated inheritance situations so my solution could actually just be rooted in a better design. But in trying to figure out what my design should be, I keep ending up thinking I really just need to inherit more than 1 base class.
My specific case involves Assets and different types of Assets.
Starting with the Asset...
Every PhysicalDevice is an Asset
Every VirtualDevice is an Asset
Every Server is an Asset
Every PhysicalServer would need to be both a PhysicalDevice and a Server
Every VirtualServer would need to be both a VirtualDevice and a Server
Every NetDevice is a PhysicalDevice
Every StorageArray is a PhysicalDevice
One solution I guess is to duplicate the Server code for both PhysicalServers, and VirtualServers however, I feel like this goes against what im trying to do, which is inherit.
They need to be separate classes because each of the types will have properties and methods. For instance, Server will have OSCaption, Memory, Procs, etc. PhysicalDevice will have things like Location, Serial, Vendor etc. And VirtualDevice will have a ParentDevice, State, VHDLocation etc.
If the inheritance is liner then i run into the problem of not being able to describe these types accurately.
Something that seems intriguing is Interfaces. It seems that i can define all base classes as interfaces and implement them in my main classes as needed. but, I am simply unsure of what the implications are if I were to do that.
for instance, something like... PhysicalServer : IAsset : IServer : IPhysical
I am in deep water so I’m really just looking for suggestions or guidance.
Interfaces are an appropriate way of ensuring contract integrity across types, but you may end up with duplicate code for each implementation.
Your scenario may lend itself better to composition than inheritance (or a combination thereof).
Example - Inheritance + Composition
public class PhysicalServer : Asset
{
public PhysicalInfo PhysicalProperties
{
get;
set;
}
}
public class VirtualServer : Asset
{
public VirtualInfo VirtualProperties
{
get;
set;
}
}
Example - Composition Only
public class VirtualServer
{
public VirtualInfo VirtualProperties
{
get;
set;
}
public AssetInfo AssetProperties
{
get;
set;
}
}
You could then add polymorphism/generics into the mix and create derivatives of types to represent more specific needs.
Example - Inheritance + Composition + Genericized Member that inherits from a common type
public class VirtualServer<TVirtualInfo> : Asset
where TVirtualInfo : VirtualDeviceInfo
{
public TVirtualInfo VirtualProperties
{
get;
set;
}
}
public class VirtualServerInfo : VirtualDeviceInfo
{
// properties which are specific to virtual servers, not just devices
}
There are countless ways that you could model this out, but armed with interfaces, composition, inheritance, and generics you can come up with an effective data model.
Use mixins.
You first decide which is the primary thing you want your object to be. In your case I think it should be server.
public class PhysicalServer : Server
Then you add interfaces for the other functionalities.
public class PhysicalServer : Server,IAsset,IVirtualDevice
And you add extension methods to the interfaces.
public static int WordCount(this IAsset asset)
{
//do something on the asset
}
Here's an article on mixins in case my answer is too simple: http://www.zorched.net/2008/01/03/implementing-mixins-with-c-extension-methods/
C# doesn't support multiple inheritance from classes (but does support multiple implementations of interfaces).
What you're asking for is not multiple inheritance. Multiple inheritance is where a single class has more than one base class. In your example each class inherits from one/zero other classes. Asset and Server being the ultimate base classes. So you have no problem doing that in c#, you can just define the functionality common in eg server and then do different things in VirtualDevice and PhysicalDevice.
However you will end up with a possibly complex class hierarchy and many people would advocate composition over inheritance. This is where you'd have interfaces defining behaviour and classes implement the interface to say that they do something but each class can implement the interface methods differently. So your example for the PhysicalServer interfaces may be encouraged.
To start with remember that inheritance is the obvious result of the kind of problem that you have mentioned. Every class does have more than one behavior and everyone falls into this trap. So chill. You are not the first nor the last.
You need to modify your thinking a bit to break away from the norm.
You need to look at it from the angle of what "changes" in future rather than look at a hierarchical kind of class diagram. A class diagram may not be hierarchical instead it needs to represent "what changes" and what "remains constant". From what I see, in future you may define a MobileDevice, VirtualMobileDevice.
In your current classes you seem to have properties like Vendor, Serial. These may be needed in MobileDevice too right ? So you need to modify your thinking to actually think of behaviors instead of classes that make hierarchical sense.
Rethink, you are going down the track of multiple inheritance, very dangerous and complex design. Its not the correctness of your thought process that is in question here. Its the question of you coding something and someone up ahead in the near future complicating it beyond repair.
No multiple inheritance in java is there for this one reason, to ensure that you dont think the hierarchical way.
Think "factories" (for creation), strategy (for common functionality/processing).
Edited :
Infact you should also consider creating layers in the form of library, so that there is complete abstraction and control on the main parts of your processing. What ever you intend to do with the Asset/Device class should be abstracted into a library, which can be protected by change.

Why aren't all fields/properties/methods public?

I know this may sound stupid, but i really want to know :)
im learning c# currently,
and as you know you need to set "object"(button,label,text,variable, etc.) public or whatever you like.
However, you still need to write a code like this:
// my point is you cant just type label1.text you need to type class.label1.text
// so there is no chance of getting bugged
//because there is label1 in each of forms/classes
class Classlol = new class();
classlol.label1.blabla
So what's the point of making it unreachable in other forms ? why every thing isnt public or its not public by default ?
Thanks.
Simply speaking, pretty much the same reason that you wear clothes. Not everything should be exposed to the public at all times. Selected things need to be public so that others can interact with them, but other things are private and should be kept internal to that class.
Although, I probably shouldn't have used the word internal there in that last sentence, because there's a third option: the internal access modifier. The name used in VB.NET (Friend) is probably clearer. This indicates that a piece of data should be visible to all of the other classes within a single assembly, but hidden from outside. A similar analogy applies: there are things that you might share with your closest friends, but still don't want to be public.
There are other more complicated reasons, like to enable information hiding, to maximize the separation between a particular class and the rest of an application, and to maintain a consistent public interface even though implementation details may have been changed between versions, all of which contribute to good object-oriented design. If you really want to understand the nitty-gritty, I suggest picking up a good book on object-oriented programming. It's very difficult, if not impossible, to master an object-oriented language like C# without a solid understanding of the fundamentals.
Things aren't public by default because they might contain sensitive information, or at least information that you don't want to expose as part of the class's public interface. Making something public is a bigger decision with more risks than simply making it private, so you are forced to make that decision explicitly.
The point of using classes is to be able to separate your code into logically related pieces. This makes your code easier to understand and maintain.
For example, if you need to modify code in a class, you can focus more on the way that class functions and less on other parts of your project. However, public members of your class limit this separation somewhat because, if you modify a public member, that can affect other parts of your project.
Keeping as much of your class private as possible (while still usable from your application) maximizes the separation between it and the rest of your application. It makes it easier to think about only the logic in the class you are working on, and it allows you to modify those private members without having to think what other parts of your application might be affected.
I suggest that you read more about abstraction in object oriented programming. Maybe the Wikipedia article on abstraction is a good place to start.
EDIT: Konrad is absolutely right, abstraction does not automatically imply "hiding" information. You could say that it's the role of encapsulation in object oriented programming.
I guess what I wanted to say is that this question is not specific to C#, but rather begs for a bit of reading on general object oriented programming principles.
The default access modifier is internal which means it's public inside the same assembly and private outside the assembly.
If you want to expose certain data as public, for example text of some Label, the best practice is creating public readonly property like this:
public string LabelText
{
get { return MyLabel.Text; }
}
To access it you'll have to use such code:
string text = classInstance.LabelText;
This way the Label itself is not public, but its text can be read by everyone.

Good Case For Interfaces

I work at a company where some require justification for the use of an Interface in our code (Visual Studio C# 3.5).
I would like to ask for an Iron Clad reasoning that interfaces are required for. (My goal is to PROVE that interfaces are a normal part of programming.)
I don't need convincing, I just need a good argument to use in the convincing of others.
The kind of argument I am looking for is fact based, not comparison based (ie "because the .NET library uses them" is comparison based.)
The argument against them is thus: If a class is properly setup (with its public and private members) then an interface is just extra overhead because those that use the class are restricted to public members. If you need to have an interface that is implemented by more than 1 class then just setup inheritance/polymorphism.
Code decoupling. By programming to interfaces you decouple the code using the interface from the code implementing the interface. This allows you to change the implementation without having to refactor all of the code using it. This works in conjunction with inheritance/polymorphism, allowing you to use any of a number of possible implementations interchangeably.
Mocking and unit testing. Mocking frameworks are most easily used when the methods are virtual, which you get by default with interfaces. This is actually the biggest reason why I create interfaces.
Defining behavior that may apply to many different classes that allows them to be used interchangeably, even when there isn't a relationship (other than the defined behavior) between the classes. For example, a Horse and a Bicycle class may both have a Ride method. You can define an interface IRideable that defines the Ride behavior and any class that uses this behavior can use either a Horse or Bicycle object without forcing an unnatural inheritance between them.
The argument against them is thus: If
a class is properly setup (with its
public and private members) then an
interface is just extra overhead
because those that use the class are
restricted to public members. If you
need to have an interface that is
implemented by more than 1 class then
just setup inheritance/polymorphism.
Consider the following code:
interface ICrushable
{
void Crush();
}
public class Vehicle
{
}
public class Animal
{
}
public class Car : Vehicle, ICrushable
{
public void Crush()
{
Console.WriteLine( "Crrrrrassssh" );
}
}
public class Gorilla : Animal, ICrushable
{
public void Crush()
{
Console.WriteLine( "Sqqqquuuuish" );
}
}
Does it make any sense at all to establish a class hierarchy that relates Animals to Vehicles even though both can be crushed by my giant crushing machine? No.
In addition to things explained in other answers, interfaces allow you simulate multiple inheritance in .NET which otherwise is not allowed.
Alas as someone said
Technology is dominated by two types of people: those who understand what they do not manage, and those who manage what they do not understand.
To enable unit testing of the class.
To track dependencies efficiently (if the interface isn't checked out and touched, only the semantics of the class can possibly have changed).
Because there is no runtime overhead.
To enable dependency injection.
...and perhaps because it's friggin' 2009, not the 70's, and modern language designers actually have a clue about what they are doing?
Not that interfaces should be thrown at every class interface: just those which are central to the system, and which are likely to experience significant change and/or extension.
Interfaces and abstract classes model different things. You derive from a class when you have an isA relationship so the base class models something concrete. You implement an interface when your class can perform a specific set of tasks.
Think of something that's Serializable, it doesn't really make sense (from a design/modelling point of view) to have a base class called Serializable as it doesn't make sense to say something isA Serializable. Having something implement a Serializable interface makes more sense as saying 'this is something the class can do, not what the class is'
Interfaces are not 'required for' at all, it's a design decision. I think you need to convince yourself, why, on a case-by-case basis, it is beneficial to use an interface, because there IS an overhead in adding an interface. On the other hand, to counter the argument against interfaces because you can 'simply' use inheritance: inheritance has its draw backs, one of them is that - at least in C# and Java - you can only use inheritance once(single inheritance); but the second - and maybe more important - is that, inheritance requires you to understand the workings of not only the parent class, but all of the ancestor classes, which makes extension harder but also more brittle, because a change in the parent class' implementation could easily break the subclasses. This is the crux of the "composition over inheritance" argument that the GOF book taught us.
You've been given a set of guidelines that your bosses have thought appropriate for your workplace and problem domain. So to be persuasive about changing those guidelines, it's not about proving that interfaces are a good thing in general, it's about proving that you need them in your workplace.
How do you prove that you need interfaces in the code you write in your workplace? By finding a place in your actual codebase (not in some code from somebody else's product, and certainly not in some toy example about Duck implementing the makeNoise method in IAnimal) where an interface-based solution is better than an inheritance-based solution. Show your bosses the problem you're facing, and ask whether it makes sense to modify the guidelines to accommodate situations like that. It's a teachable moment where everyone is looking at the same facts instead of hitting each other over the head with generalities and speculations.
The guideline seems to be driven by a concern about avoiding overengineering and premature generalisation. So if you make an argument along the lines of we should have an interface here just in case in future we have to..., it's well-intentioned, but for your bosses it sets off the same over-engineering alarm bells that motivated the guideline in the first place.
Wait until there's a good objective case for it, that goes both for the programming techniques you use in production code and for the things you start arguments with your managers about.
Test Driven Development
Unit Testing
Without interfaces producing decoupled code would be a pain. Best practice is to code against an interface rather than a concrete implementation. Interfaces seem rubbish at first but once you discover the benefits you'll always use them.
You can implement multiple interfaces. You cannot inherit from multiple classes.
..that's it. The points others are making about code decoupling and test-driven development don't get to the crux of the matter because you can do those things with abstract classes too.
Interfaces allow you to declare a concept that can be shared amongst many types (IEnumerable) while allowing each of those types to have its own inheritance hierarchy.
In this case, what we're saying is "this thing can be enumerated, but that is not its single defining characteristic".
Interfaces allow you to make the minimum amount of decisions necessary when defining the capabilities of the implementer. When you create a class instead of an interface, you have already declared that your concept is class-only and not usable for structs. You also make other decisions when declaring members in a class, such as visibility and virtuality.
For example, you can make an abstract class with all public abstract members, and that is pretty close to an interface, but you have declared that concept as overridable in all child classes, whereas you wouldn't have to have made that decision if you used an interface.
They also make unit testing easier, but I don't believe that is a strong argument, since you can build a system without unit tests (not recommended).
If your shop is performing automated testing, interfaces are a great boon to dependency injection and being able to test a unit of software in isolation.
The problem with the inheritance argument is that you'll either have a gigantic god class or a hierarchy so deep, it'll make your head spin. On top of that, you'll end up with methods on a class you don't need or don't make any sense.
I see a lot of "no multiple inheritance" and while that's true, it probably won't phase your team because you can have multiple levels of inheritance to get what they'd want.
An IDisposable implementation comes to mind. Your team would put a Dispose method on the Object class and let it propagate through the system whether or not it made sense for an object or not.
An interface declares a contract that any object implementing it will adhere to. This makes ensuring quality in code so much easier than trying to enforce written (not code) or verbal structure, the moment a class is decorated with the interface reference the requirements/contract is clear and the code won't compile till you've implemented that interface completely and type-safe.
There are many other great reasons for using Interfaces (listed here) but probably don't resonate with management quite as well as a good, old-fashioned 'quality' statement ;)
Well, my 1st reaction is that if you've to explain why you need interfaces, it's a uphill battle anyways :)
that being said, other than all the reasons mentioned above, interfaces are the only way for loosely coupled programming, n-tier architectures where you need to update/replace components on the fly etc. - in personal experience however that was too esoteric a concept for the head of architecture team with the result that we lived in dll hell - in the .net world no-less !
Please forgive me for the pseudo code in advance!
Read up on SOLID principles. There are a few reasons in the SOLID principles for using Interfaces. Interfaces allow you to decouple your dependancies on implementation. You can take this a step further by using a tool like StructureMap to really make the coupling melt away.
Where you might be used to
Widget widget1 = new Widget;
This specifically says that you want to create a new instance of Widget. However if you do this inside of a method of another object you are now saying that the other object is directly dependent on the use of Widget. So we could then say something like
public class AnotherObject
{
public void SomeMethod(Widget widget1)
{
//..do something with widget1
}
}
We are still tied to the use of Widget here. But at least this is more testable in that we can inject the implementation of Widget into SomeMethod. Now if we were to use an Interface instead we could further decouple things.
public class AnotherObject
{
public void SomeMethod(IWidget widget1)
{
//..do something with widget1
}
}
Notice that we are now not requiring a specific implementation of Widget but instead we are asking for anything that conforms to IWidget interface. This means that anything could be injected which means that in the day to day use of the code we could inject an actual implementation of Widget. But this also means that when we want to test this code we could inject a fake/mock/stub (depending on your understanding of these terms) and test our code.
But how can we take this further. With the use of StructureMap we can decouple this code even more. With the last code example our calling code my look something like this
public class AnotherObject
{
public void SomeMethod(IWidget widget1)
{
//..do something with widget1
}
}
public class CallingObject
{
public void AnotherMethod()
{
IWidget widget1 = new Widget();
new AnotherObject().SomeMethod(widget1);
}
}
As you can see in the above code we removed the dependency in the SomeMethod by passing in an object that conforms to IWidget. But in the CallingObject().AnotherMethod we still have the dependency. We can use StructureMap to remove this dependency too!
[PluginFamily("Default")]
public interface IAnotherObject
{
...
}
[PluginFamily("Default")]
public interface ICallingObject
{
...
}
[Pluggable("Default")]
public class AnotherObject : IAnotherObject
{
private IWidget _widget;
public AnotherObject(IWidget widget)
{
_widget = widget;
}
public void SomeMethod()
{
//..do something with _widget
}
}
[Pluggable("Default")]
public class CallingObject : ICallingObject
{
public void AnotherMethod()
{
ObjectFactory.GetInstance<IAnotherObject>().SomeMethod();
}
}
Notice that no where in the above code are we instantiating an actual implementation of AnotherObject. Because everything is wired for StructurMap we can allow StructureMap to pass in the appropriate implementations depending on when and where the code is ran. Now the code is truely flexible in that we can specify via configuration or programatically in a test which implementation we want to use. This configuration can be done on the fly or as part of a build process, etc. But it doesn't have to be hard wired anywhere.
Appologies as this doesn't answer your question regarding a case for Interfaces.
However I suggest getting the person in question to read..
Head First Design Patterns
-- Lee
I don't understand how its extra overhead.
Interfaces provide flexibility, manageable code, and reusability. Coding to an interface you don't need to worry about the concreted implementation code or logic of the certain class you are using. You just expect a result. Many class have different implementation for the same feature thing (StreamWriter,StringWriter,XmlWriter)..you do not need to worry about how they implement the writing, you just need to call it.

Categories