Understanding abstraction in OOP - oop

I was studying the object oriented concepts and there the abstraction concept is basically described as hiding the implementation from user. So if there is a member function in a class and we call that function for some task, abstraction says that user should not be concerned about how things are getting done but should only be aware of what is getting done. But even in a non object oriented programming style, if we write a function, the whole task is accomplished by simply calling a function. Doesn't it follow the abstraction logic too? Or, is there any difference between the abstraction in OOP and functional programming?

In Object Oriented Programming, we generally think about Abstractions in terms of inheritance and polymorphism.
Let's consider the Writer interface
interface Writer {
void write(byte[] bytes)
}
This interface allows a user to write to... something. What, we're not particularly worried about. We could have multiple versions of this:
class FileWriter implements Writer
class StringWriter implements Writer
class LogWriter implements Writer
class MySuperCustomWriter implements Writer
Where we write isn't important, be it a File, String, a socket, or wherever. All we want to do is write to something. This lets us write code like this:
public class MyBusinessLogic {
private final Writer writer;
public MyBusinessLogic(Writer writer) {
this.writer = writer;
}
void someBusinessLogic() {
// ..
writer.write(someStuff);
}
}
What we have here is some business logic that wants to do some writing. By using an interface, our business logic is no longer dependent on any specific method of writing. It just gets some object that is capable of doing some writing. We can pass it any of our example writers and be sure that it'll work right, because we're interested here in the behavior of writing, and not the implementation.
By doing this, the business logic is not dependent on the file system, network, or anything else.

It's not the fact that you call a function that is providing the abstraction but the manor in which it's called. For example, you might have a function which allows you to write a line of text:
void writeLine(string fileName, string value)
But that is not abstracted from the fact that you're writing to a file. The abstracted version would not require the caller to provide the fileName parameter because that is specific to that particular implementation of the function. Instead you would have:
void writeLine(string value)
And the fileName is provided using another mechanism e.g. a constructor argument of a class if you're using OOP and calling a writeLine method or, in the functional case, you might curry the original function to create the abstracted version.

Quick Encapsulation Example
type
public class DateTimeClass
private
Era: integer;
Culture: integer;
Year: integer;
Month: integer;
Day: integer;
protected
Integer function getYear ( );
// other functions
procedure setYear ( );
// other functions
public
procedure AssignOccidentalDate
(NewYear: integer; NewMonth: integer;
NewDay : integer);
end;
...
var Date: DateTimeClass;
Date.AssignOccidentalDate (2019, 07, 27);
...
You can only access the "public" declarations.

Related

Strategy Pattern and Open-Closed Principle Conflict

I was reading through strategy pattern and was trying to implement it but I have got stuck at deciding the strategy implementation which I feel violates the open-closed principle.
In strategy pattern we code to interface and based on client interaction we will pass in the strategy implementation.
Now if we have bunch of strategies so we need to decide using conditions which strategy the client chooses something like
IStrategy str;
if(stragety1) {
str = new Strategy1()
} else if (stragety2) {
str = new Strategy2()
} and so on..
str.run()
Now as per open-closed principle the above is open to extension but it is not closed to modification
If I need to add another strategy(extension) in future I do need to alter this code.
is there a way where this could be avoided or it is how we need to implement strategy pattern ?
1) You must separate selecting/creating a concrete strategy from its uses. I. e. use function selectStrategy, pass it as (constructor) parameter, etc.
2) There is no way to fully avoid conditional creation, but you can hide it (e. g. using some dictionary for mapping state=>strategy) and/or shift it into another level of the application. The last approach is very powerful and flexible, but depends on the task. In some cases you may put selecting/creating on the same level that uses it. In other cases you may even end up with delegation selecting/creating to the highest/lowest level.
2.1) You can use the Registry pattern and kinda avoid modification of "core" object when adding new strategy's.
This is indeed not closed to modification, but that is due to the way you initialize. You are using a value (enum?) to determine which Strategy subclass should be used. As #bpjoshi points out their comment, this is more of a Factory pattern.
Wikipedia discusses how a Strategy pattern can support the Open/Closed Principle, instead of hampering it.
In that example, they use a Car class with a Brake Strategy. Some cars brake with ABS, some don't. Different Car subclasses and instances can be given different Strategies for braking.
To get your code closed for modification, you need to select the Strategies differently. You want to select the Strategy in the place where new behavior or subclass is defined. You'd have to refactor your code so that the specific Strategy subclass is applied at the point where the code is extended.
I think, there is misunderstanding about Closed for Modifications.
In 1988, Mayer said:
Software that works should when possible not be changed when your application is extended with new functionality.
and Rober C. Matrin said:
This definition is obviously dated.
Think about that very carefully. If the behaviors of all the modules in your system could be extended, without modifying them, then you could add new features to that system without modifying any old code. The features would be added solely by writing new code.
https://8thlight.com/blog/uncle-bob/2014/05/12/TheOpenClosedPrinciple.html
Adding some new codes without modifying old codes do not conflict with Open-Closed Principle.
I think the decision you are referring to should be the responsibility of a factory class. The following is some example code:
public interface ISalary
{
decimal Calculate();
}
public class ManagerSalary : ISalary
{
public decimal Calculate()
{
return 0;
}
}
public class AdminSalary : ISalary
{
public decimal Calculate()
{
return 0;
}
}
public class Employee
{
private ISalary salary;
public Employee(ISalary salary)
{
this.salary = salary;
}
public string Name { get; set; }
public decimal CalculateSalary()
{
return this.salary.Calculate();
}
}
The Employee class uses the Strategy pattern and follows the Open/Closed principle, i.e. it is open to new strategy types (ISalary implementations) through injection via the constructor, but closed to modification.
The piece that is missing is the code that creates the Employee objects, something like:
public enum EmployeeType
{
Manager,
Admin
}
public class EmployeeFactory
{
public Employee CreateEmployee(EmployeeType type)
{
if (type == EmployeeType.Manager)
return new Employee(new ManagerSalary());
else if (type == EmployeeType.Admin)
return new Employee(new AdminSalary());
etc
}
}
This is a very simple factory pattern. There are better ways to do this but this is the simplest way to explain the concept.

