Thursday, September 17, 2009

Gang of Four Design Patterns review


Design Patterns: Elements of Reusable Object-Oriented Software was the first published book to identify patterns in object-oriented programmind and has become a classic in the last ten years.

What is a design pattern?
In computer science, but also in architecture, a design pattern is a standard solution to a common problem. In the software engineering field, patterns fill the lack of functionality of an object-oriented language.
Whenever you hear the words Factory, Lazy Loading, Singleton or Iterator, the argument is design patterns:
  • tipically the name of a design pattern is written capitalized: Iterator is one of them, while an iterator is a specific object;
  • design patterns are built with classes and objects and their representation is often a Uml diagram. When a set of classes you write falls in the diagram definition, it's said that you are implementing the pattern.
  • a pattern is a reusable technique and does not consist in reusable code: you may write many Factory classes but they will never be interchangeable. What is similar in them is the underlying concept and contract structure, the recurring theme.
  • also Anti-patterns exist, but they are not commonly teached.
This book, written by the Gang of Four and published in 1994, is the first presentation of patterns for the general developers public. It has sold more than 500.000 copies and even nowadaysl it does not have an alternative as a complete reference manual for the original patterns.
The name Gang of Four for the authors Erich Gamma, Richard Helm, Ralph Johnson and John Vlissides is mutuated from the original Chinese Gang of Four, which was an alliance of (obviously four) communist party officials.

Chapter 1 (Introduction) and chapter 2 (A case study)
The beginning of this book already provides great value. The first chapter is about object-oriented programming, a recap of its principles, and a 50000 feet view of the patterns and how they fit together. Composition and inheritance are in the list of the topics; a guide for the reader helps to orient in the book, searching the right pattern for the job.
The second chapter is a study for the design of a WYSIWYG text editor a la OpenOffice, whose architecture is composed a bit at the time applying eight design patterns. It can be useful to read the practical solution of a real world problem and how Gang of Four manages to implementing the patterns presented.

After this introduction, the patterns are presented. Every pattern is described in the book as follows:
  • Name and classification: the name of this patterns have become a standard and they are referred all over the Internet. The classification will tell you what king of pattern you are viewing (creational, structural or behavioral).
  • Intent: every pattern solves a problem and it is stated in the most general form.
  • Also known as: other names for the pattern, now mostly in disuse.
  • Motivation: why the problem is a real, painful problem and how the pattern solves it brilliantly. This is the main explanation of how the solution works.
  • Applicability: typical cases where you will reach these pages of the book to read how to implement the pattern.
  • Structure: Uml class diagram or object diagram
  • Participants: descriptions of the classes involved in the diagram, with generic names.
  • Collaborations: the method calls of the objects.
  • Consequences: what this pattern application implies and its advantages or limitations.
  • Implementation: long notes on the best ways to implement in code this pattern.
  • Sample code: it speak by itself; a complete example of C code which shows you how to do practical work with this pattern. Although there is little mumbo jumbo in this book, I appreciate a lot this parts which keep out it and present something that compiles.
  • Known uses: object-oriented application which has applied this pattern successfully.
  • Related patterns: similar patterns to consult if the current solution feels wrong or raise other issues than the one it solves.
As you can see, nearly everything you want to know about writing an Iterator or a Builder is kept in this book.

Creational patterns (5 chapters)
This collection of patterns is dedicated to the creation of objects, solving problems like abstracting away a particular kind of objects behind an interface and simplify the creation process by eliminating repetitive code.
Abstract Factory, Builder, Factory Method, Prototype and Singleton are presented in this first big part.

Structural patterns (7 chapters)
This second collection presents patterns used for maintain a clean object graph: the typical intents are sharing interfaces and objects for reuse or adding responsibilities to subclasses without cluttering the class tree.
Adapter, Bridge, Composite, Decorator, Facade, Flyweight and Proxy are presented in this section.

