Square is-a Rectangle. But not really.

Inheritance is not always the answer. While the answer does seem obvious and often seems right, one has to always be careful when modelling real world entities to objects and classes because at the end of the day, they’re not the same.

My app supported two kinds of exercises: Lifting exercises, where you lift weights like squats and bicep curls and so on, and Cardio exercises like the Treadmill and the Bicycle, etc.

Naturally in the Data layer, I modeled this as a generic exercise class with Lifting and Cardio exercise sub-classes like so:

exercise-inheritance (1).png

 

Simple enough. Lifting and Cardio are different types of exercises and therefore there should be a common Exercise class that they inherit from.

The problem was as follows. You can adjust a lot of things when doing Cardio type exercises. Say you’re on a treadmill. On a treadmill you can adjust the speed, the incline and time. On a bicycle, you can only adjust the time and the intensity, which is basically how hard you have to push the pedals. Then there’s the elliptical, for which you can have speed, incline, intensity and of course, time.

Basically, each cardio exercise had it’s own set of fields.

Treadmill Bicycle Elliptical
Time Time Time
Speed Speed Speed
Incline Intensity Incline
Intensity

That’s not even counting planking, which can have time and poundage.

Lifting exercises on the other hand are simple, each set has a poundage and there’s a maximum number of sets you have to do.

So no matter how hard I tried, I still found myself ultimately needing to differentiate between Lifting exercises and Cardio exercises at some point in the code, i.e. if lifting do this... , for example when displaying a list of exercises or editing them or what have you.

It was then all too late when I remembered a podcast by Scott Hanselman called hanselminutes. Lovely stuff by the way. Specifically, this episode starring Robert C. Martin (Uncle Bob).

The idea was simple: Lifting and Cardio exercises are fundamentally different. They don’t inherit from the same class.

Just like Square and Rectangle. A square is-a rectangle in geometry but in code, it has a completely different entity. Square does not inherit from Rectangle . Not always anyway

For example, the setHeight() function of a Rectangle is not the same as a setHeight() function of  a square. In fact a square wouldn’t even have a setHeight(), it would be much more appropriate to call it setSide() or setLength() or something. It’s not a good idea to always map the real world exactly to their entities in software.

This is just a little bit of wisdom I once learned and forgot when I needed it most. Hopefully, now that you’ve seen this, that won’t be the case for you.

Advertisements

Making Android DialogFragments reusable.

In Android, as with any other platform, Dialogs are fairly common. Dialog Boxes can be of different types doing different things and might be needed all the time in your project. So there’s a big incentive to making them reusable.

Building an Android Dialog Box is simple. You create a class that extends DialogFragment, you define it’s views and titles and so on and you have the Activity or Fragment that you need call it whenever it needs to.

Let’s take a situation where you need to add or edit the name of an existing field and we use a dialog because that’s the only field you’re using or maybe you want someone to enter some information, etc.

Generally speaking, the code that you’d write to create a simple Dialog with an EditText (which is Android’s text input control) and that has an OK/Cancel button would look like this:

// MyEditDialogFragment.java
mEditText = new EditText(getContext());
listener = (MainActivity) getContext();

return new AlertDialog.Builder(getContext())
                .setView(mEditText)
                .setPositiveButton(getString(android.R.string.ok), new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        // Do something when user clicks OK.
                    }
                })
                .setNegativeButton(getString(android.R.string.cancel), null)

Let’s assume we have some text we want to edit and we want to do that with a DialogFragment. So we have some text, and we have a button. When we click the button, we get a Dialog box to edit the text. It would look something like this:

fragment-ui.png

So in the scenario described above we have a MainActivity that calls a DialogFragment where we enter new text and change the text in the Activity. The question then is, “How do we return the data from the Activity?”

It’s important to mention here that it is recommended that you use Fragments. Fragments make passing data between the calling Fragment and the DialogFragment relatively easy. But sometimes, one makes the mistake of not using Fragments and now you have to either rewrite your entire Activity to use Fragments or figure out how to return data from the DialogFragment to an Activity, as I had to recently.

The recommended way to do that is described here. Simply put, we define a listener object in the DialogFragment to call some function in the MainActvitiy. The MainActvivity will implement our listener interface, in this case OnDialogCompletedListener and will provide an implementation for the onCompleted(String) method that will be called by the DialogFragment.

We change the code above to what is given below:

