Let us recap:
• We had two classes, PutOption and CallOption.
• These classes could be used in much the same way, so the code for pricing them was almost identical.
• To avoid duplicating code, we carefully observed which functions Put- Option and CallOption had in common.
• We designed an interface which simply listed these common functions, albeit using some unusual syntax.
• We indicated that PutOption and CallOption implemented the inter- face.
• By telling the C++ compiler about the interface we were able to write one priceByMonteCarlo function that works for any path-independent option.
If two different types of objects have similar functions then we can write algorithms that will work with both types of objects by using interfaces. This is a powerful way to avoid duplicating code.
How common is it for two different types of object to have similar func- tions? The answer is extremely common. Here are some examples:
1. Two printers provided by different manufacturers will differ in many ways, but the manufacturers should provide objects that allow us to print files on the different printers without duplicating our code. They can do this by agreeing on a common interface for all printers. This is the same thing as saying they should agree on a common set of print functions all printers are guaranteed to support.
2. Two monsters in a computer game (say an elf and a dragon) will have many functions in common. For example, they will have functions to return their weights, heights, name and to draw them on the screen. The author of the game will introduce an interface Monster to avoid duplicating code.
3. All stock price models should have a function generatePrices. We can write a standard interface StockPriceModel with various implementa- tions such as BlackScholesModel, StudentTModel, HestonModel and JumpDiffusionModel. The last three are simply the names of some stock price models that have been proposed in the mathematical finance litera- ture. Our Monte Carlo pricing code can then be modified so it will work with any model. Doing this is left as an exercise, see Exercise 14.4.5. The end result is a very powerful pricing function that can price any path-independent option using any model for the stock price at time T. 4. All trading strategies should have a function selectPortfolio which decides how to invest at a particular moment in time. We can have a general interface TradingStrategy and concrete subclasses Delta- HedgingStrategy and BuyAndHoldStrategy. See Exercise 14.4.6. 5. Any encryption algorithm should have methods encrypt and decrypt.
This can be represented as an interface called Cipher. It is then possible to provide different implementations of the encryption algorithm that work in different ways. For example, you might write a CaeserCipher that replaces a with d, b with e, c with f, etc., or you might write a ReverseCipher that replaces a with z and b with y, etc. You could then write software that sends encrypted messages and that is capable of working with any Cipher.
6. Any object of type GroupElement should have methods inverse and multiply. You could then represent any mathematical Group in C++ by providing an appropriate implementation of GroupElement.
In fact, we actually met the idea of an interface before. An ostream is a general data type. We can write data to any stream simply because it has a << function. We don’t need to worry about whether it is a file stream or a stream that writes to the screen. What we have been describing in this chapter is how to write your own general types that are as flexible as the ostream class.
While the examples above all focus on interfaces in computer software, you can see interfaces in real world design. One example is a car: All cars have steering wheels that behave in the same way. You can drive a car of any make or model because they all make the same basic promise to turn right when you rotate the steering wheel clockwise. Another example is electrical plug sockets. All electrical appliances have the same interface and so they can all be plugged into the same electrical sockets.
Whether we use interfaces for real world design or in software, the payoff is the same. In one example we can learn to drive all cars at once because they have the same interface. In another example, we can price all path-independent options at once because they have the same interface.
We have given a lot of examples because the concept of interfaces is the most important idea in object-oriented programming. You might find that at first it is difficult to think of ways in which interfaces could be useful. If so you are not alone. Most programmers find it difficult to take full advantage of interfaces. In practice the only way to learn how to use interfaces is to see lots of examples. In software jargon, examples of how to use interfaces are called “design patterns” after the famous book Design Patterns: Elements of
Reusable Object-Oriented Software [4]. The aim of this book is to show you
the most important design patterns for financial mathematics.
Another piece of software jargon that is useful to know is the word poly-
morphism, which simply means “many forms” in Greek. Polymorphic software
is software that can work equally well with a variety of different data types. So a function that uses the ostream will be polymorphic because it can be used to write to files, strings, the network, and the screen. Our Monte Carlo pricer is polymorphic because it can be used to price many kinds of options.