I have a requirement to create some objects that implement a given interface, where the type of concrete implementation being created is based on an Enum value.
I run into trouble when the different concrete implementations require different parameters at runtime.
This example (C#) is fine:
public enum ProductCategory
{
Modem,
Keyboard,
Monitor
}
public class SerialNumberValidatorFactory()
{
public ISerialNumberValidator CreateValidator(ProductCategory productCategory)
{
switch (productCategory)
{
case ProductCategory.Modem:
return new ModemSerialNumberValidator();
case ProductCategory.Keyboard:
return new KeyboardSerialNumberValidator();
case ProductCategory.Monitor:
return new MonitorSerialNumberValidator();
default:
throw new ArgumentException("productType", string.Format("Product category not supported for serial number validation: {0}", productCategory))
}
}
}
However, what happens if the concrete implementations have different constructor arguments? I can't pass in all the values to the SerialNumberValidatorFactory.CreateValidator() method, so how do I proceed?
I've heard the Abstract Factory pattern is supposed to solve this, but I'm not sure how to implement it properly.
You can always create a Settings container to pass to the CreateValidator method. Start with a base IValidatorSettings, then create IModemSerialNumberValidatorSettings etc, your CreateValidator could then take ProductType and IValidatorSettings arguments.
Your concrete classes for the validators would then take their IXXXValidatorSettings interface as the sole constructor argument.
Further to this you could then create an IValidatorSettings factory.
I think abstract factory is a factory that creates a factory to handle a given set of types - not sure if it would apply in your scenario.
What you are using is a Factory Method pattern, what you should use is an Abstract Factory
In abstract factory, you provide a factory class for each concrete implementation:
So your code becomes: (forgive the code, but the rationale is same)
public class SerialNumberValidatorFactory
{
public static SerialNumberValidatorFactory newInstance(
ProductCategory productCategory)
{
switch (productCategory)
{
case ProductCategory.Modem:
return new ModemValidatorFactory();
....
}
}
public abstract ISerialNumberValidator createValidator();
}
public class ModemValidatorFactory extends SerialNumberValidatorFactory
{
public ISerialNumberValidator createValidator()
{
return new ModemSerialNumberValidator("model", "number");
}
}
ISerialNumberValidator = SerialNumberValidatorFactory.newInstance(productCategory).createValidator()
Related
I have an IDirectory interface and a Directory class that implements it.
I need to create an IDirectoryEnumerator which just has a method that looks like so:
IEnumerable<IDirectory> GetDirectories();
So I created a DirectoryEnumerator class, but I'm not sure which IDirectory to return in GetDirectories(), since I want to keep my code loosely-coupled.
Should I use generics with constraints to IDirectory somehow?
Should I get it somehow through a DI container?
Should something like that be tightly-coupled and I should focus on a specific concrete type?
Or is there another better option?
Note: concrete types of IDirectory in my example don't have any default constructors and are immutable.
You could let the concrete IDirectoryEnumerator implementation accept some sort of factory (e.g. IDirectoyFactory) through the constructor, and then use a parametrized method in that factory to create concrete types of IDirectory.
This also makes testing easier and enables you to use a DI container to inject the dependencies.
EXAMPLE:
public interface IDirectoryEnumerator
{
IEnumerable<IDirectory> GetDirectories();
}
public class DirectoryEnumImpl : IDirectoryEnumerator
{
private readonly IDirectoryFactory _directoryFactory;
public DirectoryEnumImpl(IDirectoryFactory directoryFactory)
{
_directoryFactory = directoryFactory;
}
public IEnumberable<IDirectory> GetDirectories()
{
// you can use the factory here
}
}
public interface IDirectoryFactory
{
IDirectory CreateDirectory(DirectoryType directoryType);
}
public class DirectoryFactoryImpl : IDirectoryFactory
{
IDirectory CreateDirectory(DirectoryType directoryType)
{
if (directoryType == DirectoryType.DIR_A)
return new Dir_A();
// the same goes for other types.
}
}
public enum DirectoryType {
DIR_A, DIR_B, // etc ...
}
I have SaveManager Abstract class and my concrete classes TVSaveManager, DataSaveManager and VoiceSaveManager implementing SaveManager Abstract class.
List<SaveManager> lstPrdSaveManager;
public SaveResponseModel SaveProducts(SaveProductsRequest objSaveProductsRequest)
{
SaveResponseModel saveResponseModel = new SaveResponseModel();
lstPrdSaveManager = SaveManagerFactory.GetSaveManagers(objSaveProductsRequest, saveResponseModel);
lstPrdSaveManager.ForEach(saveManager =>
{
saveResponseModel = saveManager.MapAndSaveProduct();
});
return saveResponseModel;
}
Factory class will decide which manager to create and send us the list. I will loop thru the list and invoke the common interface 'MapAndSaveProduct' that every concrete classes will adhere. I guess more or like a strategy pattern.
But the thing is all the concrete savemanage's MapAndSaveProduct method return type is different. TVResponse for TvSaveManager and DataResponse for DataSaveManager and so on. So i created SaveResponseModel class to club all the return types (I am passing SaveResponseModel to factory so that it will get passed to all concrete savemanager class's constructor. Individual class will set the desired property., like TvSaveManager -> saveResponseModel.TvResponse). I get desired result and code looks clean.
Questions are,
1) Is it the correct way to use this pattern when we have different type?
2) If concrete class have different types, should not we use strategy pattern?
3) Should I approach to different design pattern in this case. if yes which one?
You've got a combination of Strategy and Visitor in a single group of methods; this is absolutely OK. You could separate them out by giving the responses a common interface, and adding a visitor to it for harvesting the right response. This would apply two patterns in sequence, rather than applying both at the same time.
interface IResponseVisitor {
void VisitTvResponse(TvResponse r);
void VisitDataResponse(DataResponse r);
}
interface IResponse {
void Accept(IResponseVisitor v);
}
class TvResponse : IResponse {
public void Accept(IResponseVisitor v) {
v.VisitTvResponse(this);
}
}
class DataResponse : IResponse {
public void Accept(IResponseVisitor v) {
v.VisitDataResponse(this);
}
}
Now all your MapAndSaveProduct implementations could return the common IResponse. You could collect them all, and then go through them with an implementation of IResponseVisitor, and do what you need for each type inside the corresponding Accept method.
I have some code in an application that I am not really thrilled about right now. I created a few classes like so:
class Base
{
// base properties ...
}
class DerivedA : Base
{
}
class DerivedB : Base
{
}
I have a method in my application that needs to create one of these objects (with more to come in the future) based on a string property that is stored in the database. Each one of these objects gets its data from slightly different places, but the way I'm doing it right now is just a big if block and it doesn't seem very maintainable:
class BaseCreator
{
Base Create(string name)
{
if (name == "DerivedA" )
return CreateDerivedA();
else if(name == "DerivedB")
return CreateDerivedB();
}
}
What are some ways I can refactor this code to be more maintainable and make it easier to add new types in the future? I am using dependency injection (Ninject) in my application if that makes any difference.
Inheritance trees are always difficult to maintain once they grow. If you know up front that the tree will be large---seriously consider using composition instead of inheritance. Especially if you're already using a DI framework, interfaces are the way to go.
I think you should use the abstract factory pattern which solves this problem.
It provides an interface for creating families of related or dependent objects without specifying their concrete classes.
http://www.dofactory.com/Patterns/PatternAbstract.aspx
Or just a factory pattern
http://www.dotnetperls.com/factory
I will note that your if/else or switch structure is not a bad thing. The bad thing is when you have the same if/else or switch expressed multiple times.
When you have nicely decoupled your code and you are programming to the interface or abstract base rather than the concrete, know that somewhere in your application, something knows how to create the particular concrete instance that you need. This can be code, it can be configuration, it can be some container, etc. But that something has to exist. The idea is to have that something existing once.
Your approach is fine as long as this is the only method where it exists. This class' reason to exist is that it creates the concrete instances that fulfill some interface. Its reason to change is that some other concrete implementation has been added (or removed).
The general case can be solved by a bit of composition and the use of the Specification pattern:
public class Base
{
public abstract bool IsSatisfiedBy(string name);
// base properties ...
}
public class DerivedA : Base
{
public override bool IsSatisfiedBy(string name)
{
return name == "DerivedA";
}
}
public class DerivedB : Base
{
public override bool IsSatisfiedBy(string name)
{
return name == "DerivedB";
}
}
public class BaseCreator
{
private readonly IEnumerable<Base> candidates;
public BaseCreator(IEnumerable<Base> candidates)
{
this.candidates = candidates;
}
public Base Create(string name)
{
return this.candidates.First(c => c.IsSatisfiedBy(name));
}
}
If you really must use strings, you can use reflection:
object GetInstance(string typeName)
{
Type.GetType(typeName).GetConstructor(Type.EmptyTypes).Invoke(new object[0]);
}
You could also use a dictionary:
IDictionary<string, Func<object>> TypeMap = new Dictionary<string, Func<object>>()
{
{ "TypeA", () => new TypeA() },
{ "TypeB", () => new TypeB() },
{ "TypeC", () => new TypeC() },
};
object GetInstance(string typeName)
{
return TypeMap[typeName]();
}
For others landing on this page, consider using generics, if you don't have to use strings:
T CreateInstance<T>()
where T : new()
{
return new T();
}
There isn't a general answer to this question. Abstract Factory may be correct, but it all depends on what the difference is between these implementations and how you use them.
It could well be that you should be using Template, Strategy, State or any other similar pattern. Look into them, and definitely Abstract Factory, and decide on a pattern that suits your specific scenario.
I've just finished Mark Seemann's book Dependency Injection in .NET and I'm now trying to refactor some legacy code. (I am not, at this stage, relying on any particular DI container, rather just trying to move all the dependencies to one place).
I'm looking at the following factory class which determines the ArchiveType by reading the first few bytes of the archive with archiveReader.GetArchiveType() and then returns an instance of an ArchiveRestorer based on the ArchiveType enum.
public class ArchiveRestorerFactory : IArchiveRestorerFactory
{
public ArchiveRestorer Create(ArchiveReader archiveReader)
{
ArchiveType type = archiveReader.GetArchiveType();
switch (type)
{
case ArchiveType.CurrentData:
return new CurrentDataArchiveRestorer(archiveReader);
break;
case ArchiveType.HistoricalData:
return new HistoricalDataArchiveRestorer(archiveReader);
break;
case ArchiveType.AuditTrail:
return new AuditTrailArchiveRestorer(archiveReader);
break;
default:
throw new Exception("ArchiveRestorerFactory error: Unknown value for ArchiveType.");
}
}
}
How do I refactor this so that the class does not depend on the concrete types CurrentDataArchiveRestorer, HistoricalDataArchiveRestorer and AuditTrailArchiveRestorer?
Should I move the three concrete restorers into the factory's constructor?
public ArchiveRestorer Create(ArchiveReader archiveReader,
ArchiveRestorer currentDataArchiveRestorer,
ArchiveRestorer historicalDataArchiveRestorer,
ArchiveRestorer auditTrailDataArchiveRestorer)
{
// guard clauses...
// assign to readonly fields
}
That seems to be the approach suggested here, but then it will instantiate all three restorers when only one is needed? What if I had 20 different possible concrete implementations instead?
I feel like I should be implementing a concrete factory for each type of restorer and returning that instead but then I would just be replacing one new with another.
What is the best way to refactor this?
The way I'd do this, given the code you've already got, would be to create a factory for each of these objects which has a Create() method.
I'd have an interface for these factories also and have them inherit from a general factory interface.
You can then use the interfaces as a point for injection into your constructor.
Which would be called similar to this:
case ArchiveType.CurrentData:
return _currentDateArchiveRestorerFactory.Create(archiveReader);
break;
Alternatively, it might be better to have a single factory that creates an instance of a given type. Since all of these objects are restorers you could just create the instance based on the enum rather than a switch.
_restorerFactory.Create(ArchiveType.CurrentData);
Why not make the ArchiveReader responsible for creating the appropriate ArchiveRestorer? Then the first iteration of the code would look like this:
public class ArchiveRestorerFactory : IArchiveRestorerFactory
{
public ArchiveRestorer Create(ArchiveReader archiveReader)
{
ArchiveRestorer restorer = archiveReader.GetArchiveRestorer();
return restorer;
}
}
By then, it should be pretty obvious that the factory is redundant, so in the second iteration of the code you can throw it away let the consumers invoke the ArchiveReader directly.
Make one interface with one method with returns type of that interface and let three archiver classes implement that interface and then in the create method the parameter type would be just the interface and it will return the required object by calling the method of interface you just created. So you don't need concrete type in create method.
interface ILogger
{
void Log(string data);
}
class Logger : ILogger
{
.
.
.
}
At this point, you use an intermediate factory object to return the logger to be used within the component:
class MyComponent
{
void DoSomeWork()
{
// Get an instance of the logger
ILogger logger = Helpers.GetLogger();
// Get data to log
string data = GetData();
// Log
logger.Log(data);
}
}
class Helpers
{
public static ILogger GetLogger()
{
// Here, use any sophisticated logic you like
// to determine the right logger to instantiate.
ILogger logger = null;
if (UseDatabaseLogger)
{
logger = new DatabaseLogger();
}
else
{
logger = new FileLogger();
}
return logger;
}
}
class FileLogger : ILogger
{
.
.
.
}
class DatabaseLogger : ILogger
{
.
.
.
}
I would solve this problem by agreeing on a naming convention and utilizing Unity's ability to name registrations. Example of this here: https://dannyvanderkraan.wordpress.com/2015/06/29/real-world-example-of-dependency-injection-based-on-run-time-values/
I'm still trying to get a better understanding of Interfaces. I know about what they are and how to implement them in classes.
What I don't understand is when you create a variable that is of one of your Interface types:
IMyInterface somevariable;
Why would you do this? I don't understand how IMyInterface can be used like a class...for example to call methods, so:
somevariable.CallSomeMethod();
Why would you use an IMyInterface variable to do this?
You are not creating an instance of the interface - you are creating an instance of something that implements the interface.
The point of the interface is that it guarantees that what ever implements it will provide the methods declared within it.
So now, using your example, you could have:
MyNiftyClass : IMyInterface
{
public void CallSomeMethod()
{
//Do something nifty
}
}
MyOddClass : IMyInterface
{
public void CallSomeMethod()
{
//Do something odd
}
}
And now you have:
IMyInterface nifty = new MyNiftyClass()
IMyInterface odd = new MyOddClass()
Calling the CallSomeMethod method will now do either something nifty or something odd, and this becomes particulary useful when you are passing in using IMyInterface as the type.
public void ThisMethodShowsHowItWorks(IMyInterface someObject)
{
someObject.CallSomeMethod();
}
Now, depending on whether you call the above method with a nifty or an odd class, you get different behaviour.
public void AnotherClass()
{
IMyInterface nifty = new MyNiftyClass()
IMyInterface odd = new MyOddClass()
// Pass in the nifty class to do something nifty
this.ThisMethodShowsHowItWorks(nifty);
// Pass in the odd class to do something odd
this.ThisMethodShowsHowItWorks(odd);
}
EDIT
This addresses what I think your intended question is - Why would you declare a variable to be of an interface type?
That is, why use:
IMyInterface foo = new MyConcreteClass();
in preference to:
MyConcreteClass foo = new MyConcreteClass();
Hopefully it is clear why you would use the interface when declaring a method signature, but that leaves the question about locally scoped variables:
public void AMethod()
{
// Why use this?
IMyInterface foo = new MyConcreteClass();
// Why not use this?
MyConcreteClass bar = new MyConcreteClass();
}
Usually there is no technical reason why the interface is preferred. I usually use the interface because:
I typically inject dependencies so the polymorphism is needed
Using the interface clearly states my intent to only use members of the interface
The one place where you would technically need the interface is where you are utilising the polymorphism, such as creating your variable using a factory or (as I say above) using dependency injection.
Borrowing an example from itowlson, using concrete declaration you could not do this:
public void AMethod(string input)
{
IMyInterface foo;
if (input == "nifty")
{
foo = new MyNiftyClass();
}
else
{
foo = new MyOddClass();
}
foo.CallSomeMethod();
}
Because this:
public void ReadItemsList(List<string> items);
public void ReadItemsArray(string[] items);
can become this:
public void ReadItems(IEnumerable<string> items);
Edit
Think of it like this:
You have to be able to do this.
rather than:
You have to be this.
Essentially this is a contract between the method and it's callers.
Using interface variables is the ONLY way to allow handler methods to be written which can accept data from objects that have different base classes.
This is about as clear as anyone is going to get.
An interface is used so you do not need to worry about what class implements the interface. An example of this being useful is when you have a factory method that returns a concrete implementation that may be different depending on the environment you are running in. It also allows an API designer to define the API while allowing 3rd parties to implement the API in any way they see fit. Sun does this with it's cryptographic API's for Java.
public interface Foo {
}
public class FooFactory {
public static Foo getInstance() {
if(os == 'Windows') return new WinFoo();
else if(os == 'OS X') return new MacFoo();
else return new GenricFoo();
}
}
Your code that uses the factory only needs to know about Foo, not any of the specific implementations.
I was in same position and took me few days to figure out why do we have to use interface variable.
IDepartments rep = new DepartmentsImpl();
why not
DepartmentsImpl rep = new DepartmentsImpl();
Imagine If a class implements two interfaces that contain a member with the same signature, then implementing that member on the class will cause both interfaces to use that member as their implementation.
class Test
{
static void Main()
{
SampleClass sc = new SampleClass();
IControl ctrl = (IControl)sc;
ISurface srfc = (ISurface)sc;
// The following lines all call the same method.
sc.Paint();
ctrl.Paint();
srfc.Paint();
}
}
interface IControl
{
void Paint();
}
interface ISurface
{
void Paint();
}
class SampleClass : IControl, ISurface
{
// Both ISurface.Paint and IControl.Paint call this method.
public void Paint()
{
Console.WriteLine("Paint method in SampleClass");
}
}
// Output:
// Paint method in SampleClass
// Paint method in SampleClass
// Paint method in SampleClass
If the two interface members do not perform the same function, however, this can lead to an incorrect implementation of one or both of the interfaces.
public class SampleClass : IControl, ISurface
{
void IControl.Paint()
{
System.Console.WriteLine("IControl.Paint");
}
void ISurface.Paint()
{
System.Console.WriteLine("ISurface.Paint");
}
}
The class member IControl.Paint is only available through the IControl interface, and ISurface.Paint is only available through ISurface. Both method implementations are separate, and neither is available directly on the class. For example:
IControl c = new SampleClass();
ISurface s = new SampleClass();
s.Paint();
Please do correct me if i am wrong as i am still learning this Interface concept.
Lets say you have class Boat, Car, Truck, Plane.
These all share a common method TakeMeThere(string destination)
You would have an interface:
public interface ITransportation
{
public void TakeMeThere(string destination);
}
then your class:
public class Boat : ITransportation
{
public void TakeMeThere(string destination) // From ITransportation
{
Console.WriteLine("Going to " + destination);
}
}
What you're saying here, is that my class Boat will do everything ITransportation has told me too.
And then when you want to make software for a transport company. You could have a method
Void ProvideServiceForClient(ITransportation transportationMethod, string whereTheyWantToGo)
{
transportationMethod.TakeMeThere(whereTheyWantToGo); // Cause ITransportation has this method
}
So it doesn't matter which type of transportation they want, because we know it can TakeMeThere
This is not specific to C#,so i recommend to move to some othere flag.
for your question,
the main reason why we opt for interface is to provide a protocol between two components(can be a dll,jar or any othere component).
Please refer below
public class TestClass
{
static void Main()
{
IMyInterface ob1, obj2;
ob1 = getIMyInterfaceObj();
obj2 = getIMyInterfaceObj();
Console.WriteLine(ob1.CallSomeMethod());
Console.WriteLine(obj2.CallSomeMethod());
Console.ReadLine();
}
private static bool isfirstTime = true;
private static IMyInterface getIMyInterfaceObj()
{
if (isfirstTime)
{
isfirstTime = false;
return new ImplementingClass1();
}
else
{
return new ImplementingClass2();
}
}
}
public class ImplementingClass1 : IMyInterface
{
public ImplementingClass1()
{
}
#region IMyInterface Members
public bool CallSomeMethod()
{
return true;
}
#endregion
}
public class ImplementingClass2 : IMyInterface
{
public ImplementingClass2()
{
}
#region IMyInterface Members
public bool CallSomeMethod()
{
return false;
}
#endregion
}
public interface IMyInterface
{
bool CallSomeMethod();
}
Here the main method does not know about the classes still it is able to get different behaviour using the interface.
The purpose of the Interface is to define a contract between several objects, independent of specific implementation.
So you would usually use it when you have an Intrace ISomething, and a specific implementation
class Something : ISomething
So the Interface varialbe would come to use when you instantiate a contract:
ISomething myObj = new Something();
myObj.SomeFunc();
You should also read interface C#
Update:
I will explaing the logic of using an Interface for the variable and not the class itself by a (real life) example:
I have a generic repositor interace:
Interface IRepository {
void Create();
void Update();
}
And i have 2 seperate implementations:
class RepositoryFile : interface IRepository {}
class RepositoryDB : interface IRepository {}
Each class has an entirely different internal implementation.
Now i have another object, a Logger, that uses an already instansiated repository to do his writing. This object, doesn't care how the Repository is implemented, so he just implements:
void WriteLog(string Log, IRepository oRep);
BTW, this can also be implemented by using standard classes inheritance. But the difference between using interfaces and classes inheritance is another discussion.
For a slightly more details discussion on the difference between abstract classes and interfaces see here.
Say, for example, you have two classes: Book and Newspaper. You can read each of these, but it wouldn't really make sense for these two to inherit from a common superclass. So they will both implement the IReadable interface:
public interface IReadable
{
public void Read();
}
Now say you're writing an application that will read books and newspapers for the user. The user can select a book or newspaper from a list, and that item will be read to the user.
The method in your application that reads to the user will take this Book or Newspaper as a parameter. This might look like this in code:
public static void ReadItem(IReadable item)
{
item.Read();
}
Since the parameter is an IReadable, we know that the object has the method Read(), thus we call it to read it to the user. It doesn't matter whether this is a Book, Newspaper, or anything else that implements IReadable. The individual classes implement exactly how each item will be read by implementing the Read() method, since it will most likely be different for the different classes.
Book's Read() might look like this:
public void Read()
{
this.Open();
this.TurnToPage(1);
while(!this.AtLastPage)
{
ReadText(this.CurrentPage.Text);
this.TurnPage();
}
this.Close();
}
Newspaper's Read() would likely be a little different:
public void Read()
{
while(!this.OnBackPage)
{
foreach(Article article in this.CurrentPage.Articles)
{
ReadText(article.Text);
}
}
}
The point is that the object contained by a variable that is an interface type is guaranteed to have a specific set of methods on it, even if the possible classes of the object are not related in any other way. This allows you to write code that will apply to a variety of classes that have common operations that can be performed on them.
No, it is not possible. Designers did not provide a way. Of course, it is of common sense also. Because interface contains only abstract methods and as abstract methods do not have a body (of implementation code), we cannot create an object..
Suppose even if it is permitted, what is the use. Calling the abstract method with object does not yield any purpose as no output. No functionality to abstract methods.
Then, what is the use of interfaces in Java design and coding. They can be used as prototypes from which you can develop new classes easily. They work like templates for other classes that implement interface just like a blue print to construct a building.
I believe everyone is answering the polymorphic reason for using an interface and David Hall touches on partially why you would reference it as an interface instead of the actual object name. Of course, being limited to the interface members etc is helpful but the another answer is dependency injection / instantiation.
When you engineer your application it is typically cleaner, easier to manage, and more flexible if you do so utilizing dependency injection. It feels backwards at first if you've never done it but when you start backtracking you'll wish you had.
Dependency injection normally works by allowing a class to instantiate and control the dependencies and you just rely on the interface of the object you need.
Example:
Layer the application first. Tier 1 logic, tier 2 interface, tier 3 dependency injection. (Everyone has their own way, this is just for show).
In the logic layer you reference the interfaces and dependency layer and then finally you create logic based on only the interfaces of foreign objects.
Here we go:
public IEmployee GetEmployee(string id)
{
IEmployee emp = di.GetInstance<List<IEmployee>>().Where(e => e.Id == id).FirstOrDefault();
emp?.LastAccessTimeStamp = DateTime.Now;
return emp;
}
Notice above how we use di.GetInstance to get an object from our dependency. Our code in that tier will never know or care about the Employee object. In fact if it changes in other code it will never affect us here. If the interface of IEmployee changes then we may need to make code changes.
The point is, IEmployee emp = never really knows what the actual object is but does know the interface and how to work with it. With that in mind, this is when you want to use an interface as opposed to an object becase we never know or have access to the object.
This is summarized.. Hopefully it helps.
This is a fundamental concept in object-oriented programming -- polymorphism. (wikipedia)
The short answer is that by using the interface in Class A, you can give Class A any implementation of IMyInterface.
This is also a form of loose coupling (wikipedia) -- where you have many classes, but they do not rely explicitly on one another -- only on an abstract notion of the set of properties and methods that they provide (the interface).