// MyEditDialogFragment.java
return new AlertDialog.Builder(getContext())
                .setTitle("New Text")
                .setView(mEditText)
                .setPositiveButton(getString(android.R.string.ok), new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        String text = mEditText.getText().toString();
                        listener.onCompleted(text);
                    }
                })
                .setNegativeButton(getString(android.R.string.cancel), null)

In the code above, we get the text from the EditText and pass it to the onComplete(String) function, which is defined in the MainActivity. That function simply changes the text. Since MainActivity will implement the OnDialogCompletedListener interface, it will have to override that function.

// MainActivity.java
@Override
public void onCompleted(String text) {
    mTextView.setText(text);
}

What’s important to note here is that our DialogFragment calls the onCompleted(String) on the MainActivity so it’s inherently tied to the MainActivity, especially the one onCompleted function.

If you wanted to add the data entered in the Dialog to a database, this wouldn’t be substantially different to calling a method from the Activity to do that. The problem with that approach is that you have the same method called, each time the Dialog is created. If you wanted to do something else, you’d have a problem.

Meaning that if I wanted to do something else, say “add a new text box”, we couldn’t use the same DialogFragment

So clearly the solution is to set our own listener and pass it to the fragment. The way we can do that is simply to inject our own listener. Say we define a setOnDialogCompleteListener() for our DialogFragment which is simply this:

// MainActivity.java
public void setOnDialogCompletedListener (OnDialogCompletedListener listener) {
    this.listener = listener;
}

Now when creating the Dialog in the MainActivity, we simply set our own listener as we would do for a Button or any other View.

// MainActivity.java
mButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                FragmentManager manager = getSupportFragmentManager();
                MyEditDialogFragment fragment = new MyEditDialogFragment();
                fragment.setOnDialogCompletedListener(new OnDialogCompletedListener() {
                    @Override
                    public void onCompleted(String text) {
                        mTextView.setText(text)
                    }
                });
                fragment.show(manager, TAG);
            }
        });

Now the DialogFragment is not tied to the MainActivity. Now it can be reused anywhere we like.

// SomeActivity.java
fragment.setOnDialogCompletedListener(new OnDialogCompletedListener() {
                    @Override
                    public void onCompleted(String text) {
                        FirebaseDatabase.getInstance().getReference()
                                .child("posts")
                                .child(getKey())
                                .child("name")
                                .setValue(text);
                    }
                });

In the code above, now we’re using the same MyEditDialogFragment to update data in a database, in different Activity altogether without changing anything about the Dialog.

Optionally, we could define it in a newInstance method.

// MyEditDialogFragment.java
public MyEditDialogFragment(OnDialogCompletedListener listener) {
        this.listener = listener;
    }
// Note: a default constructor is also defined

    public static MyEditDialogFragment newInstance(String text, OnDialogCompletedListener listener) {
        Bundle args = new Bundle();
        
        MyEditDialogFragment fragment = new MyEditDialogFragment(listener);
        fragment.setArguments(args);
        return fragment;
    }

This generates an Android Lint warning saying that non-default constructors should not be used since when re-instantiating the fragment, they will not be called. However since we’re explicitly calling them in the newInstance() method, we should be fine.

Our newInstance() method takes two parameters: A title for the DialogFragment and the listener. Now when we instantiate the DialogFragment we will also have to provide an OnDialogCompletedListener for it.

// MainActivity.java

                MyEditDialogFragment fragment = MyEditDialogFragment.newInstance("Edit Subtitle",
                        new OnDialogCompletedListener() {
                            @Override
                            public void onCompleted(String text) {
                                mSubtitleTextView.setText(text);
                            }
                        });
            }

“Communication in MVC Teams: A Test-Driven Approach”, now published in the IJCSE.

My blog post about using Test-Driven Development for communication was created as part of a research paper I was writing. The paper in full has now been published in the IJCSE.

The paper is titled “Communication in MVC Teams: A Test-Driven Approach“, now available here.

Making ASP.NET MVC code more testable using a Service Layer.

Common wisdom says regarding the Repository and Unit of Work patterns in ASP.NET MVC to implement it on top of Entity Framework. This is supposed to make your code more testable and more decoupled, which is always desirable.

Doing this, however, can be complicated. The general architecture of an application implementing these patterns (as seen on MSDN) is shown below:

