I had a disscusion with a collegue about approaches to these topics in our project.
Im making a Progress System, in short a ProgressMonitor class and a Task class, ProgressMonitor handles an array of tasks. All pretty straight forward stuff. But when it came to the tasks ui, we had to opinions.
Each task has his own UI. We agree we should have an HUD class for handling UI.
The difference in opinion is, he wants the HUD to handle each specific task's UI and so the HUD class would grow quite big and the task would have near to no logic about its UI.
My opinion, The HUD would only handle the logic that is the same for all things in our project that need UI's, and all specific logic is handle by the objects that need UI.
Advantage of his is some ownership (objects that need to acces some ui info can easily get it from HUD)
My advantages, HUD stay light clean and reusable.
What would be more correct acording to OOP?
I'll start with questions that will affect the implementation:
Question 1: Is the Task closely related to it's UI?
Question 2: Is the UI for all tasks the same or has minor differences?
Question 3: Do you need to show different UI for each task based on the specific task?
If the answer to Question 1 is Yes and separating the two responsibilies is hard, adding the UI logic to the Task can simply things a lot.
If the answer to Question 2 is Yes then using the classic model/view separation will make writing new tasks easier as you only need to add the task logic to the Task class.
You can have a TasksHUD class who's responsibility will be to handle a list of TaskUI class. Eeach TaskUI class will have a Task associated with it and handle the rendering of UI and presentation logic for this specific task.
This way your TasksHUD class will manage how the list is shown to the user, while each list entry will be handled by the TaskUI class. The task presentation code will be reused.
Task will only have the responsibilities of executing, changing it's status and other things that a task must do in your app (if you give a more details I can a more detaildd and probably more accurate description), while the responsibility of presenting a task will be given to a TaskUI.
This way if you need to change the logic how a task is rendered, you have to change only the TaskUI class.
You can write as many tasks as you wan't without having the need to write a UI related code for those tasks.
If you need to change the Task class you may or may not have to change TaskUI class as the dependecy goes from TaskUI to Task. Some changes will affect the UI some won't.
If the answer to Question 3 is Yes then:
You can add the responsibility of handling it's UI to the Task. This way it would be easier to change them as they are in the same class. One problem here is that the Task class can grow having multiple responsibilies. Also sharing rendering code for similar tasks etc.
Event in this case you can decouple the Task from it's UI in two classes Task and TaskUI but you will need a mechanism in your app that will associate a specific Task class with it's TaskUI class. This can lead to more classes and a complexity that may not wan't to manage. In the long run it may save you time (mostly from chaising bugs).
Here is a pseudo code example:
interface TaskObserver {
void onTaskChanged(t);
}
interface TaskUI {
void render();
}
interface TaskUIFactory {
register(TaskUIFactoryRegistry registry);
TaskUI create(Task task);
}
interface Task {
TaskStatus status;
execute();
addEventListener(TaskObserver o);
}
class TaskA : Task {
// implementation.....
}
class TaskA_UI : TaskUI, TaskObserver {
TaskA mTask;
TaskA_UI(TaskA task) {
mTask = task;
mTask.addEventListener(this);
}
render() {
// rendering goes here
}
onTaskChanged(t) {
// raise an event or signal to the TaskHUD that a refresh is needed
}
}
class TaskA_UIFactory : TaskUIFactory {
void register(TaskUIFactoryRegistry registry) {
registry.Register(typeof(TaskA), this);
}
TaskUI createUI(Task task) {
return new TaskA_UI((TaskA)task);
}
}
When a task is added your TasksHUD can use the TaskUIFactoryRegistry to get a TaskUIFactory that will create a TaskUI.
Here are some resources that you can check that discuss these kind of issues:
Presentation Model
GUI architectures
Related
I have the following desing in DDD
Post Aggregate with
Body: HTML of the post
Banner entity with
Html: HTML of the banner
The Banner entity belongs to Post aggregate, so I want to create a method BodyWithBanners in the Post aggregate.
The point of this method will be to search into the HTML of the Post.Body and insert the HTML of the Banner.
So far, so good.
However I have intention of reuse this functionallity in abstract: "Insert some HTML inside another HTML". So I'm creating a diffent class for doing that: BannerReplacer
Here comes the problem, how should I invoke this new class?
Just create an instance inside the Post.BodyWithBanners method (breaking Dependency Injection)
Passing the BannerReplacer in the constructor of the Post aggregate (This can be a nightmare for creating Post instances)
Passing the BannerReplacer to the BodyWithBanners method (which implies the client using Post must handle the BannerReplacer)
I have chosen for now the first option, but I don't feel really confortable with it, I believe there must be a better way of doing this.
I have chosen for now the first option, but I don't feel really comfortable with it, I believe there must be a better way of doing this.
Much of the time, the first option is fine -- so you should practice being comfortable with it. That mostly means thinking more about what dependency injection is for, and having a clear picture in your mind for whether or not those forces are at play here.
If Banner is an entity, in the domain-driven-design sense, then it is probably something analogous to an in memory state machine. It's got a data structure that it manages, and some functions for changing that data structure, or answering interesting questions about that data structure, but it doesn't have I/O, database, network etc concerns.
That in turn suggests that you can run it the same way in all contexts - you don't need a bunch of substitute implementations to make it testable. You just instantiate one and call its methods.
If it runs the same way in all contexts, then it doesn't need configurable behavior. If you don't need to be able to configure the behavior, then you don't need dependency injection (because all copies of this entity will use (copies of) the same dependencies.
When you do have a configurable behavior, then the analysis is going to need to look at scope. If you need to be able to change that behavior from one invocation to the next, then the caller is going to need to know about it. If the behavior changes less frequently than that, then you can start looking into whether "constructor injection" makes sense.
You know that you intend to use a single BannerReplacer for a given method invocation, so you can immediately start with a method that looks like:
class Banner {
void doTheThing(arg, bannerReplacer) {
/* do the bannerReplacer thing */
}
}
Note that this signature has no dependency at all on the lifetime of the bannerReplacer. More particularly, the BannerReplacer might have a longer lifetime than Banner, or a shorter one. We only care that the lifetime is longer than the doTheThing method.
class Banner {
void doTheThing(arg) {
this.doTheThing(arg, new BannerReplacer())
}
// ...
}
Here, the caller doesn't need to know about BannerReplacer at all; we'll use a new copy of the default implementation every time. Caller's that care which implementation is used can pass in their own.
class Banner {
bannerReplacer = new BannerReplacer()
void doTheThing(arg) {
this.doTheThing(arg, this.bannerReplacer)
}
// ...
}
Same idea as before; we're just using an instance of the BannerReplacer with a longer lifetime.
class Banner {
Banner() {
this(new BannerReplacer())
}
Banner(bannerReplacer) {
this.bannerReplacer = bannerReplacer;
}
void doTheThing(arg) {
this.doTheThing(arg, this.bannerReplacer)
}
// ...
}
Same idea as before, but now we are allowing the "injection" of a default implementation that can outlive the given instance of Banner.
In the long term, the comfort comes from doing the analysis to understand the requirements of the current problem, so that you can choose the appropriate tool.
I'm not so sure the title is a good match for this question I want to put on the table.
I'm planning to create a web MVC framework as my graduation dissertation and in a previous conversation with my advisor trying to define some achivements, he convinced me that I should choose a modular design in this project.
I already had some things developed by then and stopped for a while to analyze how much modular it would be and I couldn't really do it because I don't know the real meaning of "modular".
Some things are not very cleary for me, like for example, just referencing another module blows up the modularity of my system?
Let's say I have a Database Access module and it OPTIONALY can use a Cache module for storing results of complex queries. As anyone can see, I at least will have a naming dependency for the cache module.
In my conception of "modular design", I can distribute each component separately and make it interact with others developed by other people. In this case I showed, if someone wants to use my Database Access module, they will have to take the Cache as well, even if he will not use it, just for referencing/naming purposes.
And so, I was wondering if this is really a modular design yet.
I came up with an alternative that is something like creating each component singly, without don't even knowing about the existance of other components that are not absolutely required for its functioning. To extend functionalities, I could create some structure based on Decorators and Adapters.
To clarify things a little bit, here is an example (in PHP):
Before
interface Cache {
public function isValid();
public function setValue();
public function getValue();
}
interface CacheManager {
public function get($name);
public function put($name, $value);
}
// Some concrete implementations...
interface DbAccessInterface {
public doComplexOperation();
}
class DbAccess implements DbAccessInterface {
private $cacheManager;
public function __construct(..., CacheManager $cacheManager = null) {
// ...
$this->cacheManager = $cacheManager;
}
public function doComplexOperation() {
if ($this->cacheManager !== null) {
// return from cache if valid
}
// complex operation
}
}
After
interface Cache {
public function isValid();
public function setValue();
public function getValue();
}
interface CacheManager {
public function get($name);
public function put($name, $value);
}
// Some concrete implementations...
interface DbAccessInterface {
public function doComplexOperation();
}
class DbAccess implements DbAccessInterface {
public function __construct(...) {
// ...
}
public function doComplexQuery() {
// complex operation
}
}
// And now the integration module
class CachedDbAcess implements DbAccessInterface {
private $dbAccess;
private $cacheManager;
public function __construct(DbAccessInterface $dbAccess, CacheManager $cacheManager) {
$this->dbAccess = $dbAccess;
$this->cacheManager = $cacheManager;
}
public function doComplexOperation() {
$cache = $this->cacheManager->get("Foo")
if($cache->isValid()) {
return $cache->getValue();
}
// Do complex operation...
}
}
Now my question is:
Is this the best solution? I should do this for all the modules that do not have as a requirement work together, but can be more efficient doing so?
Anyone would do it in a different way?
I have some more further questions involving this, but I don't know if this is an acceptable question for stackoverflow.
P.S.: English is not my first language, maybe some parts can get a little bit confuse
Some resources (not theoretical):
Nuclex Plugin Architecture
Python Plugin Application
C++ Plugin Architecture (Use NoScript on that side, they have some weird login policies)
Other SO threads (design pattern for plugins in php)
Django Middleware concept
Just referencing another module blows up the modularity of my system?
Not necessarily. It's a dependency. Having a dependencies is perfectly normal. Without dependencies modules can't interact with each other (unless you're doing such interaction indirectly which in general is a bad practice since it hides dependencies and complicates the code). Modular desing implies managing of dependencies, not removing them.
One tool - is using interfaces. Referencing module via interface makes a so called soft dependency. Such module can accept any implementation of an interface as a dependency so it is more independant and as a result - more maintainable.
The other tool - designing modules (and their interfaces) that have only single responcibility. This also makes them more granular, independant and maintainable.
But there is a line which you should not cross - blindly applying these tools may leed to a too modular and too generic desing. Making things too granular makes the whole system more complex. You should not solve universe problems, making generic modules, that all developers can use (unless it is your goal). First of all your system should solve your domain tasks and make things generic enough, but not more than that.
I came up with an alternative that is something like creating each component singly, without don't even knowing about the existance of other components that are not absolutely required for its functioning
It is great if you came up with this idea by yourself. The statement itself, is a key to modular programming.
Plugin architecture is the best in terms of extensibility, but imho it is hard to maintenance especially in intra application. And depending the complexity of plugin architecture, it can make your code more complex by adding plugin logics, etc.
Thus, for intra modular design, I choose the N-Tier, interface based architecture. Basically, the architecture relays on those tiers:
Domain / Entity
Interface [Depend on 1]
Services [Depend on 1 and 2]
Repository / DAL [Depend on 1 and 2]
Presentation Layer [Depend on 1,2,3,4]
Unfortunately, I don't think this is achieveable neatly in php projects as it need separated project / dll references in each tier. However, following the architecture can help to modularize the application.
For each modules, we need to do interface-based design. It can help to enhance the modularity of your code, because you can change the implementation later, but still keep the consumer the same.
I have provided an answer similiar to this interface-based design, at this stackoverflow question.
Lastly but not least, if you want to make your application modular to the UI, you can do Service Oriented Architecture. This is simply make your application as bunch of services, and then make the UI to consume the service. This design can help to separate your UI with your logic. You can later use different UI such as desktop app, but still use the same logic. Unfortunately, I don't have any reliable source for SOA.
EDIT:
I misunderstood the question. This is my point of view about modular framework. Unfortunately, I don't know much about Zend so I will give examples in C#:
It consist of modules, from the smallest to larger modules. Example in C# is you can using the Windows Form (larger) at your application, and also the Graphic (smaller) class to draw custom shapes in the screen.
It is extensible, or replaceable without making change to base class. In C# you can assign FormLoad event (extensible) to the Form class, inherit the Form or List class (extensible) or overridding form draw method to create a custom window graphic (replaceable).
(optional) it is easy to use. In normal DI interface design, we usually inject smaller modules into a larger (high level) module. This will require an IOC container. Refer to my question for detail.
Easy to configure, and does not involve any magical logic such as Service Locator Pattern. Search Service Locator is an Anti Pattern in google.
I don't know much about Zend, however I guess that the modularity in Zend can means that it can be extended without changing the core (replacing the code) inside framework.
If you said that:
if someone wants to use my Database Access module, they will have to take the Cache as well, even if he will not use it, just for referencing/naming purposes.
Then it is not modular. It is integrated, means that your Database Access module will not work without Cache. In reference of C# components, it choose to provide List<T> and BindingList<T> to provide different functionality. In your case, imho it is better to provide CachedDataAccess and DataAccess.
Let's say I have a few controllers. Each controller can at some point create new objects which will need to be stored on the server. For example I can have a RecipeCreationViewController which manages a form. When this form is submitted, a new Recipe object is created and needs to be saved on the server.
What's the best way to design the classes to minimize complexity and coupling while keeping the code as clean and readable as possible?
Singleton
Normally I would create a singleton NetworkAdapter that each controller can access directly in order to save objects.
Example:
[[[NetworkAdapter] sharedAdapter] saveObject:myRecipe];
But I've realized that having classes call singletons on their own makes for coupled code which is hard to debug since the access to the singleton is hidden in the implementation and not obvious from the interface.
Direct Reference
The alternative is to have each controller hold a reference to the NetworkAdapter and have this be passed in by the class that creates the controller.
For example:
[self.networkAdapter saveObject:myRecipe];
Delegation
The other approach that came to mind is delegation. The NetworkAdapter can implement a "RemoteStorageDelegate" protocol and each controller can have a remoteStorageDelegate which it can call methods like saveObject: on. The advantage being that the controllers don't know about the details of a NetworkAdapter, only that the object that implements the protocol knows how to save objects.
For example:
[self.remoteStorageDelegate saveObject:myRecipe];
Direct in Model
Yet another approach would be to have the model handle saving to the network directly. I'm not sure if this is a good idea though.
For example:
[myRecipe save];
What do you think of these? Are there any other patterns that make more sense for this?
I would also stick with Dependency Injection in your case. If you want to read about that you will easily find good articles in the web, e.g. on Wikipedia. There are also links to DI frameworks in Objective C.
Basically, you can use DI if you have two or more components, which must interact but shouldn't know each other directly in code. I'll elaborate your example a bit, but in C#/Java style because I don't know Objective C syntax. Let's say you have
class NetworkAdapter implements NetworkAdapterInterface {
void save(object o) { ... }
}
with the interface
interface NetworkAdapterInterface {
void save(object o);
}
Now you want to call that adapter in a controller like
class Controller {
NetworkAdapterInterface networkAdapter;
Controller() {
}
void setAdapter(NetworkAdapterInterface adapter) {
this.networkAdapter = adapter;
}
void work() {
this.networkAdapter.save(new object());
}
}
Calling the Setter is where now the magic of DI can happen (called Setter Injection; there is also e.g. Constructor Injection). That means that you haven't a single code line where you call the Setter yourself, but let it do the DI framework. Very loose coupled!
Now how does it work? Typically with a common DI framework you can define the actual mappings between components in a central code place or in a XML file. Image you have
<DI>
<component="NetworkAdapterInterface" class="NetworkAdapter" lifecycle="singleton" />
</DI>
This could tell the DI framework to automatically inject a NetworkAdapter in every Setter for NetworkAdapterInterface it finds in your code. In order to do this, it will create the proper object for you first. If it builds a new object for every injection, or only one object for all injections (Singleton), or e.g. one object per Unit of Work (if you use such a pattern), can be configured for each type.
As a sidenote: If you are unit testing your code, you can also use the DI framework to define completely other bindings, suitable for your test szenario. Easy way to inject some mocks!
As I understand interfaces they are contracts, I interpret it as the contract word, ie must have what is specified in the interface (ex open, close, read, write for an interface handling files).
But what im having a hard time grasping is why you would need to have an interface that tells you what the class must be able to do at all, wouldnt you know that already since you wrote it in the interface specification?
The only reason I can see for interfaces is in large projects where you want to be able to use a class without really knowing how it is built. By seeing what the interface requires will allow you to know how to use it.
Which leads me to wonder why I should use (or if I should) interfaces in projects that I will be the only one working on. Im pretty sure there are more uses for it that im not seeing.
I took most of my assumptions and interpretations from this question and this vbforums post
You're right in that interfaces specify the contract but the implementaiton can be vastly different.
Simple example: lists in Java. List is an interface. Two common implementations are ArrayList and LinkedList. Each behaves different but honours the same contract. By that I mean that ArrayList has O(1) (constant) access whereas LinkedList has O(n) access.
If you don't yet understand what O(1) and O(n) mean, I suggest you take a look at the Plain english explanation of Big O.
The reason you do this even on your own code (ie something that isn't or won't be a public API) is to:
facilitate unit testing: you can mock up an interface whereas you can't (or can't easily) mock up a class; and
to allow you to change the implementation later without affecting the calling code.
Interfaces are useful when you have two classes which need to work together but should be decoupled from each other as much as possible. A common example of this is when you use listeners to connect model and view together in the model-view-controller design pattern.
For example, let's say you had a GUI application where users could log in and log out. When users log out you might, say, change your "Currently logged in as So-and-So" label and close all of the visible dialog windows.
Now you have a User class with a logOut method, and whenever logOut is called you want all of these things to happen. One way to do that is have the logOut method handle all of these tasks:
// Bad!
public void logOut() {
userNameLabel.setText("Nobody is logged in");
userProfileWindow.close();
}
This is frowned upon because your User class is now tightly coupled to your GUI. It would be better to have the User class be dumber and not do so much. Instead of closing userProfileWindow itself it should just tell userProfileWindow that the user has logged out and let userProfileWindow do whatever it wants to do (it wants to close itself).
The way to do this is by creating a generic UserListener interface with a method loggedOut that is called by the User class when the user logs out. Anybody who wants to know when the user logs in and logs out will then implement this interface.
public class User {
// We'll keep a list of people who want to be notified about logouts. We don't know
// who they are, and we don't care. Anybody who wants to be notified will be
// notified.
private static List<UserListener> listeners;
public void addListener(UserListener listener) {
listeners.add(listener);
}
// This will get called by... actually, the User class doesn't know who's calling
// this or why. It might be a MainMenu object because the user selected the Log Out
// option, or an InactivityTimer object that hasn't seen the mouse move in 15
// minutes, who knows?
public void logOut() {
// Do whatever internal bookkeeping needs to be done.
currentUser = null;
// Now that the user is logged out, let everyone know!
for (UserListener listener: listeners) {
listener.loggedOut(this);
}
}
}
// Anybody who cares about logouts will implement this interface and call
// User.addListener.
public interface UserListener {
// This is an abstract method. Each different type of listener will implement this
// method and do whatever it is they need to do when the user logs out.
void loggedOut(User user);
}
// Imagine this is a window that shows the user's name, password, e-mail address, etc.
// When the user logs out this window needs to take action, namely by closing itself so
// this information isn't viewable by other users. To get notified it implements the
// UserListener interface and registers itself with the User class. Now the User.logOut
// method will cause this window to close, even though the User.java source file has no
// mention whatsoever of UserProfileWindow.
public class UserProfileWindow implements UserListener {
public UserProfileWindow() {
// This is a good place to register ourselves as interested observers of logout
// events.
User.addListener(this);
}
// Here we provide our own implementation of the abstract loggedOut method.
public void loggedOut(User user) {
this.close();
}
}
The order of operations will look like this:
The application starts and a user logs in. She opens her UserProfileWindow.
The UserProfileWindow adds itself as a UserListener.
The user goes idle and doesn't touch the keyboard or mouse for 15 minutes.
An imagined InactivityTimer class notices and calls User.logOut.
User.logOut updates the model, clearing the currentUser variable. Now if anybody asks, there's nobody logged in.
User.logOut loops through its listener list, calling loggedOut() on each listener.
The UserProfileWindow's loggedOut() method is invoked, which closes the window.
This is great because this User class knows absolutely nothing about who needs to know about log out events. It doesn't know that the user name label needs to be updated, that the profile window needs to be closed, none of that. If later we decide more things need to be done when a user logs out, the User class does not need to be changed at all.
So, the listener pattern is one example of where interfaces are super useful. Interfaces are all about decoupling classes, removing ties and dependencies between classes that need to interact with each other but should not have strong ties in their code to each other.
But what im having a hard time grasping is why you would need to have an interface that tells you what the class must be able to do at all, wouldnt you know that already since you wrote it in the interface specification?
It is also good when you are writing externally available code. In this case the code writer is not the user of the Interface. If you are delivering a library to users, you may want to document only the Interface, and allow the Class to change based on context or to evolve over time without changing the Interface.
Suppose you're writing a set of classes that implements guns. You might have a Pistol, a Rifle, and a MachineGun. Then, suppose you decide to use these classes in such a way that you'd like to perform the fire() action on each of these guns. You could do it this way:
private Pistol p01;
private Pistol p02;
private Rifle r01;
private MachineGun mg01;
public void fireAll() {
p01.fire();
p02.fire();
r01.fire();
mg01.fire();
}
That kind of sucks, because you have to change code in a few places if you add or remove guns. Or even worse, suppose you want to be able to add and remove guns at runtime: it becomes even harder.
Let's make an interface that each of the above guns will implement, call it Firearm. Now we can do this.
private Firearm[] firearms;
public void fireAll() {
for (int i = 0; i < firearms.length; ++i) {
firearms[i].fire();
}
}
That lends itself to changes a little bit better, wouldn't you say?
Let's say you have two classes Car and Gorilla. These two classes have nothing to do with each other. But, let's say you also have a class that can crush things. Instead of defining a method that takes a Car and crushes it and then having a separate method that takes a Gorilla and crushes it, you make an Interface called ICrushable ...
interface ICrushable
{
void MakeCrushingSound();
}
Now you can have your car and your Gorilla implement ICrushable and your Car implement ICrushable and your crusher can then operate on an ICrushable instead of a Car and a Gorilla ...
public class Crusher
{
public void Crush(ICrushable target)
{
target.MakeCrushingSound();
}
}
public class Car : ICrushable
{
public void MakeCrushingSound()
{
Console.WriteLine("Crunch!");
}
}
public class Gorilla : ICrushable
{
public void MakeCrushingSound()
{
Console.WriteLine("Squish!!");
}
}
static void Main(string[] args)
{
ICrushable c = new Car(); // get the ICrushable-ness of a Car
ICrushable g = new Gorilla(); // get the ICrushable-ness of a Gorilla
Crusher.Crush(c);
Crusher.Crush(g);
}
And Viola! You have a Crusher that can crush Cars and get "Crunch!" and can crush Gorillas and get "Squish!". Without having to go through the process of finding a type-relationship between Cars and Gorillas and with compile-time type checking (instead of a runtime switch statement).
Now, consider something less silly ... an Class that can be compared (IComparable) for example. The class will define how you compare two things of it's type.
Per comment: Okay, let's make it so we can sort an array of Gorillas. First, we add something to sort by, say Weight (please ignore the dubious business logic of sorting Gorillas by weight ... it's not relevant here). Then we implement ICompararble ...
public class Gorilla : ICrushable, IComparable
{
public int Weight
{
get;
set;
}
public void MakeCrushingSound()
{
Console.WriteLine("Squish!!");
}
public int CompareTo(object obj)
{
if (!(obj is Gorilla))
{
throw (new ArgumentException());
}
var lhs = this;
var rhs = obj as Gorilla;
return (lhs.Weight.CompareTo(rhs.Weight));
}
}
Notice we have "gotten around" the restriction of single inheritance that many languages have. We are allowed to implement as many interfaces as we like. Now, just by doing that, we can use functionality that was written more than 10 years ago on a class I just wrote today (Array.Sort, Array.BinarySearch). We can now write the following code ...
var gorillas = new Gorilla[] { new Gorilla() { Weight = 900 },
new Gorilla() { Weight = 800 },
new Gorilla() { Weight = 850 }
};
Array.Sort(gorillas);
var res = Array.BinarySearch(gorillas,
new Gorilla() { Weight = 850 });
My Gorillas get sorted and binary search finds the matching Gorilla with the Weight of 850.
If you ever want to revisit your old code, you will thank yourself for having built yourself some interfaces. Nothing is more frustrating than wanting to implementing a new type of something that exists, only to realize you do not remember what a new object had to have.
In Java, you can implement multiple interfaces, which sort of simulates multiple inheritance (an object with multiple parent objects). You can only extend one superclass.
No one forces you to write interface and there is no language enforces that even. Its a best practice and idiom that a good programmer would follow. You are the only one to use your code, and ya, you can write what you like but what if you leave the project and someone else has to maintain and/or extend it? Or what if some other projects consider using your code? Or even what if after a while, you have to revisit your code for adding features or refactoring? You would create a nightmare for these sorts of things. It will be hard to understand what your object relationships and contracts established b/w them.
Abstraction:
Code written to use an interface is reusable an never needs to change. In the below case, the sub will work with System.Array, System.ArrayList, System.Collection.CollectionBase, List of T, because they all implement IList. An existing class can easily implement an interface even when the class inherits another class.
You could even write your class to implement IList to us in the sub. Or another program could also implement the interface to use in the sub.
public sub DoSomething(byval value as IList)
end sub
You can also use multiple interfaces in a class, so a class can be both a IList and IEnumerable, in most languages you can on inherit one class.
I would also look at how they are used in the various frameworks.
As I understand your question why do we need Interfaces ? right ?
Well we don't need them :)
In C++ for example, when you define a template... say a dummy function that looks like ::
template <typename T>
void fun(const T& anObjectOfAnyType)
{
anyThing.anyFunction();
}
you can use this function anywhere with any type that has a function called anyFunction...
the only thing that the compiler is going to do, is to replace T with the name of the type,
and compile the new piece of code...
This is very error prone in fact. The reason is that if we plug in a type which does not have a anyFunction then we are going to get an error, that error is different every time,
every line that can not be translated by the compiler will issue an error for it. You get A LOT of errors for the ONLY MISSING THING!
The new type does not have the required functions to work correctly with our fun for example.
Now interfaces solve this whole issue, how ?
If the type has the required functions, then it is suitable, if not then the compiler will issue an error that the type is not suitable.
The template example is just for clarification, and if you want to imaging what will happen if java is without interfaces, then the only thing you have to do is to check for the existence of every function manually in every class, where you assume that class implements a particular function. The dirty work is done by the compiler :)
Thanks,
an interface reduces what the client is dependent on (http://en.wikipedia.org/wiki/Dependency_inversion_principle). it allows for multiple implementations and the ability to change implementations at run time.
I'm having a problem designing part of my program (not writing it, for once!). This is kind of hard to explain without writing a novel, so I'll try and be brief.
Basically, I have a program which reads/writes parameters from a piece of hardware. Currently, it does so over Serial, but eventually, I'll like it to do so over USB, using the .NET wrapper for the FTDI chip http://www.ftdichip.com/Projects/CodeExamples/CSharp.htm
I think my problem is, I know I want several layers of abstraction, but I can't seem to know where to draw the lines. First, I don't want my ReadParam(), WriteParam(), and SendCommand() functions to be sitting in my main form class. That just seems cobbled. So obviously they should be in some other class, which I'll instantiate. Let's call that Comm for now.
The first option is, I could make an interface, lets say IComm, and have my Serial and USB flavors both implement that. The problem with this is, a large percentage of the code would be duplicated in both flavors, because I have special ReadReplyData() and other functions, that do pre-processing of the serial data before they return it to the GUI.
So the next option, is have Comm be an intermediary class, which defines an interface ICommDriver. Comm would implement a private ReadReplyData() formatting function, as well as the public ReadParam(), WriteParam(), and SendCommand() functions, while ICommDriver would specify only simpler Read and Write functions.
This all seems trivial except for two twists. One, I want this to be multi-theaded, obviously, so the GUI doesn't hang. So I'm thinking that Comm would use a BackgroundWorker to do all the reads/writes. Also, the Serial flavor needs to be told which COM port to open (from a GUI drop-down), while the USB flavor does not. So do I make that part of the interface or not?
Thanks for your help everyone, I've been writing/deleting code for days trying to figure out the correct way to do this!
Jonathon
I know I want several layers of
abstraction, but I can't seem to know
where to draw the lines
This is where your problem lies. It is a fundamentally flawed approach to development and it is exactly what leads to this paralysis. Develop several concrete implementations of the flavors first. Get them working in your application with kludgy if type1 else type2 logic. Then go back and refactor them all to share a common contract, common base, what have you. It will be blindingly obvious what needs to go where.
With more details in the comments:
If you have shared code between implementations, you should use an abstract class. In my experience it's best practice to keep the public methods final and call protected abstract methods from the public methods, like so:
public interface IComm
{
void WriteParam(...);
}
public abstract class CommStandardBase : IComm
{
public void WriteParam(...)
{
DoWriteParam(...);
}
private void DoWriteParam(...)
{
CommonWrite1(...);
HandleWriteParam(...);
CommonWrite2(...);
}
protected abstract void HandleWriteParam(...);
private void CommonWrite1(...)
{
...
}
private void CommonWrite2(...)
{
...
}
}
Make each class self-contained. It should be single-instance, single-threaded and can be passed between workers and reporters.
In regards to exactly which kind of interfaces you need, that is ultimately up to you and whoever knows how this application works at that low of a level. I would like to respond to the part about using your implementations in a UI, and the comment about Comm using a BackgroundWorker. I would recommend inverting that. BackgroundWorker is really a UI level component....but Comm would be more of a "central" component (like a business object in an enterprise application). Your UI should create a BackgroundWorker that then creates Comm instances to perform the required work, and orchestrate any events from your Comm to update the UI. If you need your UI and the BackgroundWorker to communicate over a lengthy duration of time, I would recommend creating some kind of data transfer object that your UI can create, drop in a queue, and use ManualResetEvent or AutoResetEvent threading handles to communicate between your UI thread and the BackgroundWorker. That should give you a more loosely coupled product, allowing you to develop your Comm class independantly of any kind of UI that may display it (possibly allowing you to have WindForms, WPF, Command line, and maybe even PowerShell clients.)
I am somewhat in VB.NET mode at the momement so here goes...
Interface IComm
Function ReadParam()
Function WriteParam()
Function SendCommand()
End Interface
>
MustInherit Class CommBase
.... Load this up with the overideable
End Class
Then just implement the interface and inherit the base if needed. I also agree with Rex M. Don't push it too far for loose coupling.