Why is overriding of static methods left out of most OOP languages?

It is certainly not for good OOP design - as the need for common behavior of all instances of a derived class is quite valid conceptually. Moreover, it would make for so much cleaner code if one could just say Data.parse(file), have the common parse() code in the base class and let overriding do its magic than having to implement mostly similar code in all data subtypes and be careful to call DataSybtype.parse(file) - ugly ugly ugly
So there must be a reason - like Performance ?
As a bonus - are there OOP languages that do allow this ?
Java-specific arguments are welcome as that's what I am used to - but I believe the answer is language agnostic.
EDIT : one could ideally :
<T> void method(Iface<? extends T> ifaceImpl){
T.staticMeth(); // here the right override would be called
}
This will also fail due to erasure (in java at least) - if erasure is at work one needs (would need) to actually pass the class :
<T, K extends T> void method(Iface<K> ifaceImpl, Class<K> cls){
cls.staticMeth(); // compile error
}
Does it make sense ? Are there languages doing this already ? Is there a workaround apart from reflection ?
Speaking to C++
class Foo {
public:
static void staticFn(int i);
virtual void virtFn(int i);
};
The virtual function is a member function - that is, it is called with a this pointer from which to look up the vtable and find the correct function to call.
The static function, explicitly, does not operate on a member, so there is no this object from which to look up the vtable.
When you invoke a static member function as above, you are explicitly providing a fixed, static, function pointer.
foo->virtFn(1);
expands out to something vaguely like
foo->_vtable[0](foo, 1);
while
foo->staticFn(1);
expands to a simple function call
Foo##staticFn(1);
The whole point of "static" is that it is object-independent. Thus it would be impossible to virtualize.

OOAD - File-Format-Reader class vs Object-Model class: which should depend on which?

Let's consider, as an example, the domain of GPS and Geographical (GIS) entities.
We would model the meaningful geographic entities (points, paths, regions) as classes in any desired programming language, and these classes would be a conceptual, "implementation-free" representation of these entities.
On the other hand, there are a lot of file formats that save these features with more or less the same meaning. In the GPS domain the most common file formats are GPX, KML, ShapeFile, WellKnownText, etc.
Supposing, then, I want to create a GpsFeatureCollection class which would contain a Points property, a Paths property, and so on. Also, I would implement classes like GpsReader, KmlReader, ShapeFileReader (and their respective Writers) and so on.
THE QUESTION IS:
Which is the best practice in OOAD:
Have a GpsFeatureCollection to instantiate a FileFormat(Reader/Writer) class?
Have a GpsFeatureCollection to implement Read/WriteFromFormat methods instead of classes?
Have each file format reader to instantiate an empty GpsFeatureCollection, populate it with data read from file, then pass the populated object as a return value?
Have a mediator class to avoid any dependency between FileFormatClass and ObjectModelClass?
None of the above?
"Well, it depends..."
I am really interested in doing "the right thing". My immediate plans are to use Python, but most probably this would matter for other languages too. This is causing some "analysis paralysis" in my pet project currently...
Here is my take wherein I pass reader and writer instances to read() and write() methods, this seems to achieve good level of decoupling and yet provides flexibility to pick various readers and writers.
Code uses Java-like syntax
Declare a Reader interface, we will assuming multiple implementation such KMLReader,
ShapeFileReader, etc
interface Reader {
GpsFeatureCollection read();
}
Declare a Writer interface, we will assuming multiple implementation such KMLWriter, ShapeFileWriter, etc
interface Writer {
void write(GpsFeatureCollection c);
}
Let's declare GpsFeatureCollection class to have read and write methods which accept respective interfaces as parameter to perform the job.
class GpsFeatureCollection {
...
public static GpsFeatureCollection read(Reader r) {
return r.read();
}
public static void write(Writer w) {
w.write(this);
}
}
Some example of usage using different readers and writers.
// Reading data
GpsFeaureCollection data = GpsFeatureCollection.read(new ShapeFileReader("/tmp/shapefile"));
// Writing data
data.write(new KMLWriter("/tmp/kmlfile"));