Windows-Live-Writer_8c4963ba1fa3_CE3B_Repository_pattern_diagram_1df790d3-bdf2-4c11-9098-946ddd9cd884

Implementing all of these classes can of course be daunting. Trying to write testable, modular code and following best practices might  lead to an explosion of classes, especially if you’re trying to follow the Repository pattern and what not.

There is a simpler way to do this. Implementing only a Service layer allows you to write more testable, modular code without having to write several different layers of classes.

Now, the standard architecture that ASP.NET MVC generates with scaffolding looks like this:

standard-m-v-c

The Model is used by the Controller to render into the View. Much of the code you’ll need is auto-generated but it’s very hard to test if you need to add your own business logic.

If you write Services however, classes that encapsulate Entity Framework stuff to use in your controller, you have a mockable, testable chunk of business logic which can decouple much of your application. It would look something like this:

service-example (1)

Each model would have a service. However, you can have a Service for a logical group of Models as well, that is up to you. Each Service will implement an interface, which can be mocked in unit tests and injected into the controllers.

For example, if you have a Student model and an Instructor model such that one Instructor has many Students and each model has it’s own controller. We can write a Service class for each model that uses the DbContext as it’s repository and unit of work. This way we will still be using the Repository and Unit of Work patterns, but not repeating stuff.

These services can then be injected into the Controller as you see fit and the reason we define interfaces for each service, is precisely so we can inject mock implementations of the services in the Controller.

Consider our Student-Instructor example. Say that you want a list of Students for that Instructor displayed when the user views details about that Instructor. You want this list to be always arranged by the Students’ names in alphabetical order.

We write a function in the InstructorService class to do this, let’s call it GetStudents(int instId) that simply returns a list of students with that instructor. It may seem simple but there are a lot of benefits to having such small functions. The first being that we don’t have to re-write the query each time we use it. For instance, we can use it in a normal Action method or we could use it in a Web API controller.

The normal Details action method, that renders a View that shows Instructor Details would be modified thus:

// GET: Instructors/Details/5
public ActionResult Details(int? id)
{
        if (id == null)
        {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
        }

        // I'm using id ?? 0 to convert int into a nullable int.
        Instructor instructor = instructorService.FindById(id ?? 0);
        ViewBag.students = instructorService.GetStudents(id ?? 0);

        if (instructor == null)
        {
                return HttpNotFound();
        }
        return View(instructor);
}

Where the instructorService object is injected into the Controller or initialized somewhere else. I’m using a ViewBag here but I should probably use ViewModels.

Regardless, we can easily test the behavior of our Details action method using the following test:

[TestMethod]
public void TestMethod1()
{
        // Arrange
        Mock mock = new Mock();
        Instructor testInstructor = new Instructor() { Id = 1, Name = "Test Instructor" };
        Student testStudentA = new Student()
        {
                Id = 100,
                Name = "AAA",
                Instructor = testInstructor
        };

        Student testStudentB = new Student()
        {
                Id = 100,
                Name = "BBB",
                Instructor = testInstructor
        };

        mock.Setup(m => m.GetStudents(It.IsAny()))
                .Returns(new List() { testStudentA, testStudentB });

        mock.Setup(m => m.FindById(It.IsAny())).Returns(testInstructor);

        // This List is already arranged alphabetically.
        List expectedStudents = new List()
        {
                testStudentA,
                testStudentB
        };

        // Act
        InstructorsController controller = new InstructorsController(mock.Object);
        var result = controller.Details(testInstructor.Id) as ViewResult;
        List returnedStudents = result.ViewBag.students;

        // Assert
        CollectionAssert.AreEqual(expectedStudents, returnedStudents);
}

The test above may see large but a lot of it is simply initialization code, that would go in a different method. This test simply makes sure that the ViewBag contains the proper students.

What’s important to note here is that we are testing the controller and only the controller. Therefore we create Mocks of all of its dependencies, which in this case is the IInstructorService interface.

This means that we can also test the Service classes if we mock the DbContext class, i.e. the Model which they depend on.

An example of such a test, that tests the GetStudents() method is given below. I’ve omitted a lot of the setup code this time, so it should be easier to follow.