Behavioral patterns (11 chapters)
These patterns are concerned with building a standard architecture for objects and with assigning responsibilities to the right owner. The intents are retain loos coupling between classes while at the same time allow complex algorithms and control flow to happen. For instance, abstracting way the State of an object to decouple it.
Chain Of Responsibility, Command, Interpreter, Iterator, Mediator, Memento, Observer, State, Strategy, Template Method and Visitor are presented here in this last part.

A glossary, a guide to the Uml notation and the foundation classes, on which the code examples are based, are also provided at the end of the book. This bonus will teach you also the basics of Uml.

In sum, this book is a milestone in the history of object-oriented programming and it will always have a reserved space next to my desk into my hard disk to allow a rapid consultation. I won't advise to read it all the first time, as it can be boring, but having it at hand can help whenever you're thinking if the design of your application can be improved.

The image at the top is the cover of the current edition of the book. There is also en electronic version: Design Patterns CD: Elements of Reusable Object-Oriented Software (Professional Computing).

Wednesday, September 16, 2009

How to TDD a database application

After the publishing of Failed attempt to apply Tdd response, some readers have asked me how to test a database application, as an example of code which is not suitable for xUnit frameworks.

Let's start with saying that database is not a special case for testing, as it's only a port of your application. Whenever the application interact with an external program I would say it presents a port, and this pattern is called Hexagonal Architecture.
Your effort should be in testing thoroughly the core of the application, building a solid object-oriented Domain Model piece after piece, by writing a test at the time an making it pass. The Domain Model should not have dependency on any infrastructure like database, http requests, twitter adapters, and so on: this refinement of the Domain Model pattern is called Domain-Driven Design and when applied produces easy testable code. The Domain Model would be tested by injecting fake adapters as there should be no logic in the database: this is object-oriented programming and in database object do not exist nor we can test it easily and automatically with Junit.
Though, this approach is very complicated and it is considered when the domain has a rich set of rules and behavior, while many applications have only CRUD capabilities.

