Related
In interviews I have been asked to explain the difference between abstraction and encapsulation. My answer has been along the lines of
Abstraction allows us to represent complex real world in simplest manner. It is the process of identifying the relevant qualities and behaviors an object should possess; in other words, to represent the necessary feature without representing the background details.
Encapsulation is a process of hiding all the internal details of an object from the outside real world. The word "encapsulation", is like "enclosing" into a "capsule". It restricts clients from seeing its internal view where the behavior of the abstraction is implemented.
I think with above answer the interviewer was convinced, but then I was asked, if the purpose of both is hiding, then why there is a need to use encapsulation. At that time I didn't have a good answer for this.
What should I have added to make my answer more complete?
Abstraction has to do with separating interface from implementation. (We don't care what it is, we care that it works a certain way.)
Encapsulation has to do with disallowing access to or knowledge of internal structures of an implementation. (We don't care or need to see how it works, only that it does.)
Some people do use encapsulation as a synonym for abstraction, which is (IMO) incorrect. It's possible that your interviewer thought this. If that is the case then you were each talking about two different things when you referred to "encapsulation."
It's worth noting that these concepts are represented differently in different programming languages. A few examples:
In Java and C#, interfaces (and, to some degree, abstract classes) provide abstraction, while access modifiers provide encapsulation.
It's mostly the same deal in C++, except that we don't have interfaces, we only have abstract classes.
In JavaScript, duck typing provides abstraction, and closure provides encapsulation. (Naming convention can also provide encapsulation, but this only works if all parties agree to follow it.)
Its Simple!
Take example of television - it is Encapsulation, because:
Television is loaded with different functionalies that i don't know because they are completely hidden.
Hidden things like music, video etc everything bundled in a capsule that what we call a TV
Now, Abstraction is When we know a little about something and which can help us to manipulate something for which we don't know how it works internally.
For eg:
A remote-control for TV is abstraction, because
With remote we know that pressing the number keys will change the channels. We are not aware as to what actually happens internally. We can manipulate the hidden thing but we don't know how it is being done internally.
Programmatically, when we can acess the hidden data somehow and know something.. is Abstraction .. And when we know nothing about the internals its Encapsulation.
Without remote we can't change anything on TV we have to see what it shows coz all controls are hidden.
Abstraction
Exposing the Entity instead of the details of the entity.
"Details are there, but we do not consider them. They are not required."
Example 1:
Various calculations:
Addition, Multiplication, Subtraction, Division, Square, Sin, Cos, Tan.
We do not show the details of how do we calculate the Sin, Cos or Tan. We just Show Calculator and it's various Methods which will be, and which needs to be used by the user.
Example 2:
Employee has:
First Name, Last Name, Middle Name. He can Login(), Logout(), DoWork().
Many processes might be happening for Logging employee In, such as connecting to database, sending Employee ID and Password, receiving reply from Database. Although above details are present, we will hide the details and expose only "Employee".
Encapsulation
Enclosing. Treating multiple characteristics/ functions as one unit instead of individuals.
So that outside world will refer to that unit instead of it's details directly.
"Details are there, we consider them, but do not show them, instead we show what you need to see."
Example 1:
Instead of calling it as Addition, Subtraction, Multiplication, Division, Now we will call it as a Calculator.
Example 2:
All characteristics and operations are now referred by the employee, such as "John". John Has name. John Can DoWork(). John can Login().
Hiding
Hiding the implemention from outside world.
So that outside world will not see what should not be seen.
"Details are there, we consider them, but we do not show them. You do not need to see them."
Example 1:
Your requirement: Addition, Substraction, Multiplication, Division. You will be able to see it and get the result.
You do not need to know where operands are getting stored. Its not your requirement.
Also, every instruction that I am executing, is also not your requirement.
Example 2:
John Would like to know his percentage of attendance. So GetAttendancePercentage() Will be called.
However, this method needs data saved in database. Hence it will call FetchDataFromDB(). FetchDataFromDB() is NOT required to be visible to outside world.
Hence we will hide it. However, John.GetAttendancePercentage() will be visible to outside world.
Abstraction, encapsulation and hiding complement each others.
Because we create level of abstraction over details, the details are encapsulated. And because they are enclosed, they are hidden.
Difference between Abstraction and Encapsulation :-
Abstraction
Abstraction solves the problem in the design level.
Abstraction is used for hiding the unwanted data and giving relevant data.
Abstraction lets you focus on what the object does instead of how it does it.
Abstraction- Outer layout, used in terms of design.
For Example:-
Outer Look of a Mobile Phone, like it has a display screen and keypad buttons to dial a number.
Encapsulation
Encapsulation solves the problem in the implementation level.
Encapsulation means hiding the code and data into a single unit to protect the data from outside world.
Encapsulation means hiding the internal details or mechanics of how an object does something.
Encapsulation- Inner layout, used in terms of implementation.
For Example:- Inner Implementation detail of a Mobile Phone, how keypad button and Display Screen are connect with each other using circuits.
Encapsulation
Encapsulation from what you have learnt googling around, is a concept of combining the related data and operations in a single capsule or what we could say a class in OOP, such that no other program can modify the data it holds or method implementation it has, at a particular instance of time. Only the getter and setter methods can provide access to the instance variables.
Our code might be used by others and future up-gradations or bug fixes are liable. Encapsulation is something that makes sure that whatever code changes we do in our code doesn't break the code of others who are using it.
Encapsulation adds up to the maintainability, flexibility and extensibility of the code.
Encapsulation helps hide the implementation behind an interface.
Abstraction
Abstraction is the process of actually hiding the implementation behind an interface. So we are just aware of the actual behavior but not how exactly the think works out internally. The most common example could the scenario where put a key inside the lock and easily unlock it. So the interface here is the keyhole, while we are not aware of how the levers inside the lock co-ordinate among themselves to get the lock unlocked.
To be more clear, abstraction can be explained as the capability to use the same interface for different objects. Different implementations of the same interface can exist, while the details of every implementation are hidden by encapsulation.
Finally, the statement to answer all the confusions until now -
The part that is hidden relates to encapsulation while the part that is exposed relates to abstraction.
Read more on this here
Abstraction : Abstraction is process in which you collect or gather relevant data and remove non-relevant data. (And if you have achieved abstraction, then encapsulation also achieved.)
Encapsulation: Encapsulation is a process in which you wrap of functions and members in a single unit. Means You are hiding the implementation detail. Means user can access by making object of class, he/she can't see detail.
Example:
public class Test
{
int t;
string s;
public void show()
{
s = "Testing";
Console.WriteLine(s);
Console.WriteLine(See()); // No error
}
int See()
{
t = 10;
return t;
}
public static void Main()
{
Test obj = new Test();
obj.Show(); // there is no error
obj.See(); // Error:- Inaccessible due to its protection level
}
}
In the above example, User can access only Show() method by using obj, that is Abstraction.
And See() method is calling internally in Show() method that is encapsulation, because user doesn't know what things are going on in Show() method.
I know there are lot's of answers before me with variety of examples.
Well here is my opinion abstraction is getting interested from reality .
In abstraction we hide something to reduce the complexity of it
and In encapsulation we hide something to protect the data.
So we define encapsulation as wrapping of data and methods in single entity referred as class.
In java we achieve encapsulation using getters and setters not just by wrapping data and methods in it. we also define a way to access that data.
and while accessing data we protect it also. Techinical e.g would be to define a private data variable call weight.Now we know that weight can't be zero or less than zero in real world scenario. Imagine if there are no getters and setters someone could have easily set it to a negative value being public member of class.
Now final difference using one real world example,
Consider a circuit board consisting of switches and buttons.
We wrap all the wires into a a circuit box, so that we can protect someone by not getting in contact directly(encapsulation).
We don't care how those wires are connected to each other we just want an interface to turn on and off switch. That interface is provided by buttons(abstraction)
Encapsulation : Suppose I have some confidential documents, now I hide these documents inside a locker so no one can gain access to them, this is encapsulation.
Abstraction : A huge incident took place which was summarised in the newspaper. Now the newspaper only listed the more important details of the actual incident, this is abstraction. Further the headline of the incident highlights on even more specific details in a single line, hence providing higher level of abstraction on the incident. Also highlights of a football/cricket match can be considered as abstraction of the entire match.
Hence encapsulation is hiding of data to protect its integrity and abstraction is highlighting more important details.
In programming terms we can see that a variable may be enclosed is the scope of a class as private hence preventing it from being accessed directly from outside, this is encapsulation. Whereas a a function may be written in a class to swap two numbers. Now the numbers may be swapped in either by either using a temporary variable or through bit manipulation or using arithmetic operation, but the goal of the user is to receive the numbers swapped irrespective of the method used for swapping, this is abstraction.
Abstraction: In case of an hardware abstraction layer, you have simple interfaces to trigger the hardware (e.g. turn enginge left/right) without knowing the hardware details behind. So hiding the complexity of the system. It's a simplified view of the real world.
Encapsulation: Hiding of object internals. The object is an abstraction of the real world. But the details of this object (like data structures...) can be hidden via encapsulation.
Abstraction refers to the act of representing essential features without including the background details or explanations.
Encapsulation is a technique used for hiding the properties and behaviors of an object and allowing outside access only as appropriate. It prevents other objects from directly altering or accessing the properties or methods of the encapsulated object.
Difference between abstraction and encapsulation
1.Abstraction focuses on the outside view of an object (i.e. the interface) Encapsulation (information hiding) prevents clients from seeing it’s inside view, where the behavior of the abstraction is implemented.
2.Abstraction solves the problem in the design side while Encapsulation is the Implementation.
3.Encapsulation is the deliverable of Abstraction. Encapsulation barely talks about grouping up your abstraction to suit the developer needs.
ABSTRACTION:"A view of a problem that extracts the essential information
relevant to a particular purpose and ignores the remainder of
the information."[IEEE, 1983]
ENCAPSULATION: "Encapsulation or equivalently information hiding refers to the
practice of including within an object everything it needs, and
furthermore doing this in such a way that no other object need ever
be aware of this internal structure."
Abstraction is one of the many benefits of Data Encapsulation. We can also say Data Encapsulation is one way to implement Abstraction.
My opinion of abstraction is not in the sense of hiding implementation or background details!
Abstraction gives us the benefit to deal with a representation of the real world which is easier to handle, has the ability to be reused, could be combined with other components of our more or less complex program package. So we have to find out how we pick a complete peace of the real world, which is complete enough to represent the sense of our algorithm and data. The implementation of the interface may hide the details but this is not part of the work we have to do for abstracting something.
For me most important thing for abstraction is:
reduction of complexity
reduction of size/quantity
splitting of non related domains to clear and independent components
All this has for me nothing to do with hiding background details!
If you think of sorting some data, abstraction can result in:
a sorting algorithm, which is independent of the data representation
a compare function, which is independent of data and sort algorithm
a generic data representation, which is independent of the used algorithms
All these has nothing to do with hiding information.
In my view encapsulation is a thought of programmer to hide the complexity of the program code by using access specifier.
Where as Abstraction is separation of method and object according to there function and behavior. For example Car has sheets, wheels, break, headlight.
Developer A, who is inherently utilising the concept of abstraction will use a module/library function/widget, concerned only with what it does (and what it will be used for) but not how it does it. The interface of that module/library function/widget (the 'levers' the Developer A is allowed to pull/push) is the personification of that abstraction.
Developer B, who is seeking to create such a module/function/widget will utilise the concept of encapsulation to ensure Developer A (and any other developer who uses the widget) can take advantage of the resulting abstraction. Developer B is most certainly concerned with how the widget does what it does.
TLDR;
Abstraction - I care about what something does, but not how it does it.
Encapsulation - I care about how something does what it does such that others only need to care about what it does.
(As a loose generalisation, to abstract something, you must encapsulate something else. And by encapsulating something, you have created an abstraction.)
Encapsulation is basically denying the access to the internal implementation or knowledge about internals to the external world, while Abstraction is giving a generalized view of any implementation that helps the external world to interact with it
The essential thing about abstraction is that client code operates in terms of a different logical/abstract model. That different model may be more or less complex than the implementation happens to be in any given client usage.
For example, "Iterator" abstracts (aka generalises) sequenced traversal of 0 or more values - in C++ it manifests as begin(), */-> (dereferencing), end(), pre/post ++ and possibly --, then there's +, +=, [], std::advance etc.. That's a lot of baggage if the client could say increment a size_t along an array anyway. The essential thing is that the abstraction allows client code that needs to perform such a traversal to be decoupled from the exact nature of the "container" or data source providing the elements. Iteration is a higher-level notion that sometimes restricts the way the traversal is performed (e.g. a forward iterator can only advance an element at a time), but the data can then be provided by a larger set of sources (e.g. from a keyboard where there's not even a "container" in the sense of concurrently stored values). The client code can generally switch to another data source abstracted through its own iterators with minimal or even no changes, and even polymorphically to other data types - either implicitly or explicitly using something like std::iterator_traits<Iterator>::value_type available.
This is quite a different thing from encapsulation, which is the practice of making some data or functions less accessible, such that you know they're only used indirectly as a result of operations on the public interface. Encapsulation is an essential tool for maintaining invariants on an object, which means things you want to keep true after every public operation - if client code could just reach in and modify your object then you can't enforce any invariants. For example, a class might wrap a string, ensuring that after any operation any lowercase letters were changed to upper case, but if the client code can reach in and put a lowercase letter into the string without the involvement of the class's member functions, then the invariant can't be enforced.
To further highlight the difference, consider say a private std::vector<Timing_Sample> data member that's incidentally populated by operations on the containing object, with a report dumped out on destruction. With the data and destructor side effect not interacting with the object's client code in any way, and the operations on the object not intentionally controlling the time-keeping behaviour, there's no abstraction of that time reporting functionality but there is encapsulation. An example of abstraction would be to move the timing code into a separate class that might encapsulate the vector (make it private) and just provide a interface like add(const Timing_Sample&) and report(std::ostream&) - the necessary logical/abstract operations involved with using such instrumentation, with the highly desirable side effect that the abstracted code will often be reusable for other client code with similar functional needs.
In my opinion, both terms are related in some sense and sort of mixed into each other. "Encapsulation" provides a way to grouping related fields, methods in a class (or module) to wrap the related things together. As of that time, it provides data hiding in two ways;
Through access modifiers.
Purely for hiding state of the class/object.
Abstracting some functionalities.
a. Through interfaces/abstract classes, complex logic inside the encapsulated class or module can be abstracted/generalized to be used by outside.
b. Through function signatures. Yes, even function signatures example of abstracting. Because callers only knows the signature and parameters (if any) and know nothing about how the function is carried out. It only cares of returned value.
Likewise, "Abstraction" might be think of a way of encapsulation in terms of grouping/wrapping the behaviour into an interface (or abstract class or might be even a normal class ).
As far as iOS is concerned, it can be said that Objective C files (i.e. .h and .m) use abstraction as well as encapsulation.
Abstraction
Header file (.h) only exposes the functions and public members to outside world. No one knows how they are used unless they have the implementation file with them. It is the .m file that holds all the usage and implementation logic with it self. "Implementation remains unexposed".
Encapsulation
The property (#property) encapsulates the memory management attribute (atomic, strong, retain, weak) of an iVar.
A program has mainly two parts : DATA and PROCESS. abstraction hides data in process so that no one can change. Encapsulation hides data everywhere so that it cannot be displayed.
I hope this clarifies your doubt.
Encapsulation is used for 2 main reasons:
1.) Data hiding & protecting (the user of your class can't modify the data except through your provided methods).
2.) Combining the data and methods used to manipulate the data together into one entity (capsule).
I think that the second reason is the answer your interviewer wanted to hear.
On the other hand, abstraction is needed to expose only the needed information to the user, and hiding unneeded details (for example, hiding the implementation of methods, so that the user is not affected if the implementation is changed).
Abstraction: Hiding the data.
Encapsulation: Binding the data.
Why Encapsulation? Why Abstraction?
lets start with the question below:
1)What happens if we allow code to directly access field ? (directly allowing means making field public)
lets understand this with an example,
following is our BankAccount class and following is its limitation
*Limitation/Policy* : Balance in BankAccount can not be more than 50000Rs. (This line
is very important to understand)
class BankAccount
{
**public** double balanceAmount;
}
Following is **AccountHolder**(user of BankAccount) class which is consumer of
**BankAccount** class.
class AccountHolder
{
BankAccount mybankAccount = new BankAccount();
DoAmountCreditInBankAccount()
{
mybankAccount.balanceAmount = 70000;
/*
this is invalid practice because this statement violates policy....Here
BankAccount class is not able to protect its field from direct access
Reason for direct access by acount holder is that balanceAmount directly
accessible due to its public access modifier. How to solve this issue and
successfully implement BankAccount Policy/Limitation.
*/
}
}
if some other part of code directly access balanceAmount field and set balance amount to 70000Rs which is not acceptable. Here in this case we can not prevent some other part of code from accessing balanceAmount field.
So what we can do?
=> Answer is we can make balanceAmount field private so that no other code can directly access it and allowing access to that field only via public method which operates on balanceAmount field. Main role of method is that we can write some prevention logic inside method so that field can not be initialized with more than 50000Rs. Here we are making binding between data field called balanceAmount and method which operates on that field. This process is called Encapsulation.(it is all about protecting fields using access modifier such as private)
Encapsulation is one way to achieve abstraction....but How?
=> User of this method will not know about implementation (How amount gets credited? logic and all that stuff) of method which he/she will invoke. Not knowing about implementation details by user is called Abstraction(Hiding details from user).
Following will be the implementation of class:
class BankAccount
{
**private** double balanceAmount;
**public** void UpdateBankBalance(double amount)
{
if(balanceAmount + amount > 50000)
{
Console.WriteLine("Bank balance can not be more than 50000, Transaction can
not be proceed");
}
else
{
balanceAmount = balanceAmount + amount;
Console.WriteLine("Amount has been credited to your bank account
successfully.....");
}
}
}
class AccountHolder
{
BankAccount mybankAccount = new BankAccount();
DoAmountCreditInBankAccount()
{
mybankAccount.UpdateBankBalance(some_amount);
/*
mybankAccount.balanceAmount will not be accessible due to its protection level
directly from AccountHolder so account holder will consume BankAccount public
method UpdateBankBalance(double amount) to update his/her balance.
*/
}
}
Simply put, abstraction is all about making necessary information for interaction with the object visible, while encapsulation enables a developer to implement the desired level of abstraction.
Encapsulation: Hiding the information at the implementation level. This deals with properties or methods which will be hidden from other objects.
Abstraction: Hiding the information at the idea level/design level. Here we decide that something will be abstract(hidden) from the user while thinking of an idea. Abstraction can be achieved using encapsulation at the implementation level.
Let's say that I have a method with the signature:
public static bool ValidDateToSend(DateTime date, string frequency)
Inside of the method is a switch on frequency.
Would changing the frequency from a string to a public enum, be considered a refactor, or is that going too far? Since this is a public method, there could potentially be many references outside of this code. The strict definition of refactoring (and what I believe is meant by fearless refactoring) is
disciplined technique for restructuring an existing body of code,
altering its internal structure without changing its external behavior
It seems to me that changing a method parameter to using a non-compatible type would indeed constitute "changing its external behavior".
The "external behavior" is the behavior of the system itself in terms of inputs and outputs. Modifying a signature is definitely a refactoring, although performing it safely may be difficult. The only exception to this is when your product is an API, in which case modifying a signature would affect customers and would not be just a refactoring.
Changing its external behavior to me indicates that what the user of the code sees changes. If the method itself is included in some kind of code library, this may be considered changing it's external behavior. If the method is being used only internally and all references to the method change, the external behavior isn't changing, and so according to the definition you list, it is refactoring. If it's in a code library, it could be considered an enhancement. It may still be considered refactoring if you consider that users of the code library will have to refactor their code to use it and the end users of their code will see no difference.
One of the big uses of code generation in c++ is to support message serialisation. Typically, you want to support specifying message contents and layout in the same step and produce code for that message type that can give you objects capable of being serialised to/from communication streams. In the past, this has usually resulted in code that looks like:
class MyMessage : public SerialisableObject
{
// message members
int myNumber_;
std::string myString_;
std::vector<MyOtherSerialisableObject> aBunchOfThingsIWantToSerialise_;
public:
// ctor, dtor, accesors, mutators, then:
virtual void Serialise(SerialisationStream & stream)
{
stream & myNumber_;
stream & myString_;
stream & aBunchOfThingsIWantToSerialise_;
}
};
The problem with using this kind of design is that violates an important rule of good architecture: you should not have to specify the intent of a design twice. Duplication of intent, like duplicated code and other common development duplication, leaves room for one place in the code to become divergent with the other, causing errors.
In the above, the duplication is the list of members. Potential errors include adding a member to the class but forgetting to add it to the serialisation list, serialising a member twice (possibly by not using the same order as the member declaration or possibly due to a misspelling of a similar member, among other ways), or serialising something that is not a member (which might produce a compiler error, unless name lookup finds something at a different scope than the object that matches lookup rules). That kind of mistake is the same reason we no longer try to match every heap allocation with a delete (instead using smart pointers) or ever file open with a close (using RAII ctor//dtor mechanisms) - we don't want to have to match up our intent in multiple places because there are times we - or another engineer less familiar with the intent - make mistakes.
Generally, therefore, this has been one of the things that code generation could take care of. You might create a file MyMessage.cg to specify both layout and members in one step
serialisable MyMessage
{
int myNumber_;
std::string myString_;
std::vector<MyOtherSerialisableObject> aBunchOfThingsIWantToSerialise_;
};
that would be run through a code generation utility and produce the code.
I was wondering if it was possible yet to do this in c++0x without external code generation. Are there any new language mechanisms that make it possible to specify a class as serialisable once, and the names and layout of it's members are used to layout the message during serialisation?
To be clear, I know that there are tricks with boost tuples and fusion that can come close to this kind of behavior even in the pre-c++0x language. Those usages, though, being based on indexing into the tuple rather than by-member-name access, have all been brittle to changing the layout, as other places in the code that access the messages would then also need to be reordered. Some kind of by-member-name access is necessary to not have to duplicate the layout specification in places in the code that use the messages.
Also, I know it might be nice to take this up to the next level and ask for specifying when some of the members shouldn't be serialised. Other languages that offer serialisation built in often offer some kind of attribute to do this, so
int myNonSerialisedNumber_ [[noserialise]];
might seem natural. However, I personally think it is bad design to have serialisable objects where everything is not serialised, since the lifetime of messages is in the transport to/from the communications layer, separate from other data lifetimes. Also, you could have an object which has a purely serialisable as on of it's members, so such functionality doesn't by anything the language doesn't already offer.
Is this possible? Or did the standards committee leave out this kind of introspective capability? I don't need it to look like the code gen file above - any simple method for compiletime specification of layout and members in a single step would solve this common problem.
This is both possible and practical in C++11 – in fact it was possible back in C++03, the syntax was just a little too unwieldy. I wrote a small library based around the same idea - see the following:
www.github.com/molw5/framework
Sample syntax:
class Object : serializable <Object,
value <NAME(“Field 1”), int>,
value <NAME(“Field 2”), float>,
value <NAME(“Field 3”), double>>
{
};
Most of the underlying code could be reproduced, in principal, in C++03 – some of the implementation details without variadic templates would have been...tricky, but I believe it would have been possible to recover the core functionality. What you could not reproduce in C++03 was the NAME macro above and the syntax relies fairly heavily on it. The macro provides the machinery necessary to generate a unique typename from a string, that is the following:
NAME(“Field 1”)
expands to
type_string <'F', 'i', 'e', 'l', 'd', ' ', '1'>
through the use of some common macros and constexpr (for character extraction). Back in C++03 something similar to the type_string above would need to be entered manually.
C++, of any form, supports neither introspection nor reflection (to the extent that they are different).
One nice thing about doing serialization manually (ie: without introspection or reflection) is that you can provide object versioning. You can support older forms of the serialization, and simply create reasonable defaults for the data that wasn't in the old versions. Or if a new version removes some data, you can simply serialize and discard it.
It seems to me that what you need is Boost.Serialization.
The Law of Demeter does not prevent passing objects into class constructors. However, it does forbid getting that same object back later and calling a method on it to get a scalar value out. Instead, a proxy method is supposed to be created that returns the scalar value instead. My question is, why is it acceptable to pass an object into a class constructor but unacceptable to get the same object back later and pull a value from it?
Because the Law of Demeter says that you should not design the external interface of an object to make it look as if it is composed of certain other objects with known interfaces, that clients can just grab hold of and access.
You pass an object into the constructor to tell your new object how to behave, but it is none of your business whether the object keeps that parameter object around, or keeps a copy of it, or just looks at it once and forgets it ever existed. By having a getMyParameterBack method, you've committed all future implementations to be able to produce that whole object on demand, and all clients to couple with two interfaces instead of one.
For example, if you pass in a URL parameter to your HTTPRequest object's constructor, then that doesn't mean HTTPRequest should have a getURL method which returns a URL object on which the caller is then expected to call getProtocol, getQueryString, etc. If someone who has an HTTPRequest object might want to know the protocol of the request, they should (the Law says) find out by calling getProtocol on the object they have, not on some other object that they happen to know HTTPRequest is storing internally.
The idea is to reduce coupling - without the Law of Demeter, the user has to know the interface to HTTPRequest and URL in order to get the protocol. With the Law, they only need the interface to HTTPRequest. And HTTPRequest.getProtocol() clearly can return "http" without needing some URL object to be involved in the discussion.
The fact that sometimes the user of the request object happens to be the one who created it, and therefore is using the URL interface too in order to pass the parameter, is neither here nor there. Not all users of HTTPRequest objects will have created them themselves. So clients which are entitled under the Law to access the URL because they created it themselves, can do it that way rather than grabbing it back off the Request. Clients which did not create the URL can't.
Personally I think the Law of Demeter as usually stated in simple form, is cracked. Are they seriously saying that if my object has a string Name field, and I want to know whether the Name contains any non-ASCII characters, then I must either define a NameContainsNonASCIICharacters method on my object instead of looking at the string itself, or else add a visitName function to the class taking a callback function in order to work around the restriction by ensuring that the string is a parameter to a function I've written? That doesn't change the coupling at all, it just replaces getter methods with visitor methods. Should every class which returns an integer have a full set of arithmetic operations, in case I want to manipulate the return value? getPriceMultipliedBy(int n)? Surely not.
What it is useful for, is that when you break it you can ask yourself why you're breaking it, and whether you could design a better interface by not breaking it. Frequently you can, but really it depends what kinds of objects you're talking about. Certain interfaces can safely be coupled against vast swathes of code - things like integer, string, and even URL, which represent widely-used concepts.
JP's answer is pretty good, so this is just a supplement, not a disagreement or other replacement.
The way I understand this heuristic is that a call to A shouldn't break because of class B changing. So if you chain your calls with a.b.foo(), then A's interface becomes dependent upon B's, violating the rule. Instead, you're supposed to call a.BFoo(), which calls b.foo() for you.
This is a good rule of thumb, but it can lead to awkward code that doesn't really address the dependency so much as enshrine it. Now A has to offer BFoo forever, even when B no longer offers Foo. Not much of an improvement and it would be arguably better in at least some cases if changes to B broke the caller that wants Foo, not B itself.
I would also add that, strictly speaking, this rule is broken constantly for a certain group of ubiquitous classe, such as string. Perhaps it's acceptable to decide which classes are likewise ubiquitous within a particular layer of an application and freely ignore Demeter's "Rule" for them.
The idea is that you only talk to your immediate friends. So, you don't do this ...
var a = new A();
var x = a.B.doSomething();
Instead you do this ...
var a = new A();
var x = a.doSomething(); // where a.doSomething might call b.doSomething();
It has it's advantages, as things become simpler for callers (Car.Start() versus Car.Engine.Start()), but you get lots of little wrapping methods. You can also use the Mediator pattern to mitigate this type of "violation".
I often see two conflicting strategies for method interfaces, loosely summarized as follows:
// Form 1: Pass in an object.
double calculateTaxesOwed(TaxForm f) { ... }
// Form 2: Pass in the fields you'll use.
double calculateTaxesOwed(double taxRate, double income) { ... }
// use of form 1:
TaxForm f = ...
double payment = calculateTaxesOwed(f);
// use of form 2:
TaxForm f = ...
double payment = calculateTaxesOwed(f.getTaxRate(), f.getIncome());
I've seen advocates for the second form, particularly in dynamic languages where it may be harder to evaluate what fields are being used.
However, I much prefer the first form: it's shorter, there is less room for error, and if the definition of the object changes later you won't necessarily need to update method signatures, perhaps just change how you work with the object inside the method.
Is there a compelling general case for either form? Are there clear examples of when you should use the second form over the first? Are there SOLID or other OOP principles I can point to to justify my decision to use one form over the other? Do any of the above answers change if you're using a dynamic language?
In all honesty it depends on the method in question.
If the method makes sense without the object, then the second form is easier to re-use and removes a coupling between the two classes.
If the method relies on the object then fair enough pass the object.
There is probably a good argument for a third form where you pass an interface designed to work with that method. Gives you the clarity of the first form with the flexibility of the second.
It depends on the intention of your method.
If the method is designed to work specifically with that object and only that object, pass the object. It makes for a nice encapsulation.
But, if the method is more general purpose, you will probably want to pass the parameters individually. That way, the method is more likely to be reused when the information is coming from another source (i.e. different types of objects or other derived data).
I strongly recommend the second solution - calculateTaxesOwed() calculates some data, hence needs some numerical input. The method has absolutly nothing to do with the user interface and should in turn not consum a form as input, because you want your business logic separated from your user interface.
The method performing the calculation should (usualy) not even belong to the same modul as the user interface. In this case you get a circular dependency because the user interface requires the business logic and the business logic requires the user interface form - a very strong indication that something is wrong (but could be still solved using interface based programming).
UPDATE
If the tax form is not a user interface form, things change a bit. In this case I suggest to expose the value using a instance method GetOwedTaxes() or instance property OwedTaxes of the TaxForm class but I would not use a static method. If the calculation can be reused elsewhere, one could still create a static helper method consuming the values, not the form, and call this helper method from within the instance method or property.
I don't think it really matters. You open yourself to side effects if you pass in the Object as it might be mutated. This might however be what you want. To mitigate this (and to aid testing) you are probably better passing the interface rather than the concrete type. The benefit is that you don't need to change the method signature if you want to access another field of the Object.
Passing all the parameters makes it clearer what the type needs, and might make it easier to test (though if you use the interface this is less of a benefit). But you will have more refactoring.
Judge each situation on its merits and pick the least painful.
Passing just the arguments can be easier to unit test, as you don't need to mock up entire objects full of data just to test functionality that is essentially just static calculation. If there are just two fields being used, of the object's many, I'd lean towards just passing those fields, all else being equal.
That said, when you end up with six, seven or more fields, it's time to consider passing either the whole object or a subset of the fields in a "payload" class (or struct/dictionary, depending on the language's style). Long method signatures are usually confusing.
The other option is to make it a class method, so you don't have to pass anything. It's less convenient to test, but worth considering when your method is only ever used on a TaxForm object's data.
I realize that this is largely an artifact of the example used and so it may not apply in many real-world cases, but, if the function is tied so strongly to a specific class, then shouldn't it be:
double payment = f.calculateTaxesOwed;
It seems more appropriate to me that a tax document would carry the responsibility itself for calculating the relevant taxes rather than having that responsibility fall onto a utility function, particularly given that different tax forms tend to use different tax tables or calculation methods.
One advantage of the first form is
Abstraction - programming to an interface rather than implementation. It makes the maintainance of your code easier in the long run becuase you may change the implementation of TaxForm without affecting the client code as long as the interface of TaxForm does not change.
This is the same as the "Introduce Parameter Object" from Martin Fowler's book on refactoring. Fowler suggests that you perform this refactoring if there are a group of parameters that tend to be passed together.
If you believe in the Law of Demeter, then you would favor passing exactly what is needed:
http://en.wikipedia.org/wiki/Law_of_Demeter
http://www.c2.com/cgi/wiki?LawOfDemeter
Separation of UI and Data to be manipulated
In your case, you are missing an intermediate class, say, TaxInfo, representing the entity to be taxed. The reason is that UI (the form) and business logic (how tax rate is calculated) are on two different "change tracks", one changes with presentation technology ("the web", "The web 2.0", "WPF", ...), the other changes with legalese. Define a clear interface between them.
General discussion, using an example:
Consider a function to create a bitmap for a business card. Is the purpose of the function
(1) // Formats a business card title from first name and last name
OR
(2) // Formats a businnes card title from a Person record
The first option is more generic, with a weaker coupling, which is generally preferrable. However, In many cases less robust against change requests - e.g. consider "case 2017: add persons Initial to business card".
Changing the implementation (adding person.Initial) is usually easier and faster than changing the interface.
The choice is ultimately what type of changes you expect: is it more likely that more information from a Personrecord is required, or is it more likely that you want to create business card titles for other data structures than Person?
If that is "undecided", anfd you can't opf for purpose (1) or (2) I'd rather go with (2), for syntactic cleanliness.
If I was made to choose one of the two, I'd always go with the second one - what if you find that you (for whatever reason) need to caculate the taxes owed, but you dont have an instance of TaxForm?
This is a fairly trivial example, however I've seen cases where a method doing a relatively simple task had complex inputs which were difficult to create, making the method far more difficult to use than it should have been. (The author simply hadn't considered that other people might want to use that method!)
Personally, to make the code more readable, I would probbaly have both:
double calculateTaxesOwed(TaxForm f)
{
return calculateTaxesOwed(f.getTaxRate(), f.getIncome());
}
double calculateTaxesOwed(double taxRate, double income) { ... }
My rule of thumb is to wherever possible have a method that takes exactly the input it needs - its very easy to write wrapper methods.
Personally, I'll go with #2 since it's much more clear of what it is that the method need. Passing the TaxForm (if it is what I think it is, like a Windows Form) is sort of smelly and make me cringe a little (>_<).
I'd use the first variation only if you are passing a DTO specific to the calculation, like IncomeTaxCalculationInfo object which will contain the TaxRate and Income and whatever else needed to calculate the final result in the method, but never something like a Windows / Web Form.