[TestMethod]
public void TestGetStudents()
{
        //
        Debug.WriteLine(mockDbSetInstructors.Object);
        List students = new List() { testStudentB, testStudentA, };
        Mock mock = new Mock();
        mock.Setup(m => m.GetAll()).Returns(students);

        // This list is in alphabetical order
        List expectedStudents = new List() { testStudentA, testStudentB };

        // Act
        // Real implementation of Instructor Service
        InstructorService service = new InstructorService(mockCtx.Object, mock.Object);
        List returnedStudents = service.GetStudents(testInstructor.Id).ToList();

        // Assert
        CollectionAssert.AreEqual(expectedStudents, returnedStudents);
}

Thus, with the inclusion of the Service classes, we don’t have too much of an explosion of classes and our code is a lot more modular and testable than it previously was.

Of course eventually you might have to use ViewModels and AutoMapper and other stuff, but simply having Service objects such as these can make things a lot more testable.

A test-driven approach to developer communication

In teams that are distributed or partially distributed, there often is a need for a centralized online meeting point where everyone can discuss and share information about what they’re working on. Stuff like WhatsApp groups, Trello boards, github issue discussions and the classic mailing lists are some of the tools already in place for this.

For a team that I was working with which comprised mostly of students working on a mock project I needed a way to make sure that everyone was always on the same page and there was some written record of what the teams needed from each other, so that the teams didn’t have to come in and talk to each other all the time.

We were developing an application using the ASP.NET MVC Platform and we had a frontend team and a backend team working in tandem. We needed a way to make sure the frontend team communicated very clearly what data (in the form of Models, URLs, etc.) they needed from the backend team.

We had a design document and UI diagrams and ER diagrams and all of that already built, however the precise details of what exact object would be returned to the Views couldn’t be easily documented. For example, say for the Books list page, they need a Book Object that may look like this:


class Book
{
public virtual Item ItemId { get; set; } // Foreign Key
public int BookId { get; set; } // primary key
public string Title { get; set; }
public string Author { get; set; }
public DateTime DateOfPublishing { get; set; }
}

There were also common business logic rules that the frontend and the backend teams had to ensure, say, the ItemID, which was a foreign key could not be null.

Of course there’s a lot of ways to communicate this, I had a crazy idea. Rather than only have documents and diagrams that everyone has to be told about and explained and are difficult to maintain, we also right tests. The frontend team writes a test for the Book object that it needs from the controller and the backend team delivers that object, thus making the tests pass.

This way, the test would be the common format of communication, that teams use to officially tell each other what they need. The tests wouldn’t replace the documentation that already existed, but rather augment it.

So the scenario would go like this: The frontend team needs a list, specifically C#’s IEnumerable of Books, whose ItemID’s are not null. They write a test that looks like the following psuedocode:


public void BookListTest
{
// code to set up test

books = controller.List();
Assert.IsType(IEnumerable, books);
Assert.IsNotNull(books.Any(b => b.ItemId));
Assert.IsNotNull(books.Any(b => b.DateOfPublishing));
}

The test above says simply that the List() method, i.e. the List View of the controller returns a) An IEnumberable of Book objects, b) the ItemId for any book is not null and c) the DateOfPublishing for any book is not null.

Of course most of these rules would already be documented in the business logic, the tests just makes sure that when their built, that stuff is taken care of.

Both the frontend people and the backend people look at this test and go, “That’s what I’m getting, that’s what I need to do”. This is included in the code and this is a test. When it is first written, the test fails. Eventually it passes and everyone moves on to the next controller or what have you.

The idea came really from studying about how computer systems that aren’t made with the same architecture communicate. For example, consider how objects are serialized and sent over to other application servers in Java. They’re converted to a specific format that every system knows and then sent over to the other instance.

Consider this a way of serializing requirements. They’re codified and cemented in the form of tests so everyone is always aware of them. If there’s a flaw in the tests, they should be updated and that change is added into the code.

This approach, of course, has flaws. The biggest flaw that we found in our project was that the tests were often wrong, so they had to be updated to pass. However, this gave everyone who read the test a clearer understanding of what the component did.

In fact, you wouldn’t be completely wrong to think that this is pointless. Projects already have sequence diagrams and use cases and other detailed documentation that already solve this problem. This approach requires you to write a lot of tests, since this is technically a form of Test-Driven Development.

However, the primary benefit of this approach, is that now you have tests. It is correct that you need additional development time to write and debug tests. It is also correct that projects can get by without this approach because diagrams and documents, while not flawless work just fine. They can be a pain sometimes and this approach doesn’t solve all the problems of asynchronous development and distributed teams. However, with this approach, now you have tests!