Think of your application as existing only in Ram memory and strip out all the unnecessary code. The classes which remains are the core of the Domain Model. For instance if I had to manage the list of the users of a forum, I would write initially only a User class and a generic collection of User objects. User in my point of view is a POJO or POPO, which does not extend anything:
class User { ...

Insulating the database from view will hide this generic collection behind an abstraction
, since it is not present at all in memory except for caching. Subsets of it can be reconstituted as needed. This abstraction is called a Repository or, at a low level, a DataMapper. Hibernate for Java and Doctrine 2 for php are example of a DataMapper pattern: they let you work on your objects and then take them and synchronize the database with the new data you have inserted: a change in a User's password, or new Users to be added. To polish the DataMapper Api, which is very generic, a UserRepository class can be created.
Even if you do not have a generic DataMapper, and work with mysql_query, PDO or JDBC queries, you can write a UserRepository which will act as the port for the database (or maybe a text file; since the repository decouples it, the storage mechanism can be anything from a memcache server to a group of monkeys which writes down on paper serializations of objects).
Depending on your architecture, your controllers or other domain classes will now have the UserRepository as a collaborator, and will talk to it and call its methods instead of accessing the database directly; this is a form of Dependency Injection. Obviously if there are other entities which are persisted, like Groups, Posts, etc. they should have their own repository class.

Of course the point of this discussion is how to test this code, since to write it we have to prepare a test before (it's called red green refactor and not code and then try to test). If we manage to write these tests first, the code will be automatically testable, and very decoupled and reusable as this is a characteristic of testable code.
What we need to write are not tests, but unit tests. If you want to check the entire path of data in the application, you can write integration tests which will exercise even the user interface, but Test-Driven Development prescribes to write unit tests: your test methods should have a dependency only on the system under test, and to the interface it uses.
Continuing our example, we need:
  • unit tests for User, Group, Post classes (Domain Model entities);
  • unit tests for controllers or other classes from the Domain Model which uses the adapters.
  • unit tests for UserRepository and similar classes (adapters);
  • unit tests for DataMapper or (infrastructure);
The point of unit testing is you can test singular components separately, and not the entire application as you would do with functional testing. Moreover, you must test each component separately or otherwise it would reveal too difficult to write classes to satisfy an integration test and the TDD benefits of adding a bit of design with every test method would be lost.
With this knowledge, we can say:
  • unit tests for Domain Model entities must be written by the developer of this application. If the project is mostly a CRUD application and is data-intensive, these test cases will be very short.
  • unit tests for controllers and everything that uses the adapters also must be written by the developer, mocking the adapters out. If you use the real adapters in testing, it will be integration testing and it will be heavy and brittle; you won't know if it's the controller or the adapter which does not work after a red test.
  • unit tests for the adapters concrete classes: this is the only interaction with the database. Fortunately, we are unit testing for this classes so we can even use a new database for every test method as every class will present a few methods; compare this approach with testing every single feature of the application by using a real database.
  • unit tests for infrastructure: these are included in the framework so we shouldn't worry.
Note that if you use a DataMapper which abstracts the particular database vendor as infrastructure, you can run the unit tests for the adapters by using a in-memory database like sqlite instead of the real database which will likely be very heavy to manage and recreate every time; this way, you de facto exclude database from your unit tests. Of course some integration tests will be necessary, but they are not part of TDD and of the design process.

I hope to have given you an idea of what unit tests means and how to deal with an application which uses a database for persistence, which is a very common scenario. Feel free to raise questions in the comments if something is not clear.

Do you want more? There's a book for .NET developers which explains DDD and database-independent testing.
The image at the top is a photograph of integrated circuits, which are real world components designed for testability and which are tested indipendently from the card where they will work.

Tuesday, September 15, 2009

SOLID part 6 (bonus): how much solid Standard Php Library is?

This is a bonus part for the SOLID principles series. You can check it out to view the articles which explain all the principles or subscribe to the feed to be informed of new posts.

How that we have talked a lot about the five SOLID principles, it's time to apply them to a real project and see the good design ideas they introduce and what trade-offs are accepted in everyday coding. Since I have mainly a php audience, I have chosen the unique object-oriented library that the php core features natively: the Standard Php Library (SPL).

The Iterator interface and its implementations were the first Spl components to be included in php. This interface is very cohesive and it does not assume much about the source where items are coming from: for instance, in every implementation there's no need to write a method that counts the elements, since it is segregated in a Countable standard interface.
Iterator is extended by RecursiveIterator and OuterIterator, which manages respectively an iterator which items have children and a iterator who decorates another. These components adds only one or two methods to the parent interface and are also very cohesive: they are the hook for opening Spl to extensions.
The responsibilities of these classes are evenly distributed: the basic Iterator implementations have proven to be very useful (such as DirectoryIterator which produces the list of files contained in a folder), while other functionalities are kept in their own OuterIterator implementation, like LimitIterator and CachingIterator.
The primary use of Iterator (and of its parent interface Traversable) is in the foreach construct, where it can be passed as it were an array. The standard implementations can be swapped without problems in a foreach, and this means that Liskov Substitution Principle is more or less respected. What comes to mind is that different Iterators will return a different type of items, but php is a dynamic language and this precisation does not strictly affect the application of principle as long as the methods retain the same meaning and intent. To solve it completely the interface should use generics like in Java: Iterator.

Spl provides object-oriented way to access filesystem (SplFileInfo and similar ones), which is not a point of interest in this discussion since these classes are a wrapper to the basic functions such as opendir() and filesize(). The same goes for Exception and its tree of subclasses. The Serializable interface is also a good hook for extension of behavior, but we are not going to overanalyze the library.

What indeed raise attention is the SplObserver and SplSubject interfaces, which suggest a standard way to implement the observer pattern. These components are not useful in my opinion, and a comparison with static typed languages will show the difference.
In a static language like Java, when a parameter is passed to a method which have a determinate signature, only the contract defined by this signature could be used in the body of the method. This is the definition of SplObserver:
public function update(SplSubject $subject);
where SplSubject contains the methods attach(), detach() and notify(). Since the contract is defined from SplSubject interface, if php were a static language we could only call these three methods, which are totally unuseful to get the state of the subject (which can be thinked as some getXXX() methods to call on the subject); only the fact that php is a dynamic language, and does not complain if you call methods which can be unexistent,allows such a method call. Moreover, these interfaces force the developer to adopt a pull-style of Observer pattern even where a push-style would be simpler.
In sum, a design pattern, like the Observer one, is a common solution to a problem and should be implemented every time with different flavours, requiring different classes. SplObserver and SplSubject fail to satisfy the Dependency Inversion Principle since they won't decouple their implementors, that needs to know a large abstraction they leave out.

With the release of php 5.3, it has become clear that the goal of Spl is to provide fast components, implemented in C for particular purposes, and not a well designed object-oriented library. SplQueue is an example of this, along with its companion SplStack:
class SplQueue extends SplDoublyLinkedList implements Iterator, ArrayAccess, Countable { ...
SplDoublyLinkedList is a classic data structure, a general purpose list that is subclassed by SplQueue and SplStack. Since it implements Iterator and other Spl interfaces, their children inherits these features, but in my opinion it's not a good idea.
A queue can be accessed only one element at time; a stack has the same limitations, which are voluntarily imposed to incapsulate the internal data structure and limit the operations that can be done on it by a client class: I would rather have a SplQueue as an interface and not a concrete implementation, with just the enqueue() and dequeue() methods; SplStack as another interface with pop() and push(). SplDoublyLinkedList would be a generic implementation, which satisfies both interfaces.
Why I would prefer this design? Because it places functionalities in two compact interfaces; otherwise Interface Segregation Principle is not applied and no interfaces are even defined. SplQueue can't be a child of a SplDoublyLinkedList as it would be a violation of Liskov Substition Principle: a implementation of a queue can use a double linked list internally, but not inherit methods from it or it is not a queue anymore.
A benefit of a Queue interface would be real decoupling and its consequences: for instance, a mock of Queue can be used in testing to make sure only enqueue() and dequeue() are used, while mocking a SplQueue as it is will expose also all the other Iterator methods as empty ones, leading to strange results (and tying my high level modules to details instead of to a queue abstraction, infringing Dependency Inversion Principle).

I would say that Spl is a good product for the goals which it had been thinked for: a reliable and fast object-oriented layer, which can overload common constructs like count() and foreach; it has been a very successful feature of php. But its design could be vastly improved, also with application of SOLID principles.

The image at the top is an upside down library.
Did you like this series? Leave a comment or subscribe to the feed to stay in touch.

Monday, September 14, 2009

Failed attempt to apply Tdd response

This is a response to the post "Why my attempt to apply tdd failed?" on the whyjava blog. I am a test-infected developer and I want to give some support to whoever had the courage to change and adopt new methodologies.

In the post the author makes a list of points which summarize the difficulties encountered while trying out Test-Driven Development. I have some comments on this list, but before analyzing it in depth I remind you that the TDD mantra is red-green-refactor. Keep in mind it every single minute since it's easy to drift away without noticing it.
  1. Time lost: this is a classic myth about TDD, but it's true that initially writing tests will require time that has to be subtracted from writing production code. But if you look at the overall picture, you will find out that tests will save you more time in the long run that the amount spent to write them. While debugging and maintaining an application having a safety net composed by good unit tests is an aid that I won't exchange even with source control. Tests also act as a documentation and this will save time for new developers who has to learn how the components works together. They also keep regression out of your project.
  2. Boring to write test cases: while practicing TDD, a developer has to find his own balance within test the obvious and not test anything. Experience at this game will make you not test getters and setters.
  3. Client support: the client does not want the developers to write tests. Besides the fact the working in this way the client is never going to know if the application works, I would find strange to tell my surgeon I don't want you to use that bistoury, I have my Miracle Blade at home.
  4. Writing exhaustive test cases: "I think tdd will make sense when you are able to cover most of the scenarios in your test class". You're right, but since in TDD you write the test cases before any production code, and only the absolutely necessary production code to make those tests pass, there's only covered scenarios. If you find a feature which is not covered by a unit test it means it has been developed before them, which is not TDD anymore.
  5. Patience: of course every technique has its learnign curve. TDD is no exception.
  6. Poor examples: if you think books are teaching you by simplicistic situations, simply download an open source software which is developed with TDD.
  7. Legacy code: it's hard to replace old (maybe procedural) code with a TDD approach, and this is a valid point. However, you should apply TDD for new features if the design allows this.
I hope to have inspired the reader to embrace Test-Driven Development, or to continue his journey in it. Becoming test-infected was like seeing the Light for me, and I think I'm becoming a better developer every day because testable code leads to decoupled and reusable code.

Pagination is dead

Pagination is the feature for displaying a long list of entities in a web application: a division of them per page and a list of link to the various pages. Today there are better solutions to this classical problem, and some of them were always available even in the first days of the web.

The typical scenario solved by pagination is to allow the search of a particular entity from a list, by displaying it a chunk at the time. Particularly in web applications, where page size is limited by bandwidth, the maximum amount of items contained in a page is fixed in less than an hundred:
The problem with pagination is how often do you look to page 2?
I google many times a day, so many that I now use the search bar of firefox instead of loading the homepage and entering the query in the input field. I usually found the first or the second result to be the most reliable resource for the query I entered since Google ranking is legendary: it's Google that decides how popular an article on this website will be and the only thing that competes in popularity with Google ranking is social network one.
Thus, I never went to the 2nd page of a Google search result. I bet you neither have done the same more than once or twice this month, and probably refining your search terms would have put the link you were looking for in the first position of the first page. Since the first link is almost always what you will be clicking some seconds later, Google main page even feature the I'm Feeling Lucky button which does this work for you.
In my opinion, Google pagination is rather useless.

In the early years of the web, pagination was the killer feature: LIMIT clauses for databases were everywhere and calculation of its argument were spread all over an application. This blog, hosted on the Blogger platform, also implements pagination: but do you prefer to scan my archives five posts at the time or to use the search box on the right?
Although all the content is available in a list of pages, a blog is not a book and it is not sequential: articles are often found by visiting a particular label or by a Google result. Honestly I sometimes look to the page 2 or 3 of a blog to form an idea on what content is posted there and decide whether to subscribe to the atom feed, but I think the author would rather have me look to a search on a tag, to a collection of popular posts or to its about page.

What about different kind of lists to paginate? Wikipedia lists are often very long: sometimes pagination is not adopted, like in the link, and the result is a unfocused and difficult to navigate page. But if you refuse to paginate there are other ways to manage this big pack of data:
  • showing results on demand a la Dzone: thanks to ajax requests, when an user reaches the end of the list or is at the last items, another chunk is lazy loaded to fill the empty space between the list and the end of the page.
  • better search system: as we have discussed earlier, Google does not need pagination since it is the best search system and you'll find your desired result in the first 10 links. Provide a mean to search a big list instead of spitting it all out, leaving the burden on the end-user.
  • real time filtering: a dojo grid presents a pagination similar to the Dzone one, but different filters can be attached to modify the query. The result is similar to google suggestion while typing in the text field, as when you add characters to your search string the filtering is performed instantly.
These are only examples of what can be done if you force yourself to not paginate. The question which I repeat here is always the same:
Who will have the patience to look at page 2?
If you keep in mind this problem, finding another user interface to substitute pagination will be at the top of your todo list.

The scroll at the top of the page shows you a continuos source of pages that reminds of pagination sliders where you can go only to the next and previous page. It was very inefficient, but ancient monks did not have Google search capabilities...

Friday, September 11, 2009

SOLID part 5: Dependency Inversion Principle

This is the fifth post in the SOLID principles series. You might want to checkout the previous entries.

High level classes should not depend on low level classes. Both should depend upon abstractions. Details should depend upon abstractions. Abstractions should not depend upon details.
The purpose of this principle is to enable decoupling of software modules. Managing dependencies is the key for isolate components to reuse later; decoupling is also important for maintenance and evolution since it stops changes in a cohesive piece of software from spreading all over an application.

The problem with dependency is the transitivity: a class depends not only on the other classes which uses directly, but also on these classes dependencies, and so on. It needs them to compile (in languages which require this process) and to work correctly; some kind of dependency between components is present in every software since object needs to work together and to know something about what methods they are going to invoke.
Let's see an example of what transitive dependency means. An object of the class Car depends on an GasEngine to move its passengers where they want to go. The GasEngine itself depends on a Gas class which models the fuel used.
The problem is that a Car should not have to use a forced fuel, like an object of the Gas class. In reality, we have electric cars or LPG ones. A Car depends upon a detail (GasEngine), while it should depend on abstraction. GasEngine is also on a lower level, so this dependency infringes both parts of the DIP.
A feasible refactoring is to introduce an interface (an abstraction) Engine which GasEngine implements and Car declares as a property. This is a powerful step since it break the dependency chain between the high level component (Car) and the low level one (GasEngine).

The Dependency Inversion in this example improves the software design since now Car and GasEngine, which are the details the principle is speaking of, depend on the abstraction Engine. Though, other issues arise when defining an abstraction: how should a Car have a reference to a GasEngine, which needs to work, while it only declares a field to contain an Engine?
There's more than one way to solve this construction problem:
  • Service Locator approach: classes like Car needs a singleton or a static registry where they pull the object they need. For instance, a method Registry::getEngine() returns an Engine whose concrete class needs to be chosen by configuration. This approach is
  • Dependency Injection: this more sophisticated, but simple at the same time, approach let Car declare its dependencies and have them injected by constructor or setters. This is the most widely used technique nowadays to achieve Inversion of Control.
Note that in the Service Locator case, Car would be totally insulated from the concrete GasEngine at compile time since the method invoked at construction includes an Engine in the signature and not a GasEngine. Though, nearly every class has a reference to a global object or static class, lying about its dependencies. Moreover, the Service Locator needs to be transported where the class are being reused.
Constructor Dependency Injection or Setter Dependency Injection is a cleaner choice since business classes have no idea of the framework or Factory which will construct the objects. Car simply declares its constructor:
public function __construct(Engine $engine);
In turn Engine will declars its needed collaborators in the constructor and the developer (or the DI framework) will learn from this signature what he must provide to build a complete object.

As always, let's do an analysis of testatiblity, confronting classes which respect or do not respect the DIP.
The initial Car class is not testable in isolation at all: it builds a GasEngine in its __construct() method and there's no way to replace it for testing purposes, expect reflection. The only thing we can test is a whole Car object, but imagine if tests were done this way in the real world... No one would know why a Car does not work when a problem arises.
The Car which uses a Service Locator is unit testable, since before running a test method we can configure the Service Locator to return a fake/mock Engine instance which follows a canned behavior. By the way, we have the hassle to configure it which can be a tedious work.
The Car which uses Dependency Injection is naturally testable: simply build a fake Engine and pass it in Car when the system under test is created. There is no need to configure other systems, which in this case get in the way instead of helping the developer.

I hope you have enjoyed this series on the five SOLID principles and that your perspective on designing a good application has shifted thanks to these pillars. New posts on object-oriented development will come in the future, you may want to subscribe to the feed to be informed of that.

The image at the top of the article is the hood open of a Ferrari F430 Spider. It depends on an Engine - a FerrariEngine maybe - and not on a GasEngine, since it can mount an ethanol one.

Thursday, September 10, 2009

SOLID part 4: Interface Segregation Principle

This is the fourth post in the SOLID principles series. You might want to subscribe to the feed to be notified of new posts.

Classes should not depend on interfaces that they not use.
The meaning of this phrase is to avoid tying a client class to a big interface if only a subset of this interface is really needed. Many times you see an interface which has lots of methods. This is a bad design choice since probably a class implementing it will infringe Single Responsibility Principle and for many other issues which arises when interfaces grow.

Let's see an example of a violation to Interface Segregation Principle. Since Car examples are becoming popular, we will continue with a vehicle example.
The class Car needs to have reference to its passengers: depending on the particular vehicle, it will transport 4 or more people and it must check during construction that it is not overloaded in weight and number of passengers since it would be not secure to drive over cartain limits. We have a class People ready who acts as a collection of Person objects; so, to load a car with People, the following method is used:
public function load(People $p);
We do not want to tie Car to People, which has in turn other dependencies, so we start with extracting an interface:
public function load(IPeople $p);
Hungarian notation is a smell that something. IPeople has many methods, the same of the People concrete class: getWeight(), remove($i), add(Person $p), and a bunch of other functions which Car will never call. What does Car need to know? This is the question that needs an answer: Car needs only a count() method to avoid being overloaded, and a getWeight() method to calculate acceleration and other physical variables. We put these two methods in an interface which will be implemented by People, deleting the awful IPeople component.
public function load(Passengers $p);
In this design, Car depends on the smallest possible interface, Passengers. An interface with a name that does not derive from its implementations is a sign that we are on a good path. Even if People has to be decoupled from Passengers interface, I strongly suggest to write an adapter implementing Passengers, which will wrap a People instance.
The important part is that Car is subjected only to variations to the method which really use, that is actually the minimum coupling introduced in the application. If such a small interface does not exist, it has to be created via extraction from the previous one.
Please note that the same issues are present in abstract base classes: although they cannot be broken down in tiny pieces since multiple inheritance is forbidden in most languages, providing every possible method in a base class can quickly transform it in a God object, and that's exaclt what we must avoid. Helpers and delegations can be used instead when not every subclass will actually need the parent's method.

Small interfaces respect the SRP, and can be combined in many ways. They can also be implemented by the same object, like many classes does in php with Countable and Iterator. Fortunately these two interfaces are separated and allow an Iterator who does not know its length to work.
The advantage of less polluted interfaces is also in simplicity of implementation: less methods result in less tests and less interaction which can cause bugs; also, the classes derived will be much more cohesive as they take only one responsibility to manage from the chosen interface.

The testing point of view results in a easy win for small interfaces. How do you know what to mock when a 20+ methods interface or base class is passed in the constructor of the system under test? When the interface has two or three methods, there is little choice in what can be called by the SUT and you can produce mocks without having to know the internals of it (which of the 20+ methods will be called at what time). Probably in such a case you will end up using a concrete class instead of a mock, transforming your unit tests in integration ones.
You will be satisfied of keeping methods to a minimum while producing a self-shunting also for testing purposes.

I think you are now at a good point in our journey in the principles of object-oriented development. Interfaces are a great decoupling tool and should be used at their full potential. Stay tuned for the next part, on Dependency Inversion (and not Injection).

The image at the top is a Swiss Army Knife. How would you define an interface for one and someone will implement it? Do you prefer a real toolbox?

Featured post

A map metaphor for architectural diagrams

It is a (two-dimension) representation of a pipe. The map is not the territory , but in software engineering terms they are models of it....

Popular posts