I see the word thrown around often, and I may have used it myself in code and libraries over time, but I never really got it. In most write-ups I came across, they just went on expecting you to figure it out.
What is a Class Factory? Can someone explain the concept?
Here's some supplemental information that may help better understand several of the other shorter, although technically correct, answers.
In the strictest sense a Class Factory is a function or method that creates or selects a class and returns it, based on some condition determined from input parameters or global context. This is required when the type of object needed can't be determined until runtime. Implementation can be done directly when classes are themselves objects in the language being used, such as Python.
Since the primary use of any class is to create instances of itself, in languages such as C++ where classes are not objects that can be passed around and manipulated, a similar result can often be achieved by simulating "virtual constructors", where you call a base-class constructor but get back an instance of some derived class. This must be simulated because constructors can't really be virtual✶ in C++, which is why such object—not class—factories are usually implemented as standalone functions or static methods.
Although using object-factories is a simple and straight-forward scheme, they require the manual maintenance of a list of all supported types in the base class' make_object() function, which can be error-prone and labor-intensive (if not over-looked). It also violates encapsulation✶✶ since a member of base class must know about all of the base's concrete descendant classes (now and in the future).
✶ Virtual functions are normally resolved "late" by the actual type of object referenced, but in the case of constructors, the object doesn't exist yet, so the type must be determined by some other means.
✶✶ Encapsulation is a property of the design of a set of classes and functions where the knowledge of the implementation details of a particular class or function are hidden within it—and is one of the hallmarks of object-oriented programming.
Therefore the best/ideal implementations are those that can handle new candidate classes automatically when they're added, rather than having only a certain finite set currently hardcoded into the factory (although the trade-off is often deemed acceptable since the factory is the only place requiring modification).
James Coplien's 1991 book Advanced C++: Programming Styles and Idioms has details on one way to implement such virtual generic constructors in C++. There are even better ways to do this using C++ templates, but that's not covered in the book which predates their addition to the standard language definition. In fact, C++ templates are themselves class factories since they instantiate a new class whenever they're invoked with different actual type arguments.
Update: I located a 1998 paper Coplien wrote for EuroPLoP titled C++ Idioms where, among other things, he revises and regroups the idioms in his book into design-pattern form à la the 1994 Design Patterns: Elements of Re-Usable Object-Oriented Software book. Note especially the Virtual Constructor section (which uses his Envelope/Letter pattern structure).
Also see the related answers here to the question Class factory in Python as well as the 2001 Dr. Dobb's article about implementing them with C++ Templates titled Abstract Factory, Template Style.
A class factory constructs instances of other classes. Typically, the classes they create share a common base class or interface, but derived classes are returned.
For example, you could have a class factory that took a database connection string and returned a class implementing IDbConnection such as SqlConnection (class and interface from .Net)
A class factory is a method which (according to some parameters for example) returns you a customised class (not instantiated!).
The Wikipedia article gives a pretty good definition: http://en.wikipedia.org/wiki/Factory_pattern
But probably the most authoritative definition would be found in the Design Patterns book by Gamma et al. (commonly called the Gang of Four Book).
I felt that this explains it pretty well (for me, anyway). Class factories are used in the factory design pattern, I think.
Like other creational patterns, it [the factory design pattern]
deals with the problem of creating
objects (products) without specifying
the exact class of object that will be
created. The factory method design
pattern handles this problem by
defining a separate method for
creating the objects, which subclasses
can then override to specify the
derived type of product that will be
created. More generally, the term
factory method is often used to refer
to any method whose main purpose is
creation of objects.
http://en.wikipedia.org/wiki/Factory_method_pattern
Apologies if you've already read this and found it to be insufficient.
Related
I use Java as an example but this is more of a general OOP design related question.
Lets take the IOExceptions in Java as an example. Why is there a class FileNotFoundException for example? Should not that be an instance of a IOException where the cause is FileNotFound? I would say FileNotFoundException is an instance of IOException. Where does this end? FileNotFoundButOnlyCheckedOnceException, FileNotFoundNoMatterHowHardITriedException..?
I have also seen code in projects I worked in where classes such as FirstLineReader and LastLineReader existed. To me, such classes actually represent instances, but I see such design in many places. Look at the Spring Framework source code for example, it comes with hundreds of such classes, where every time I see one I see an instance instead of a blueprint. Are not classes meant to be blueprints?
What I am trying to ask is, how does one make the decision between these 2 very simple options:
Option 1:
enum DogBreed {
Bulldog, Poodle;
}
class Dog {
DogBreed dogBreed;
public Dog(DogBreed dogBreed) {
this.dogBreed = dogBreed;
}
}
Option 2:
class Dog {}
class Bulldog extends Dog {
}
class Poodle extends Dog {
}
The first option gives the caller the requirement to configure the instance it is creating. In the second option, the class represents the instance itself already (as I see it, which might be totally wrong ..).
If you agree that these classes represent instances instead of blueprints, would you say it is a good practice to create classes that represents instances or is it totally wrong the way I am looking at this and my statement "classes representing instances" is just load of nonsense?
Edited
First of all: We know the Inheritance definition and we can find a lot of examples in SO and internet. But, I think we should look in-depth and a little more scientific.
Note 0:
Clarification about Inheritance and Instance terminology.
First let me name Development Scope for development life cycle, when we are modeling and programming our system and Runtime Scope for sometimes our system is running.
We have Classes and modeling and developing them in Development Scope. And Objects in Runtime Scope. There is no Object in Development Scope.
And in Object Oriented, the definition of Instance is: Creating an Object from a Class.
On the other hand, when we are talking about classes and object, we should clarify our Viewpoint about Development Scope and Runtime Scope.
So, with this introduction, I want to clarify Inheritance:
Inheritance is a relationship between Classes, NOT Objects.
Inheritance can exist in Development Scope, not in Runtime Scope. There is no Inheritance in Runtime Scope.
After running our project, there is no relationship between parent and child (If there is only Inheritance between a child class and parent class). So, the question is: What is super.invokeMethod1() or super.attribute1 ?, they are not the relationship between child and parent. All attributes and methods of a parent are transmitted to the child and that is just a notation to access the parts that transmitted from a parent.
Also, there are not any Objects in Development Scope. So there are not any Instances in Development scope. It is just Is-A and Has-A relationship.
Therefore, when we said:
I would say FileNotFoundException is a instance of an IOException
We should clarify about our Scope (Development and Runtime).
For example, If FileNotFoundException is an instance of IOException, then what is the relationship between a specific FileNotFoundException exception at runtime (the Object) and FileNotFoundException. Is it an instance of instance?
Note 1:
Why we used Inheritance? The goal of inheritance is to extending parent class functionalities (based on the same type).
This extension can happen by adding new attributes or new methods.
Or overriding existing methods.
In addition, by extending a parent class, we can reach to reusability too.
We can not restrict the parent class functionality (Liskov Principle)
We should be able to replace the child as parent in the system (Liskov Principle)
and etc.
Note 2:
The Width and Depth of Inheritance Hierarchies
The Width and Depth of Inheritance can be related to many factors:
The project: The complexity of the project (Type Complexity) and it's architecture and design. The size of the project, the number of classes and etc.
The team: The expertise of a team in controlling the complexity of the project.
and etc.
However, we have some heuristics about it. (Object-Oriented Design Heuristics, Arthur J. Riel)
In theory, inheritance hierarchies should be deep—the deeper, the better.
In practice, inheritance hierarchies should be no deeper than
an average person can keep in his or her short-term memory. A popular
value for this depth is six.
Note that they are heuristics and based on short-term memory number (7). And maybe the expertise of a team affect this number. But in many hierarchies like organizational charts is used.
Note 3:
When we are using Wrong Inheritance?
Based on :
Note 1: the goal of Inheritance (Extending parent class functionalities)
Note 2: the width and depth of Inheritance
In this conditions we use wrong inheritance:
We have some classes in an inheritance hierarchy, without extending parent class functionalities. The extension should be reasonable and should be enough to make a new class. The reasonable means from Observer's point of view. The observer can be Project Architect or Designer (Or other Architects and Designers).
We have a lot of classes in the inheritance hierarchy. It calls Over-Specialization. Some reasons may cause this:
Maybe we did not consider Note 1 (Extending parent functionalities)
Maybe our Modularization (packaging) is not correct. And we put many system use cases in one package and we should make Design Refactoring.
They are other reasons, but not exactly related this answer.
Note 4:
What should we do? When we are using Wrong Inheritance?
Solution 1: We should perform Design Refactoring to check the value of classes in order to Extending parent Functionality. In this refactoring, maybe many classes of system deleted.
Solution 2: We should perform Design Refactoring to modularization. In this refactoring, maybe some classes of our package transmitted to other packages.
Solution 3: Using the Composition over Inheritance.
We can use this technique for many reasons. Dynamic Hierarchy is one of popular reasons that we prefer Composition instead of Inheritance.
see Tim Boudreau (of Sun) notes here:
Object hierarchies don't scale
Solution 4: use instances over Subclasses
This question is about this technique. Let me named it instances over Subclasses.
When we can use it:
(Tip 1): Consider Note 1, when we do not exactly extend the parent class functionalities. Or the extensions are not reasonable and enough.
(Tip 2:) Consider Note 2, If we have a lot of subclasses (semi or identical classes) that extends the parent class a little and we can control this extension without inheritance. Note that it is not easy to say that. We should prove that it is not violating other Object Oriented Principles like Open-Close Principle.
What should we do?
Martin Fowler recommend (Book 1 page 232 and Book 2 page 251):
Replace Subclass with Fields, Change the methods to superclass fields and eliminate the subclasses.
We can use other techniques like enum as the question mentioned.
First, by including the exceptions question along with a general system design issue, you're really asking two different questions.
Exceptions are just complicated values. Their behaviors are trivial: provide the message, provide the cause, etc. And they're naturally hierarchical. There's Throwable at the top, and other exceptions repeatedly specialize it. The hierarchy simplifies exception handling by providing a natural filter mechanism: when you say catch (IOException..., you know you'll get everything bad that happened regarding i/o. Can't get much clearer than that. Testing, which can be ugly for big object hierarchies, is no problem for exceptions: There's little or nothing to test in a value.
It follows that if you are designing similar complex values with trivial behaviors, a tall inheritance hierarchy is a reasonable choice: Different kinds of tree or graph nodes constitute a good example.
Your second example seems to be about objects with more complex behaviors. These have two aspects:
Behaviors need to be tested.
Objects with complex behaviors often change their relationships with each other as systems evolve.
These are the reasons for the often heard mantra "composition over inheritance." It's been well-understood since the mid-90s that big compositions of small objects are generally easier to test, maintain, and change than big inheritance hierarchies of necessarily big objects.
Having said that, the choices you've offered for implementation are missing the point. The question you need to answer is "What are the behaviors of dogs I'm interested in?" Then describe these with an interface, and program to the interface.
interface Dog {
Breed getBreed();
Set<Dog> getFavoritePlaymates(DayOfWeek dayOfWeek);
void emitBarkingSound(double volume);
Food getFavoriteFood(Instant asOfTime);
}
When you understand the behaviors, implementation decisions become much clearer.
Then a rule of thumb for implementation is to put simple, common behaviors in an abstract base class:
abstract class AbstractDog implements Dog {
private Breed breed;
Dog(Breed breed) { this.breed = breed; }
#Override Breed getBreed() { return breed; }
}
You should be able to test such base classes by creating minimal concrete versions that just throw UnsupportedOperationException for the unimplemented methods and verify the implemented ones. A need for any fancier kind of setup is a code smell: you've put too much into the base.
Implementation hierarchies like this can be helpful for reducing boilerplate, but more than 2 deep is a code smell. If you find yourself needing 3 or more levels, it's very likely you can and should wrap chunks of common behavior from the low-level classes in helper classes that will be easier to test and available for composition throughout the system. For example, rather than offering a protected void emitSound(Mp3Stream sound); method in the base class for inheritors to use, it would be far preferable to create a new class SoundEmitter {} and add a final member with this type in Dog.
Then make concrete classes by filling in the rest of the behavior:
class Poodle extends AbstractDog {
Poodle() { super(Breed.POODLE); }
Set<Dog> getFavoritePlaymates(DayOfWeek dayOfWeek) { ... }
Food getFavoriteFood(Instant asOfTime) { ... }
}
Observe: The need for a behavior - that the dog must be able to return its breed - and our decision to implement the "get breed" behavior in an abstract base class resulted in a stored enum value.
We ended up adopting something closer to your Option 1, but this wasn't an a priori choice. It flowed from thinking about behaviors and the cleanest way to implement them.
Following comments are on the condition where sub-classes do not actually extend the functionality of their super class.
From Oracle doc:
Signals that an I/O exception of some sort has occurred. This class is the general class of exceptions produced by failed or interrupted I/O operations.
It says IOException is a general exception. If we have a cause enum:
enum cause{
FileNotFound, CharacterCoding, ...;
}
We will not be able to throw an IOException if the cause in our custom code is not included in the enum. In another word, it makes IOException more specific instead of general.
Assuming we are not programming a library, and the functionality of class Dog below is specific in our business requirement:
enum DogBreed {
Bulldog, Poodle;
}
class Dog {
DogBreed dogBreed;
public Dog(DogBreed dogBreed) {
this.dogBreed = dogBreed;
}
}
Personally I think it is good to use enum because it simplifies the class structure (less classes).
The first code you cite involves exceptions.
Inheritance is a natural fit for exception types because the language-provided construct to differentiate exceptions of interest in the try-catch statement is through use of the type system. This means we can easily choose to handle just a more specific type (FileNotFound), or the more general type (IOException).
Testing a field's value, to see whether to handle an exception, means stepping out of the standard language construct and writing some boiler plate guard code (e.g. test value(s) and rethrow if not interested).
(Further, exceptions need to be extensible across DLL (compilation) boundaries. When we use enums we may have problems extending the design without modifying the source that introduces (and other that consumes) the enum.)
When it comes to things other than exceptions, today's wisdom encourages composition over inheritance as this tends to result in less complex and more maintainable designs.
Your Option 1 is more of a composition example, whereas your Option 2 is clearly an inheritance example.
If you agree that these classes represent instances instead of blueprints, would you say it is a good practice to create classes that represents instances or is it totally wrong the way I am looking at this and my statement "classes representing instances" is just load of nonsense?
I agree with you, and would not say this represents good practice. These classes as shown are not particularly customizable and don't represent added value.
A class that has offers no overrides, no new state, no new methods, is not particularly differentiated from its base. So there is little merit in declaring such a class, unless we seek to do instance-of tests on it (like the exception handling language construct does under the covers). We can't really tell from this example, which is contrived for the purposes of asking the question, whether there is any added value in these subclasses but it doesn't appear so.
To be clear, though, there are lots of worse example of inheritance, such as when an (pre) occupation like Teacher or Student inherits from Person. This means that a Teacher cannot a be Student at the same time unless we engage in adding even more classes, e.g. TeacherStudent, perhaps using multiple inheritance..
We might call this class explosion, as sometimes we end up needing a matrix of classes because of inappropriate is-a relationships. (Add one new class, and you need a whole new row or column of exploded classes.)
Working with a design that suffers class explosion actually creates more work for clients consuming these abstractions, so it is a loose-loose situation.
Here at issue, is in our trust of natural language because when we say someone is-a Student, this is not, from a logical perspective, the same permanent "is-a"/instance-of relationship (of subclassing), but rather a potentially-temporary role being played that the Person: one of many possible roles a Person might play concurrently at that. In these cases composition is clearly superior to inheritance.
In your scenario, however, the BullDog is unlikely to be able to be anything other than the BullDog, so the permanent is-a relationship of subclassing holds, and while adding little value, at least this hierarchy does not risk class explosion.
Note that the main drawback to with the enum approach is that the enum may not be extensible depending on the language you're using. If you need arbitrary extensibility (e.g. by others and without altering your code), you have the choice of using something extensible but more weakly typed, like strings (typos aren't caught, duplicates aren't caught, etc..), or you can use inheritance, as it offers decent extensibility with stronger typing. Exceptions need this kind of extensibility by others without modification and recompilation of the originals and others since they are used across DLL boundaries.
If you control the enum and can recompile the code as a unit as needed to handle new dog types, then you don't need this extensibility.
Option 1 has to list all known causes at declaration time.
Option 2 can be extended by creating new classes, without touching the original declaration.
This is important when the base/original declaration is done by the framework. If there were 100 known, fixed, reasons for I/O problems, an enum or something similar could make sense, but if new ways to communicate can crop up that should also be I/O exceptions, then a class hierarchy makes more sense. Any class library that you add to your application can extend with more I/O exceptions without touching the original declaration.
This is basically the O in the SOLID, open for extension, closed for modification.
But this is also why, as an example, DayOfWeek type of enumerations exists in many frameworks. It is extremely unlikely that the western world suddenly wakes up one day and decides to go for 14 unique days, or 8, or 6. So having classes for those is probably overkill. These things are more fixed in stone (knock-on-wood).
The two options you present do not actually express what I think you're trying to get at. What you're trying to differentiate between is composition and inheritance.
Composition works like this:
class Poodle {
Legs legs;
Tail tail;
}
class Bulldog {
Legs legs;
Tail tail;
}
Both have a common set of characteristics that we can aggregate to 'compose' a class. We can specialize components where we need to, but can just expect that "Legs" mostly work like other legs.
Java has chosen inheritance instead of composition for IOException and FileNotFoundException.
That is, a FileNotFoundException is a kind of (i.e. extends) IOException and permits handling based on the identity of the superclass only (though you can specify special handling if you choose to).
The arguments for choosing composition over inheritance are well-rehearsed by others and can be easily found by searching for "composition vs. inheritance."
Does any programming language provide such a thing?
Where could this be used?
For example:
note that somethingStrange is not a class, its an instance (its underlined) and this is an object diagram
Spec (section 7.3.22) says:
An instance specification is depicted using the same notation as its classifier, but in place of the classifier name appears an underlined concatenation of the instance name (if any), a colon (‘:’) and the classifier name or names.
The convention for showing multiple classifiers is to separate their names by commas.
So im stuck with "multiple classifiers".
Any language with extensional rather than intensional typing will allow such constructs.
For example, in RDF two sources could make claims about a web resource which are completely conflicting, or in a 'duck type' language an object could have all the characteristics of two otherwise unrelated types.
Extensional languages classify objects by their properties - if it has prongs it's a fork, if it's got a handle and a bowl it's a spoon, if it has both prongs and a bowl it is both a fork and a spoon.
The difference between such languages and class oriented intensional languages such as C++/Java/C# to which UML is more commonly applied, is that you don't need a spork class to define things which are both spoons and forks - whether things belong to a classifier is defined by whether they meet the requirements of the classifier.
That's multiple inheritance if you're referring to classes (except that you should use solid edges for generalization), nothing wrong with that ;)
Note that an interface is also a classifier, so also the text of your question needs a bit of refinement -- nothing wrong with generalizing more than one interface, after all.
It's is a Dependency.
Dependency is a weaker form of relationship which indicates that one class depends on another because it uses it at some point of time. One class depends on another if the latter is a parameter variable or local variable of a method of the former. This is different from an association, where an attribute of the former is an instance of the latter.
In other words your somethingStance class will use both Cat and Panzer
The below it is just an example of how it might look like
Public class SomethingStrange{
public Cat CatDependency{get;set;}
public Panzer PanzerDependency{get;set;}
}
UML does allow an object to be instance of several different classes (even if they are unrelated) at the same time. The fact that this is not the normal convention and not supported by programming languages is a different issue. UML tries to be as broad as possible even if specific technologies only can implement a subset of it.
In this video from Google IO 2009, the presenter very quickly says that signatures of methods should return concrete types instead of interfaces.
From what I heard in the video, this has something to do with the GWT Java-to-Javascript compiler.
What's the reason behind this choice ?
What does the interface in the method signature do to the compiler ?
What methods can return interfaces instead of concrete types, and which are better off returning concrete instances ?
This has to do with the gwt-compiler, as you say correctly. EDIT: However, as Daniel noted in a comment below, this does not apply to the gwt-compiler in general but only when using GWT-RPC.
If you declare List instead of ArrayList as the return type, the gwt-compiler will include the complete List-hierarchy (i.e. all types implementing List) in your compiled code. If you use ArrayList, the compiler will only need to include the ArrayList hierarchy (i.e. all types implementing ArrayList -- which usually is just ArrayList itself). Using an interface instead of a concrete class you will pay a penalty in terms of compile time and in the size of your generated code (and thus the amount of code each user has to download when running your app).
You were also asking for the reason: If you use the interface (instead of a concrete class) the compiler does not know at compile time which implementations of these interfaces are going to be used. Thus, it includes all possible implementations.
Regarding your last question: all methods CAN be declared to return interface (that is what you ment, right?). However, the above penalty applies.
And by the way: As I understand it, this problem is not restricted to methods. It applies to all type declarations: variables, parameters. Whenever you use an interface to declare something, the compiler will include the complete hierarchy of sub-interfaces and implementing classes. (So obviously if you declare your own interface with only one or two implementing classes then you are not incurring a big penalty. That is how I use interfaces in GWT.)
In short: use concrete classes whenever possible.
(Small suggestion: it would help if you gave the time stamp when you refer to a video.)
This and other performance tips were presented at Google IO 2011 - High-performance GWT.
At about the 7 min point the speak addresses 'RPC Type Explosion':
For some reason I thought the GWT compiler would optimize it away again but it appears I was mistaken.
If I have a function (say messUp that does not need to access any private variables of a class (say room), should I write the function inside the class like room.messUp() or outside of it like messUp(room)? It seems the second version reads better to me.
There's a tradeoff involved here. Using a member function lets you:
Override the implementation in derived classes, so that messing up a kitchen could involve trashing the cupboards even if no cupboards are available in a generic room.
Decide that you need to access private variables later on, without having to refactor all the code that uses the function.
Make the function part of an interface, so that a piece of code may require that its argument be mess-up-able.
Using an external function lets you:
Make that function generic, so that you may apply it to rooms, warehouses and oil rigs equally (if they provide the member functions required for messing up).
Keep the class signature small, so that creating mock versions for unit testing (or different implementations) becomes easier.
Change the class implementation without having to examine the code for that function.
There's no real way to have your cake and eat it too, so you have to make choices. A common OO decision is to make everything a method (unless clearly idiotic) and sacrifice the three latter points, but that doesn't mean you should do it in all situations.
Any behaviour of a class of objects should be written as an instance method.
So room.messUp() is the OO way to do this.
Whether messUp has to access any private members of the class or not, is irrelevant, the fact that it's a behaviour of the room, suggests that it's an instance method, as would be cleanUp or paint, etc...
Ignoring which language, I think my first question is if messUp is related to any other functions. If you have a group of related functions, I would tend to stick them in a class.
If they don't access any class variables then you can make them static. This way, they can be called without needing to create an instance of the class.
Beyond that, I would look to the language. In some languages, every function must be a method of some class.
In the end, I don't think it makes a big difference. OOP is simply a way to help organize your application's data and logic. If you embrace it, then you would choose room.messUp() over messUp(room).
i base myself on "C++ Coding Standards: 101 Rules, Guidelines, And Best Practices" by Sutter and Alexandrescu, and also Bob Martin's SOLID. I agree with them on this point of course ;-).
If the message/function doesnt interract so much with your class, you should make it a standard ordinary function taking your class object as argument.
You should not polute your class with behaviours that are not intimately related to it.
This is to repect the Single Responsibility Principle: Your class should remain simple, aiming at the most precise goal.
However, if you think your message/function is intimately related to your object guts, then you should include it as a member function of your class.
Interface (or an abstract class with all the methods abstract) is a powerful weapon in a static-typed language such as C#, JAVA. It allows different derived types to be used in a uniformed way. Design patterns encourage us to use interface as much as possible.
However, in a dynamic-typed language, all objects are not checked for their type at compile time. They don't have to implement an interface to be used in a specific way. You just need to make sure that they have some methods (attributes) defined. This makes interface not necessary, or at least not as useful as it is in a static language.
Does a typical dynamic language (e.g. ruby) have interface? If it does, then what are the benefits of having it? If it doesn't, then are we losing many of the beautiful design patterns that require an interface?
Thanks.
I guess there is no single answer for all dynamic languages. In Python, for instance, there are no interfaces, but there is multiple inheritance. Using interface-like classes is still useful:
Interface-like classes can provide default implementation of methods;
Duck-typing is good, but to an extent; sometimes it is useful to be able to write isinstance(x, SomeType), especially when SomeType contains many methods.
Interfaces in dynamic languages are useful as documentation of APIs that can be checked automatically, e.g. by development tools or asserts at runtime.
As an example, zope.interface is the de-facto standard for interfaces in Python. Projects such as Zope and Twisted that expose huge APIs for consumption find it useful, but as far as I know it's not used much outside this type of projects.
In Ruby, which is a dynamically-typed language and only allows single inheritance, you can mimic an "interface" via mixins, rather than polluting the class with the methods of the "interface".
Mixins partially mimic multiple inheritance, allowing an object to "inherit" from multiple sources, but without the ambiguity and complexity of actually having multiple parents. There is only one true parent.
To implement an interface (in the abstract sense, not an actual interface type as in statically-typed languages) You define a module as if it were an interface in a static language. You then include it in the class. Voila! You've gathered the duck type into what is essentially an interface.
Very simplified example:
module Equippable
def weapon
"broadsword"
end
end
class Hero
include Equippable
def hero_method_1
end
def hero_method_2
end
end
class Mount
include Equippable
def mount_method_1
end
end
h = Hero.new
h.weapon # outputs "broadsword"
m = Mount.new
m.weapon # outputs "broadsword"
Equippable is the interface for Hero, Mount, and any other class or model that includes it.
(Obviously, the weapon will most likely be dynamically set by an initializer, which has been simplified away in this example.)