In no way am I suggesting that this replace whatever already is available to any team in the world. However, writing tests can simply be a way to tell everyone on the team, exactly what needs to be done. This approach is meant to more augment existing documentation rather than replace it.

To verify the absolute effectiveness of this approach, there needs to be a proper study looking at data over a significant period of time. I hope you’ve found this article interesting and I believe this idea is worth looking into. I’m currently writing a paper about this approach and hopefully it all works out.

What is an ERP system and why they are important

An old professor I had once said something incredibly profound that I had never considered despite my background in IT. He said that “Computerization adds transparency” in a business.

His example was that when using physical books for accounting, which is often the case for many simple shops even today, humans can introduce inconsistencies in the data, which is a fancy way of saying that they can mess with the actual finances in an organization. With computerization, i.e. just using a computer to do the accounts, inventory and other book-keeping tasks, the calculations made cannot really be controlled by people and everyone can see them (as they need to).

The impact of IT in any organization is very significant regardless of the size or nature of the organization. In this article we’re going to look at a simple example of an IT Institute that uses a simple Online Information System to maintain important class material.

An Illustration

Our situation is simple. A class has many subjects each taught by a few professors. One or two students maintain an online system, that is accessible to view by everyone but only they can upload to and it can contain all sorts of resources like books, software, code, etc. It also contains important information like notices, timetables, and important announcements

Now this looks nothing like a system that you would find in a business but it will serve the purpose of illustrating the impact that any IT system can have in an organization.

Access to Information

Information is vital to the functioning of an organization, even to a classroom. Having the system online with an easily accessible URL (or perhaps as an application installed on everyone’s phone or computer) makes sure that anyone can look up the information right then and there. This is especially useful if it is a front-desk position and you have an impatient customer sitting right in front of you.

In our example, this would expand to information being available to any student 24×7 whether or not they are in college at the time. This means that if someone wants to look up what an assignment was, they can do so from the comfort of their own bed at any time.

A common knowledge base

When an ERP system or any computer system is implemented in an organization, it centralizes the data. Meaning that all the data lives in one central location.

This means that any data coming into the system will be collected together from multiple sources across an organization. In our example, this knowledge could be class notes, articles, books and other study material that all the students in a class would need.

Having a central repository of all knowledge means that if a student needs to look up some information in any book or any notes, they all have it in a central location and they don’t have to ask each other for it, saving them a lot of time.

Saving Work

ERP systems store day-to-day information that is constantly updated. For projects, this means that everyone has a record of exactly what work is done and what needs to be done.

In our example, this would be class notes that could be uploaded every week. Everyone would know exactly where the lectures are in the syllabus hence keeping track for anybody who might’ve missed a few.

Also in our example, the knowledge base of books, notes and other resources would be constantly built up so that when the exams come, every student is well-equipped with whatever they need so that they can study without worrying about missing something from the syllabus.

Looking to the future

One of the key benefits of ERP systems for any organization is that because the information is collated, organized and readily available, managers at all levels can make important decisions for the future.

For example, both teachers and students in our example can be aware of what is done in class and what they need to do in the time remaining till the exam. Students can also look back at some mistakes that may have been made in the past and eliminating inefficiencies.

Due to the fact that the information is available constantly, short-term and long-term decisions can be made, and people can see where they went wrong and perhaps how to improve things.

ERP is a nebulous term and it can mean different things for different people, however it is important to understand that knowledge is power and that’s where ERP matters.

What are “types” in OOP, really

When I google the phrase “types in Java” or “types in OOP”, I am presented with a list of the primitive data types that have been a part of most programming languages forever. However, in an Object Oriented context, the word “type” refers to something a bit more abstract and a bit more interesting than simply storage space.

Right side, left side.

Consider the standard idiom to instantiate an object in C# or Java.

Object o = new Object();

Notice that unlike say python or javascript, we write the word “Object” twice. The question then is, why do we do so? What is the difference between the word “Object” on the left side and the word “Object” on the right side.

The technically correct answer is that the word on the right side is a Constructor and that on the left side is the name of the class and you’d be right for saying that. However, what is on the right is not simply the class name, it is also the name of the type.

The word “type” does not actually refer to the “code” of the class, i.e. the body of the class. It does not refer to the exact definition or implementation of a class or it’s functions somewhere. The word “type” only refers to the public members of a class. It does not include the private or protected members.