Encapsulation. Well-designed class

Today I read a book and the author wrote that in a well-designed class the only way to access attributes is through one of that class methods. Is it a widely accepted thought? Why is it so important to encapsulate the attributes? What could be the consequences of not doing it? I read somewhere earlier that this improves security or something like that. Any example in PHP or Java would be very helpful.
Is it a widely accepted thought?
In the object-oriented world, yes.
Why is it so important to encapsulate the attributes? What could be the consequences of not doing it?
Objects are intended to be cohesive entities containing data and behavior that other objects can access in a controlled way through a public interface. If an class does not encapsulate its data and behavior, it no longer has control over the data being accessed and cannot fulfill its contracts with other objects implied by the public interface.
One of the big problems with this is that if a class has to change internally, the public interface shouldn't have to change. That way it doesn't break any code and other classes can continue using it as before.
Any example in PHP or Java would be very helpful.
Here's a Java example:
public class MyClass {
// Should not be < 0
public int importantValue;
...
public void setImportantValue(int newValue) {
if (newValue < 0) {
throw new IllegalArgumentException("value cannot be < 0");
}
}
...
}
The problem here is that because I haven't encapsulated importantValue by making it private rather than public, anyone can come along and circumvent the check I put in the setter to prevent the object from having an invalid state. importantValue should never be less than 0, but the lack of encapsulation makes it impossible to prevent it from being so.
What could be the consequences of not
doing it?
The whole idea behind encapsulation is that all knowledge of anything related to the class (other than its interface) is within the class itself. For example, allowing direct access to attributes puts the onus of making sure any assignments are valid on the code doing the assigning. If the definition of what's valid changes, you have to go through and audit everything using the class to make sure they conform. Encapsulating the rule in a "setter" method means you only have to change it in one place, and any caller trying anything funny can get an exception thrown at it in return. There are lots of other things you might want to do when an attribute changes, and a setter is the place to do it.
Whether or not allowing direct access for attributes that don't have any rules to bind them (e.g., anything that fits in an integer is okay) is good practice is debatable. I suppose that using getters and setters is a good idea for the sake of consistency, i.e., you always know that you can call setFoo() to alter the foo attribute without having to look up whether or not you can do it directly. They also allow you to future-proof your class so that if you have additional code to execute, the place to put it is already there.
Personally, I think having to use getters and setters is clumsy-looking. I'd much rather write x.foo = 34 than x.setFoo(34) and look forward to the day when some language comes up with the equivalent of database triggers for members that allow you to define code that fires before, after or instead of a assignments.
Opinions on how "good OOD" is achieved are dime a dozen, and also very experienced programmers and designers tend to disagree about design choices and philosophies. This could be a flame-war starter, if you ask people across a wide varieties of language background and paradigms.
And yes, in theory are theory and practice the same, so language choice shouldn't influence high level design very much. But in practice they do, and good and bad things happen because of that.
Let me add this:
It depends. Encapsulation (in a supporting language) gives you some control over how you classes are used, so you can tell people: this is the API, and you have to use this. In other languages (e.g. python) the difference between official API and informal (subject to change) interfaces is by naming convention only (after all, we're all consenting adults here)
Encapsulation is not a security feature.
Another thought to ponder
Encapsulation with accessors also provides much better maintainability in the future. In Feanor's answer above, it works great to enforce security checks (assuming your instvar is private), but it can have much further reaching benifits.
Consider the following scenario:
1) you complete your application, and distribute it to some set of users (internal, external, whatever).
2) BigCustomerA approaches your team and wants an audit trail added to the product.
If everyone is using the accessor methods in their code, this becomes almost trivial to implement. Something like so:
MyAPI Version 1.0
public class MyClass {
private int importantValue;
...
public void setImportantValue(int newValue) {
if (newValue < 0) {
throw new IllegalArgumentException("value cannot be < 0");
}
importantValue = newValue;
}
...
}
MyAPI V1.1 (now with audit trails)
public class MyClass {
private int importantValue;
...
public void setImportantValue(int newValue) {
if (newValue < 0) {
throw new IllegalArgumentException("value cannot be < 0");
}
this.addAuditTrail("importantValue", importantValue, newValue);
importantValue = newValue;
}
...
}
Existing users of the API make no changes to their code and the new feature (audit trail) is now available.
Without encapsulation using accessors your faced with a huge migration effort.
When coding for the first time, it will seem like a lot of work. Its much faster to type: class.varName = something vs class.setVarName(something); but if everyone took the easy way out, getting paid for BigCustomerA's feature request would be a huge effort.
In Object Oriente Programming there is a principle that is known as (http://en.wikipedia.org/wiki/Open/closed_principle):
POC --> Principle of Open and Closed. This principle stays for: a well class design should be opened for extensibility (inheritance) but closed for modification of internal members (encapsulation). It means that you could not be able to modify the state of an object without taking care about it.
So, new languages only modify internal variables (fields) through properties (getters and setters methods in C++ or Java). In C# properties compile to methods in MSIL.
C#:
int _myproperty = 0;
public int MyProperty
{
get { return _myproperty; }
set { if (_someVarieble = someConstantValue) { _myproperty = value; } else { _myproperty = _someOtherValue; } }
}
C++/Java:
int _myproperty = 0;
public void setMyProperty(int value)
{
if (value = someConstantValue) { _myproperty = value; } else { _myproperty = _someOtherValue; }
}
public int getMyProperty()
{
return _myproperty;
}
Take theses ideas (from Head First C#):
Think about ways the fields can misused. What can go wrong if they're not set properly.
Is everything in your class public? Spend some time thinking about encapsulation.
What fields require processing or calculation? They are prime candidates.
Only make fields and methods public if you need to. If you don't have a reason to declare something public, don't.

help with interfaces and abstract classes

I'm recently getting a bit confused with interfaces and abstract classes and I feel I dont fully grasp it like I thought I did. I think I'm using them incorrectly. I'll describe what I'm doing at the moment, the problem I have faced, and then hopefully it be clear what I'm doing wrong if anything.
I wanted to write some classes that do some parsing of xml. I have different user types that have different parsing requirements.
My logic went as follows.
All parsers share a "parse" function in common and must have at least this function so I made an Interface with this function defined named IParse;
I start out with 2 user types, user type A and user type B. User type A & B share some basic functions but user type B has slightly more functions than A so I put the functions to parse what they share in an abstract class that both will extend called "ParseBase".
So now I have
// Interface
public interface IParser
{
function parse(xml:XML):void;
}
// Base Class
public class ParseBase()
{
public function getbasicdata():void{}
public function getmorebasicdata():void{}
}
//User type A
public class userTypeA extends ParseBase implement IParse
{
public function parse(xml:XML):void
{
getbasicdata()
getmorebasicdata()
}
}
//user type B
public class userTypeB extends ParseBase implement IParse
{
public function parse(xml:XML):void
{
getbasicdata()
getmorebasicdata()
}
public function extraFunctionForB():void
{
}
public function anotherExtraFunctionForB():void
{
}
}
The problem I have come up against now which leads me believe that I'm doing something wrong is as follows.
Lets say I want to add another function UserTypeB. I go and write a new public function in that class. Then In my implementation I use a switch to check what Usertype to create.
Var userParser:IParser
if(a)
{
userParser= new userTypeA();
}else if(b)
{
userParser= new userTypeB();
}
If i then try to access that new function I can't see it in my code hinting. The only function names I see are the functions defined in the interface.
What am I doing wrong?
You declare the new function only in userTypeB, not in IParser. Thus it is not visible via IParser's interface. Since userParser is declared as an IParser, you can't directly access userTypeB's functions via it - you need to either downcast it to userTypeB, or add the new function to IParser to achieve that.
Of course, adding a function to IParser only makes sense if that function is meaningful for all parsers, not only for userTypeB. This is a design question, which IMO can't be reasonably answered without knowing a lot more about your app. One thing you can do though, is to unite IParser and BaseParser - IMO you don't need both. You can simply define the public interface and some default implementation in a single abstract class.
Oher than that, this has nothing to do with abstract classes - consider rephrasing the title. Btw in the code you show, ParseBase does not seem to be abstract.
In order to access functions for a specific sub-type (UserTypeB, for example) you need the variable to be of that type (requires explicit casting).
The use of interfaces and abstract classes is useful when you only require the methods defined in the interface. If you build the interface correctly, this should be most of the time.
As Peter Torok says (+1), the IParser declares just one function parse(xml). When you create a variable userParser of type IParser, you will be allowed to call ony the parse() method. In order to call a function defined in the subtype, you will have to explicitly cast it into that subtype.
In that case IMO your should rethink the way you have designed your parsers, an example would be to put a declaration in your IParser (Good if you make this abstract and have common base functionality in here) that allow subtypes (parsers) to do some customization before and after parsing.
You can also have a separate BaseParser abstract type that implemnts the IParser interface.