Boring intro:
I know - DDD isn't about technology. As i see it - DDD is all about creating ubiquitous language with product owner and reflecting it into code in such a simple and structured manner, that it just can't be misinterpreted or lost.
But here comes a paradox into play - in order to get rid of technical side of application in domain model, it gets kind a technical - at least from design perspective.
Last time i tried to follow DDD - it ended up with whole logic outside of domain objects into 'magic' services all around and anemic domain model.
I've learnt some new ninja tricks and wondering if I could handle Goliath this time.
Problem:
class store : aggregateRoot {
products;
addProduct(product){
if (new FreshSpecification.IsSatisfiedBy(product))
products.add(product);
}
}
class product : entity {
productType;
date producedOn;
}
class productTypeValidityTerm : aggregateRoot {
productType;
days;
}
FreshSpecification is supposed to specify if product does not smell. In order to do that - it should check type of product, find by it days how long product is fresh and compare it with producedOn. Kind a simple.
But here comes problem - productTypeValidityTerm and productType are supposed to be managed by client. He should be able to freely add/modify those. Because I can't traverse from product to productTypeValidityTerm directly, i need to somehow query them by productType.
Previously - i would create something like ProductService that receives necessary repositories through constructor, queries terms, performs some additional voodoo and returns boolean (taking relevant logic further away from object itself and scattering it who knows where).
I thought that it might be acceptable to do something like this:
addProduct(product, productTypeValidityTermRepository){...}
But then again - i couldn't compose specification from multiple specifications underneath freely what's one of their main advantages.
So - the question is, where to do that? How store can be aware of terms?
With the risk of oversimplifying things: why not make the fact whether a Product is fresh something a product "knows"? A Store (or any other kind of related object) should not have to know how to determine whether a product is still fresh; in other words, the fact that something like freshSpecification or productTypeValidityTerm even exist should not be known to Store, it should simply check Product.IsFresh (or possibly some other name that aligns better with the real world, like ShouldbeSoldBy, ExpiresAfter, etc.). The product could then be aware how to actually retrieve the protductTypeValidityTerm by injecting the repository dependency.
It sounds to me like you are externalizing behavior which should be intrinsic to your domain aggregates/entities, eventually leading (again) to an anemic domain model.
Of course, in a more complicated scenario, where freshness depends on context (e.g., what's acceptable in a budget store is not deemed worthy for sale at a premium outlet) you'd need to externalize the entire behavior, both from product and from store, and create a different type altogether to model this particular behavior.
Added after comment
Something along these lines for the simple scenario I mentioned: make the FreshSpec part of the Product aggregate, which allows the ProductRepository (constructor-injected here) to (lazy) load it when needed.
public class Product {
public ProductType ProductType { get; set; }
public DateTime ProducedOn { get; set; }
private FreshSpecification FreshSpecification { get; set; }
public Product(IProductRepository productRepository) { }
public bool IsFresh() {
return FreshSpecification
.IsSatisfiedBy(ProductType, ProducedOn);
}
}
The store doesn't know about these internals: all it cares about is whether or not the product is fresh:
public class Store {
private List<Product> Products = new List<Product>();
public void AddProduct(Product product) {
if (product.IsFresh()) {
Products.Add(product);
}
}
}
Related
I have a hard time understanding how to combine a rule-based decision making approach for an agent in an agent-based model I try to develop.
The interface of the agent is a very simple one.
public interface IAgent
{
public string ID { get; }
public Action Percept(IPercept percept);
}
For the sake of the example, let's assume that the agents represent Vehicles which traverse roads inside a large warehouse, in order to load and unload their cargo. Their route (sequence of roads, from the start point until the agent's destination) is assigned by another agent, the Supervisor. The goal of a vehicle agent is to traverse its assigned route, unload the cargo, load a new one, receive another assigned route by the Supervisor and repeat the process.
The vehicles must also be aware of potential collisions, for example at intersection points, and give priority based on some rules (for example, the one carrying the heaviest cargo has priority).
As far as I can understand, this is the internal structure of the agents I want to build:
So the Vehicle Agent can be something like:
public class Vehicle : IAgent
{
public VehicleStateUpdater { get; set; }
public RuleSet RuleSet { get; set; }
public VehicleState State { get; set; }
public Action Percept(IPercept percept)
{
VehicleStateUpdater.UpdateState(VehicleState, percept);
Rule validRule = RuleSet.Match(VehicleState);
VehicleStateUpdater.UpdateState(VehicleState, validRule);
Action nextAction = validRule.GetAction();
return nextAction;
}
}
For the Vehicle agent's internal state I was considering something like:
public class VehicleState
{
public Route Route { get; set; }
public Cargo Cargo { get; set; }
public Location CurrentLocation { get; set; }
}
For this example, 3 rules must be implemented for the Vehicle Agent.
If another vehicle is near the agent (e.g. less than 50 meters), then the one with the heaviest cargo has priority, and the other agents must hold their position.
When an agent reaches their destination, they unload the cargo, load a new one and wait for the Supervisor to assign a new route.
At any given moment, the Supervisor, for whatever reason, might send a command, which the recipient vehicle must obey (Hold Position or Continue).
The VehicleStateUpdater must take into consideration the current state of the agent, the type of received percept and change the state accordingly. So, in order for the state to reflect that e.g. a command was received by the Supervisor, one can modify it as follows:
public class VehicleState
{
public Route Route { get; set; }
public Cargo Cargo { get; set; }
public Location CurrentLocation { get; set; }
// Additional Property
public RadioCommand ActiveCommand { get; set; }
}
Where RadioCommand can be an enumeration with values None, Hold, Continue.
But now I must also register in the agent's state if another vehicle is approaching. So I must add another property to the VehicleState.
public class VehicleState
{
public Route Route { get; set; }
public Cargo Cargo { get; set; }
public Location CurrentLocation { get; set; }
public RadioCommand ActiveCommand { get; set; }
// Additional properties
public bool IsAnotherVehicleApproaching { get; set; }
public Location ApproachingVehicleLocation { get; set; }
}
This is where I have a huge trouble understanding how to proceed and I get a feeling that I do not really follow the correct approach. First, I am not sure how to make the VehicleState class more modular and extensible. Second, I am not sure how to implement the rule-based part that defines the decision making process. Should I create mutually exclusive rules (which means every possible state must correspond to no more than one rule)? Is there a design approach that will allow me to add additional rules without having to go back-and-forth the VehicleState class and add/modify properties in order to make sure that every possible type of Percept can be handled by the agent's internal state?
I have seen the examples demonstrated in the Artificial Intelligence: A Modern Approach coursebook and other sources but the available examples are too simple for me to "grasp" the concept in question when a more complex model must be designed.
I would be grateful if someone can point me in the right direction concerning the implementation of the rule-based part.
I am writing in C# but as far as I can tell it is not really relevant to the broader issue I am trying to solve.
UPDATE:
An example of a rule I tried to incorporate:
public class HoldPositionCommandRule : IAgentRule<VehicleState>
{
public int Priority { get; } = 0;
public bool ConcludesTurn { get; } = false;
public void Fire(IAgent agent, VehicleState state, IActionScheduler actionScheduler)
{
state.Navigator.IsMoving = false;
//Use action scheduler to schedule subsequent actions...
}
public bool IsValid(VehicleState state)
{
bool isValid = state.RadioCommandHandler.HasBeenOrderedToHoldPosition;
return isValid;
}
}
A sample of the agent decision maker that I also tried to implement.
public void Execute(IAgentMessage message,
IActionScheduler actionScheduler)
{
_agentStateUpdater.Update(_state, message);
Option<IAgentRule<TState>> validRule = _ruleMatcher.Match(_state);
validRule.MatchSome(rule => rule.Fire(this, _state, actionScheduler));
}
I see your question as containing two main sub-questions:
modeling flexibility, particularly on how to make it easier to add properties and rules to the system.
how to come up with the right set of rules and how to organize them so the agent works properly.
so let's go to each of them.
Modeling Flexibility
I think what you have now is not too bad, actually. Let me explain why.
You express the concern about there being "a design approach that will allow me to add additional rules without having to go back-and-forth the VehicleState class and add/modify properties".
I think the answer to that is "no", unless you follow the completely different path of having agents learning rules and properties autonomously (as in Deep Reinforcement Learning), which comes with its own set of difficulties.
If you are going to manually encode the agent knowledge as described in your question, then how would you avoid the need to introduce new properties as you add new rules? You could of course try to anticipate all properties you will need and not allow yourself to write rules that need new properties, but the nature of new rules is to bring new aspects of the problem, which will often require new properties. This is not unlike software engineering, which requires multiple iterations and changes.
Rule-based Modeling
There are two types of way of writing rules: imperative and declarative.
In imperative style, you write the conditions required to take an action. You must also take care of choosing one action over the other when both apply (perhaps with a priority system). So you can have a rule for moving along a route, and another for stopping when a higher-priority vehicle approaches. This seems to be the approach you are currently pursuing.
In declarative style, you declare what the rules of your environment are, how actions affect the environment, and what you care about (assigning utilities to particular states or sub-states), and let a system process all that to compute the optimal action for you. So here you declare how taking a decision to move affects your position, you declare how collisions happen, and you declare that reaching the end of your route is good and colliding is bad. Note that here you don't have rules making a decision; the system uses the rules to determine the action with the greatest value given a particular situation.
One intuitive way to understand the difference between imperative and declarative styles is to think about writing an agent that plays chess. In an imperative style, the programmer encodes the rules of chess, but also how to play chess, how to open the game, how to choose the best movement, and so on. That is to say, the system will reflect the chess skills of the programmer. In a declarative style, the programmer simply encodes the rules of chess, and how the system can explore those rules automatically and identify the best move. In this case, the programmer doesn't need to know how to play chess well for the program to actually play a decent game of chess.
The imperative style is simpler to implement, but less flexible, and can get really messy as the complexity of your system grows. You have to start thinking about all sorts of scenarios, like what to do when three vehicles meet, for example. In the chess example, imagine if we alter a rule of chess slightly; the whole system needs to be reviewed! In a way, there is little "artificial intelligence" and "reasoning" in an imperative style system, because it is the programmer who is doing all the reasoning in advance, coming up with all the solutions and encoding them. It is just a regular program, as opposed to an artificial intelligence program. This seems to be the sort of difficulty you are talking about.
The declarative style is more elegant and extensible. You don't need to figure out how to determine the best action; the system does it for you. In the chess example, you can easily alter one rule of chess in the code, and the system will use the new rule to find the best moves in the altered game. However, it requires an inference engine, the piece of software that knows how to take in a lot of rules and utilities and decide which is the best action. Such an inference engine is the "artificial intelligence" in the system. It automatically considers all possible scenarios (not necessarily one by one, as it will typically employ smarter techniques that consider classes of scenarios) and determines the best action in each of them. However, an inference engine is complex to implement or, if you use an existing one, it is probably very limited since those are typically research packages. I believe that when it comes to real practical applications using the declarative approach people pretty much write a bespoke system for their particular needs.
I found a couple of research open source projects along those lines (see below); that will give you an idea of what is available. As you can see, those are research projects and relatively limited in scope.
After all that, how to proceed? I don't know what your particular goals are. If you are developing a toy problem to practice, your current imperative style system may be enough. If you want to learn about declarative style, a deeper reading of the AIMA textbook would be good. The authors maintain an open source repository with implementations for some of the algorithms in the book, too.
https://www.jmlr.org/papers/v18/17-156.html
https://github.com/douthwja01/OpenMAS
https://smartgrid.ieee.org/newsletters/may-2021/multi-agent-opendss-an-open-source-and-scalable-distribution-grid-platform
I have searched every way I can think of for the answer to this, so forgive me if I have overlooked a post...
I have a project containing model classes that I want to remain database-ignorant (pretend someone handed me the code and said "you're not allowed to modify one character of these classes"). I want to persist these to SQL Server using Entity Framework. So far, I have been able to use the fluent API to map anything that EF couldn't determine logically. But I have hit a block with the following:
public class PhotoPost {
// mapped as Key with fluent API - comes from blog provider
public string PostID { get; set; }
public string Caption { get; set; }
public Collection<Photo> Photos { get; set; }
}
public class Photo {
public string Url { get; set; }
public Image LoadImage() { … }
}
I have a class, PhotoPost, which represents a type of Post on a Blog. The PhotoPost instance has a collection of objects of type Photo, all of which need to be persisted to the database. My problem is that the Photo doesn't really have a primary key. Blog provider doesn't guarantee the Url will not change, and I can't touch this code to add an arbitrary ID. Furthermore, I don't really want an ID. The code that is going to interact with these objects shouldn't/won't know whether these objects came from the blog's API or from a local database (or XML, ...), so I don't really want to clutter up my code with boilerplate in subclassing these objects in another project just to add IDs everywhere (and constructors to create subclasses with IDs from parent classes without, as above) to make EF happy.
Is subclassing to add IDs my only option, or is there a way that I can meet in the middle, between "entity" and "complex type"? (From what I understand, complex types must be one-to-one with their parent entities.)
I know similar questions have been discussed several times, but my problem is slightly different, I guess. I'm experimenting with application architecture based on Domain Driven Design, using repository pattern for data access and Entity Framework infrastructure.
What I'm trying to accomplish is to have unit testable system which would have awareness of unit of works as well.
I like a design where there are core services in the system which take care of all the business logic in the application, i.e. you have some sort of CustomerService.AddOrder(int customerId, Order order) instead of ICustomerRepository.Find(int id).Orders.Add(Order order). You have a easier and intuitive interface to work with using this approach.
(Of course the CustomerService is dependent on ICustomerRepository and probably IOrderRepository as well, but it'll take care of the logic itself).
But! here comes the unit of work problem with this approach:
I'd like to have controllable unit of works inside the core services, i.e. I need to be able to start a new unit of work, do the job and DISPOSE it.
One way of doing this that I came up with is:
public interface IUnitOfWork
{
ICustomerRepository CustomerRepository { get; set; }
IOrderRepository OrderRepository { get; set; }
}
public interface IUnitOfWorkFactory
{
void New(Action<IUnitOfWork> work); // this will let you create and then dispose a new instance of IUnitOfWork implementation
}
public class CustomerService
{
private IUnitOfWorkFactory _uow { get; private set; }
public CustomerService(IUnitOfWorkFactory uowFactory)
{
_uow = uowFactory;
}
public void AddNewOrder(int id, string newName)
{
_uow.New(work =>
{
var customer = work.CustomerRepository.Find(id);
// Do some other required stuff
work.Commit();
});
}
}
After that you just have to create implementations for IUnitOfWorkFactory, IUnitOfWork and repositories; in the client code you just have to depend on CustomerService and that will be easily taken care of by IOC containers.
I like this approach, because it's kinda compact, well structured, logically organised and intuitive, but THE PROBLEM is that I don't know how to correctly UNIT test the services (e.g. behavioral testing). Integration tests are easy, but they are not my concern at this point.
Any ideas will be appreciated.
Many thanks!
What you just described are a form of domain services. I tend not to expose my domain code to the UoW, but admittedly, that's a personal preference. Having domain services control UoW scope gives them a responsibility they shouldn't have (it's an application service at that point). Instead, I'd have the domain service depend on the repositories (and optionally other services) it needs to collaborate with (makes it explicit enough but not confusing). You seem to be introducing interfaces for the purpose of making it testable/pluggable, but you're not gaining much from them at this point. Might a better strategy not be to take a dependency on an inmemory dbcontext (EF)? I believe there's a nuget package for that. That way, you could inject the inmemory dbcontext in the repository (I'm assuming you'd want to keep these) implementations. The SUT factory (the thing that creates the system under test, i.e. something that creates a domain service in this case) could then wire everything together, allowing you to control and assert using the inmemory dbcontext. Alternatively you could create your own inmemory repositories, or use mocking (but that's gonna be brittle and a world of pain). As you write your first few tests, keep watching out for verbosity, and refactor it relentlessly. Not doing so is going to make those tests either cumbersome to write or a burden to maintain in the long haul.
Maybe you could create a UnitOfWorkScope class that manages your active UnitOfWorks:
private CustomerRepository customerRepository;
'...
using (UnitOfWorkScope scope = new UnitOfWorkScope())
{
customer = customerRepository.GetByID(id);
customer.BuySomething(price)
'...
scope.complete()
}
End Using
This questions doesn't let me sleep as it's since one year I'm trying to find a solution but... still nothing happened in my mind. Probably you can help me, because I think this is a very common issue.
I've a n-layered application: presentation layer, business logic layer, model layer. Suppose for simplicity that my application contains, in the presentation layer, a form that allows a user to search for a customer. Now the user fills the filters through the UI and clicks a button. Something happens and the request arrives to presentation layer to a method like CustomerSearch(CustomerFilter myFilter). This business logic layer now keeps it simple: creates a query on the model and gets back results.
Now the question: how do you face the problem of loading data? I mean business logic layer doesn't know that that particular method will be invoked just by that form. So I think that it doesn't know if the requesting form needs just the Customer objects back or the Customer objects with the linked Order entities.
I try to explain better:
our form just wants to list Customers searching by surname. It has nothing to do with orders. So the business logic query will be something like:
(from c in ctx.CustomerSet
where c.Name.Contains(strQry) select c).ToList();
now this is working correctly. Two days later your boss asks you to add a form that let you search for customers like the other and you need to show the total count of orders created by each customer. Now I'd like to reuse that query and add the piece of logic that attach (includes) orders and gets back that.
How would you front this request?
Here is the best (I think) idea I had since now. I'd like to hear from you:
my CustomerSearch method in BLL doesn't create the query directly but passes through private extension methods that compose the ObjectQuery like:
private ObjectQuery<Customer> SearchCustomers(this ObjectQuery<Customer> qry, CustomerFilter myFilter)
and
private ObjectQuery<Customer> IncludeOrders(this ObjectQuery<Customer> qry)
but this doesn't convince me as it seems too complex.
Thanks,
Marco
Consider moving to DTO's for the interface between the presentation layer and the business layer, see for example:- http://msdn.microsoft.com/en-us/magazine/ee236638.aspx
Something like Automapper can relieve much of the pain associated with moving to DTOs and the move will make explicit what you can and cannot do with the results of a query, i.e. if it's on the DTO it's loaded, if it's not you need a different DTO.
Your current plan sounds a rather too tightly coupled between presentation layer and data layer.
I would agree with the comment from Hightechrider in reference to using DTOs, however you have a valid question with regard to business entities.
One possible solution (I'm using something along these lines on a project I'm developing) is to use DTOs that are read-only (at least from the presentation layer perspective. Your query/get operations would only return DTOs, this would give you the lazy loading capability.
You could setup your business layer to return an Editable object that wraps the DTO when an object/entity is updated/created. Your editable object could enforce any business rules and then when it was saved/passed to the business layer the DTO it wrapped (with the updated values) could be passed to the data layer.
public class Editable
{
//.......initialize this, other properties/methods....
public bool CanEdit<TRet>(Expression<Func<Dto, TRet>> property)
{
//do something to determine can edit
return true;
}
public bool Update<TRet>(Expression<Func<Dto, TRet>> property, TRet updatedValue)
{
if (CanEdit(property))
{
//set the value on the property of the DTO (somehow)
return true;
}
return false;
}
public Dto ValueOf { get; private set;}
}
This gives you the ability to enforce if the user can get editable objects from the business layer as well as allowing the business object to enforce if the user has permission to edit specific properties of an object. A common problem I run into with the domain I work in is that some users can edit all of the properties and others can not, while anyone can view the values of the properties. Additionally the presentation layer gains the ability to determine what to expose as editable to the user as dictated and enforced by the business layer.
Other thought I had is can't your Business Layer expose IQueryable or take standard expressions as arguments that you pass to your data layer. For example I have a page building query something like this:
public class PageData
{
public int PageNum;
public int TotalNumberPages;
public IEnumerable<Dto> DataSet;
}
public class BL
{
public PageData GetPagedData(int pageNum, int itemsPerPage, Expression<Func<Dto, bool>> whereClause)
{
var dataCt = dataContext.Dtos.Where(whereClause).Count();
var dataSet = dataContext.Dtos.Where(whereClause).Skip(pageNum * itemsPerPage).Take(itemsPerPage);
var ret = new PageData
{
//init this
};
return ret;
}
}
Sorry to ask sich a generic question, but I've been studying these and, outside of say the head programming conveying what member MUST be in a class, I just don't see any benefits.
There are two (basic) parts to object oriented programming that give newcomers trouble; the first is inheritance and the second is composition. These are the toughest to 'get'; and once you understand those everything else is just that much easier.
What you're referring to is composition - e.g., what does a class do? If you go the inheritance route, it derives from an abstract class (say Dog IS A Animal) . If you use composition, then you are instituting a contract (A Car HAS A Driver/Loan/Insurance). Anyone that implements your interface must implement the methods of that interface.
This allows for loose coupling; and doesn't tie you down into the inheritance model where it doesn't fit.
Where inheritance fits, use it; but if the relationship between two classes is contractual in nature, or HAS-A vs. IS-A, then use an interface to model that part.
Why Use Interfaces?
For a practical example, let's jump into a business application. If you have a repository; you'll want to make the layer above your repository those of interfaces. That way if you have to change anything in the way the respository works, you won't affect anything since they all obey the same contracts.
Here's our repository:
public interface IUserRepository
{
public void Save();
public void Delete(int id);
public bool Create(User user);
public User GetUserById(int id);
}
Now, I can implement that Repository in a class:
public class UserRepository : IRepository
{
public void Save()
{
//Implement
}
public void Delete(int id)
{
//Implement
}
public bool Create(User user)
{
//Implement
}
public User GetUserById(int id)
{
//Implement
}
}
This separates the Interface from what is calling it. I could change this Class from Linq-To-SQL to inline SQL or Stored procedures, and as long as I implemented the IUserRepository interface, no one would be the wiser; and best of all, there are no classes that derive from my class that could potentially be pissed about my change.
Inheritance and Composition: Best Friends
Inheritance and Composition are meant to tackle different problems. Use each where it fits, and there are entire subsets of problems where you use both.
I was going to leave George to point out that you can now consume the interface rather than the concrete class. It seems like everyone here understands what interfaces are and how to define them, but most have failed to explain the key point of them in a way a student will easily grasp - and something that most courses fail to point out instead leaving you to either grasp at straws or figure it out for yourself so I'll attempt to spell it out in a way that doesn't require either. So hopefully you won't be left thinking "so what, it still seems like a waste of time/effort/code."
public interface ICar
{
public bool EngineIsRunning{ get; }
public void StartEngine();
public void StopEngine();
public int NumberOfWheels{ get; }
public void Drive(string direction);
}
public class SportsCar : ICar
{
public SportsCar
{
Console.WriteLine("New sports car ready for action!");
}
public bool EngineIsRunning{ get; protected set; }
public void StartEngine()
{
if(!EngineIsRunning)
{
EngineIsRunning = true;
Console.WriteLine("Engine is started.");
}
else
Console.WriteLine("Engine is already running.");
}
public void StopEngine()
{
if(EngineIsRunning)
{
EngineIsRunning = false;
Console.WriteLine("Engine is stopped.");
}
else
Console.WriteLine("Engine is already stopped.");
}
public int NumberOfWheels
{
get
{
return 4;
}
}
public void Drive(string direction)
{
if (EngineIsRunning)
Console.WriteLine("Driving {0}", direction);
else
Console.WriteLine("You can only drive when the engine is running.");
}
}
public class CarFactory
{
public ICar BuildCar(string car)
{
switch case(car)
case "SportsCar" :
return Activator.CreateInstance("SportsCar");
default :
/* Return some other concrete class that implements ICar */
}
}
public class Program
{
/* Your car type would be defined in your app.config or some other
* mechanism that is application agnostic - perhaps by implicit
* reference of an existing DLL or something else. My point is that
* while I've hard coded the CarType as "SportsCar" in this example,
* in a real world application, the CarType would not be known at
* design time - only at runtime. */
string CarType = "SportsCar";
/* Now we tell the CarFactory to build us a car of whatever type we
* found from our outside configuration */
ICar car = CarFactory.BuildCar(CarType);
/* And without knowing what type of car it was, we work to the
* interface. The CarFactory could have returned any type of car,
* our application doesn't care. We know that any class returned
* from the CarFactory has the StartEngine(), StopEngine() and Drive()
* methods as well as the NumberOfWheels and EngineIsRunning
* properties. */
if (car != null)
{
car.StartEngine();
Console.WriteLine("Engine is running: {0}", car.EngineIsRunning);
if (car.EngineIsRunning)
{
car.Drive("Forward");
car.StopEngine();
}
}
}
As you can see, we could define any type of car, and as long as that car implements the interface ICar, it will have the predefined properties and methods that we can call from our main application. We don't need to know what type of car is - or even the type of class that was returned from the CarFactory.BuildCar() method. It could return an instance of type "DragRacer" for all we care, all we need to know is that DragRacer implements ICar and we can carry on life as normal.
In a real world application, imagine instead IDataStore where our concrete data store classes provide access to a data store on disk, or on the network, some database, thumb drive, we don't care what - all we would care is that the concrete class that is returned from our class factory implements the interface IDataStore and we can call the methods and properties without needing to know about the underlying architecture of the class.
Another real world implication (for .NET at least) is that if the person who coded the sports car class makes changes to the library that contains the sports car implementation and recompiles, and you've made a hard reference to their library you will need to recompile - whereas if you've coded your application against ICar, you can just replace the DLL with their new version and you can carry on as normal.
So that a given class can inherit from multiple sources, while still only inheriting from a single parent class.
Some programming languages (C++ is the classic example) allow a class to inherit from multiple classes; in this case, interfaces aren't needed (and, generally speaking, don't exist.)
However, when you end up in a language like Java or C# where multiple-inheritance isn't allowed, you need a different mechanism to allow a class to inherit from multiple sources - that is, to represent more than one "is-a" relationships. Enter Interfaces.
So, it lets you define, quite literally, interfaces - a class implementing a given interface will implement a given set of methods, without having to specify anything about how those methods are actually written.
Maybe this resource is helpful: When to Use Interfaces
It allows you to separate the implementation from the definition.
For instance I can define one interface that one section of my code is coded against - as far as it is concerned it is calling members on the interface. Then I can swap implementations in and out as I wish - if I want to create a fake version of the database access component then I can.
Interfaces are the basic building blocks of software components
In Java, interfaces allow you to refer any class that implements the interface. This is similar to subclassing however there are times when you want to refer to classes from completely different hierarchies as if they are the same type.
Speaking from a Java standpoint, you can create an interface, telling any classes that implement said interface, that "you MUST implement these methods" but you don't introduce another class into the hierarchy.
This is desireable because you may want to guarantee that certain mechanisms exist when you want objects of different bases to have the same code semantics (ie same methods that are coded as appropriate in each class) for some purpose, but you don't want to create an abstract class, which would limit you in that now you can't inherit another class.
just a thought... i only tinker with Java. I'm no expert.
Please see my thoughts below. 2 different devices need to receive messages from our computer. one resides across the internet and uses http as a transport protocol. the other sits 10 feet away, connect via USB.
Note, this syntax is pseudo-code.
interface writeable
{
void open();
void write();
void close();
}
class A : HTTP_CONNECTION implements writeable
{
//here, opening means opening an HTTP connection.
//maybe writing means to assemble our message for a specific protocol on top of
//HTTP
//maybe closing means to terminate the connection
}
class B : USB_DEVICE implements writeable
{
//open means open a serial connection
//write means write the same message as above, for a different protocol and device
//close means to release USB object gracefully.
}
Interfaces create a layer insulation between a consumer and a supplier. This layer of insulation can be used for different things. But overall, if used correctly they reduce the dependency density (and the resulting complexity) in the application.
I wish to support Electron's answer as the most valid answer.
Object oriented programming facilitates the declaration of contracts.
A class declaration is the contract. The contract is a commitment from the class to provide features according to types/signatures that have been declared by the class. In the common oo languages, each class has a public and a protected contract.
Obviously, we all know that an interface is an empty unfulfilled class template that can be allowed to masquerade as a class. But why have empty unfulfilled class contracts?
An implemented class has all of its contracts spontaneously fulfilled.
An abstract class is a partially fulfilled contract.
A class spontaneously projects a personality thro its implemented features saying it is qualified for a certain job description. However, it also could project more than one personality to qualify itself for more than one job description.
But why should a class Motorcar not present its complete personality honestly rather than hide behind the curtains of multiple-personalities? That is because, a class Bicycle, Boat or Skateboard that wishes to present itself as much as a mode of Transport does not wish to implement all the complexities and constraints of a Motorcar. A boat needs to be capable of water travel which a Motorcar needs not. Then why not give a Motorcar all the features of a Boat too - of course, the response to such a proposal would be - are you kiddin?
Sometimes, we just wish to declare an unfulfilled contract without bothering with the implementation. A totally unfulfilled abstract class is simply an interface. Perhaps, an interface is akin to the blank legal forms you could buy from a stationary shop.
Therefore, in an environment that allows multiple inheritances, interfaces/totally-abstract-classes are useful when we just wish to declare unfulfilled contracts that someone else could fulfill.
In an environment that disallows multiple inheritances, having interfaces is the only way to allow an implementing class to project multiple personalities.
Consider
interface Transportation
{
takePassengers();
gotoDestination(Destination d);
}
class Motorcar implements Transportation
{
cleanWindshiedl();
getOilChange();
doMillionsOtherThings();
...
takePassengers();
gotoDestination(Destination d);
}
class Kayak implements Transportation
{
paddle();
getCarriedAcrossRapids();
...
takePassengers();
gotoDestination(Destination d);
}
An activity requiring Transportation has to be blind to the millions alternatives of transportation. Because it just wants to call
Transportation.takePassengers or
Transportation.gotoDestination
because it is requesting for transportation however it is fulfilled. This is modular thinking and programming, because we don't want to restrict ourselves to a Motorcar or Kayak for transportation. If we restricted to all the transportation we know, we would need to spend a lot of time finding out all the current transportation technologies and see if it fits into our plan of activities.
We also do not know that in the future, a new mode of transport called AntiGravityCar would be developed. And after spending so much time unnecessarily accommodating every mode of transport we possibly know, we find that our routine does not allow us to use AntiGravityCar. But with a specific contract that is blind any technology other than that it requires, not only do we not waste time considering all sorts of behaviours of various transports, but any future transport development that implements the Transport interface can simply include itself into the activity without further ado.
None of the answers yet mention the key word: substitutability. Any object which implements interface Foo may be substituted for "a thing that implements Foo" in any code that needs the latter. In many frameworks, an object must give a single answer to the question "What type of thing are you", and a single answer to "What is your type derived from"; nonetheless, it may be helpful for a type to be substitutable for many different kinds of things. Interfaces allow for that. A VolkswagonBeetleConvertible is derived from VolkswagonBeetle, and a FordMustangConvertible is derived from FordMustang. Both VolkswagonBeetleConvertible and FordMustangConvertible implement IOpenableTop, even though neither class' parent type does. Consequently, the two derived types mentioned can be substituted for "a thing which implements IOpenableTop".