This boils down to the concept that the collection of all the operations you can do on an object (i.e. the functions you can call on it, etc.) form the type of the object. This collection can also be known as the interface of the class, i.e. how someone can use the class.

Using a Class

Consider the following situation. Fred and Bill are working on some kind of coffee order system where Fred designs the frontend and Bill designs the classes and the database i.e. the backend. For those who may not know, here are some of the various kinds of coffee you can make:

Types_coffee_chart

Bill defines a Coffee class that provides methods to add Espresso (i.e. the  base of the coffee) and options to add other ingredients to make whatever kind of coffee a user needs. Perhaps this coffee class looks like the following:


class Coffee {
    private void grindCoffee() {
        // ...
    }
    private void addCoffee() {
        // ...
    }
    public void addWater() {
        // ...
    }
    public void addEspresso() {
        grindCoffee();
        addCoffee();
        addWater();
        // return 30ml espresso
    }
    public void addFoam(int qty) {
        //.. add some amount of foam
    }
    public void addSteamedMilk(int qty) {
        //.. add some amount of milk
    }
}

The interface of the Coffee class would include addEspresso(), addFoam() and addSteamedMilk() and Fred can combine these to make whatever kind of coffee they need and offer it in their user interface. This is how Fred will use the class Coffee.

Fred of course cannot control how the Espresso is made. They are only presented with the option to add the Espresso by the Coffee class. The functions to grind and add coffee are used internally by the class and therefore they are private.

So the addEspresso(), addFoam() and addSteamedMilk() functions would make up the type of the Coffee object. For dynamically typed languages like Python or Ruby, this “type” is decided at runtime, i.e. when the code is actually executing. For statically typed languages, the “type” i.e. the collection of methods that you can call on an object is set at compile time. This is why a grindCoffee() operation on a Coffee object would fail because the compiler would not be able to find that method in the object’s type, since it is private.

As long as the function is present in the object’s type (i.e. the left side in our idiom above) the function call will work. This is where Inheritance and Polymorphism come into play.

Inheriting Types

The type of an object does not tell you anything about how the function works, i.e. how it is implemented. It just tells you that you can call that function on that object. As long as the function is present in the type of the object, it doesn’t really matter how it is written. Consider the following example:

class A {
    public void foo() {
        System.out.println("A");
    }
}

class AB extends A {
    @Override
    public void foo() {
        System.out.println("AB");
    }
    public void bar() {

    }
}

If we make an object of type A and point it to a reference of class AB with:

A obj = new AB()

then obj.foo() will call foo() from AB. This is basic Polymorphism. What’s interesting however, is that obj does not have a bar() method because that isn’t part of the type A.

If we want obj to change types, we’ll have to cast it appropriately. However, at compile time, the type of obj i.e. the list of methods and stuff that can be performed on it does not contain bar(). Of course this does not mean that when we define an unrelated class with the same methods as A, we can do the same thing because a type is not literally only the method list. However, any class that is part of A‘s hierarchy i.e. any class down the inheritance structure can be used to create an object of type A.

This fact actually helps in decoupling a lot of the code that you may write. It is also what makes Dependency Injection possible.

Interfaces in Java (and C#) can also be used in the same way as we used A. An interface really is just a type declaration if you think about it. Consider a class C implementing an interface called Iface

We can actually do the following:

Iface obj = new C();

This works the same way for any class implementing Iface even down the inheritance tree, i.e. in this case, any subclass of C.

The beauty of this of course is that developers can make accurate assumptions about the type of the object coming in from somewhere and not have to worry about the implementation.

Decoupling code

If we look at the Coffee Order system example above, if Fred who’s working on the frontend only uses Interface, Bill can modify and extend his classes on his side without breaking things for Fred.

For Example, if Fred has a simple method called makeCappuccino(), he could define it somewhat like this:

void makeCappucino(CoffeeType obj) {
    obj.addEspresso();
    obj.addFoam();
    obj.addSteamedMilk();
}

Now it doesn’t matter if Bill sends Coffee or any special subclass of Coffee, say FancyCoffee or something. As long as it derives from the CoffeeType interface, Fred can use it to make a cappuccino, making his code independent of Bill’s code in this regard.

I hope this clears up some doubts people might’ve had about the word “type” in OOP and hopefully reading this will help in some way.