How do I handle similar objects with different properties? - c#

I'm building an RSS client and using the Argotic framework. It provides different classes for different kinds of feeds like Atom, RSS, and OPML. These classes don't inherit from any other class and they don't implement a common interface for accessing their properties.
There is a GenericSyndicationFeed type that implements an overloaded method where you can pass in an AtomFeed or RssFeed. If I want to use the "more" strongly typed classes I would essentially need two code paths (one for Atom and one for RSS) everywhere in my program. Obviously, I'm not going to do this.
There is no documentation from the author other than the API documentation, so I'm kind of at a loss as to why it was implemented this way instead of taking full advantage of the complete classes. One thing that bothers me is that I can't get the authors of an item when using the GenericSyndicationItem type.
What can I do here? Make a wrapper class? Or inherit from the RssFeed and AtomFeed classes and implement an interface to expose the properties I feel should be similar from both?

When you are using a third-party library and the library doesn't meet your architectural needs: adapt! But how?
You've already identified some of your options and there are more:
Wrap existing classes in new classes using the Adapter Pattern
Extend and unify disparate classes by implementing a common interface
Refactor the original code to use Polymorphism natively
If the existing classes really have no common base class at all, then the first two options are both about the same amount of work. Wrapping has the advantage of a little looser coupling in case you ever decide to switch to a different framework. Extending avoids a lot of code like adaptee.AdapteeMethod since you can call base methods without specifying an instance. In this case I would lean towards the adapter pattern unless there is at least some common base class you can exploit through inheritance.
The last serious option is refactoring the code to be more object-oriented and I only recommend this approach if you are intending to contribute back to the project and have the blessing of the project's author. The reason is that you have working code that you probably don't full understand and messing around with it just risks breaking it. Leave the working code alone and adapt it from the outside.

It has been a really long time since I wrote Argotic (it was written before System.ServiceModel.Syndication existed in .NET), but since the concept of author exists in both RSS 2.0 and Atom, I don't really recall why the generic feed item did not include an Authors collection. It may have been because the outline elements in an OPML document do not have the concept of author. Poor design on my part obviously.
The bottom line is I was still young and learning, and Argotic while useful when it was written 3 years ago; is woefully in need of a major refactoring. If System.ServiceModel.Syndication can fulfill your needs, I recommend you use that to parse your syndication feeds.
Since you have the full source code to Argotic, and it is not fulfilling your needs; you could add an Authors collection to the generic syndication item class and populate it when consuming an RSS or Atom feed.
You most definitely have my blessing to refactor as you see fit regardless of whether you contribute back, I passed off project responsibilities years ago and am not sure what state it is in these days.
That said and done, if you know the format of the feed prior to consuming it, you can do the following:
RssFeed feed = RssFeed.Create(new Uri("http://www.pwop.com/feed.aspx?show=dotnetrocks&filetype=master"));
AtomFeed feed = AtomFeed.Create(new Uri("http://news.google.com/?output=atom"));

Related

Cross-DDL Extension of an Entityclass

What I want to archieve:
Service assembly (project) that holds EntityClasses - pure Data.
GUI assembly that extends those Entities for its own pourposes - Runtime information for GUI.
What I tried:
Derivation (Gui defines class ExtendedEntity : Service.BaseEntity)
seems to be the most common and only practicable way to me, but:
Converting Service.BaseEntity to ExtendedEntity after retrieving Data from the Service is painful. can 'workaround' this by using reflection to generate new ExtendedEntity instances based on base entity instances, but that can't be the 'proper' solution.
Partial classes
is exactly what I'm looking for, except the fact, that it does not work cross-assembly.
I'd greatly appreciate any hints helping me to find a proper & clean solution without reflection cheating =)
This is not a direct answer, but you may want to think a little more about your design. Why does your GUI need intimate knowledge of the mechanics of data storage? Typically we work very hard to make sure that the the UI and the data access are loosely coupled, so we can make changes to either without fear of breaking what already work. The design you are looking to implement can lead to unforeseen problems later.
One common pattern that works well for this type of thing is called the Repository pattern. Essentially the service assembly (repository) would contain all of the knowledge required to push data into and out of a particular data store. The 'shape' of the data is well known, and shared between the GUI and the repository. The service assembly would make the CRUD operations available to the GUI, and the GUI would would hold a reference to the repository, and call methods on it to fetch, create and update the data it needs.
Here are some links to get started on the ideas of loose coupling, the repository pattern, and dependency injection.
Cohesion and coupling
What is dependency injection
What's a good repository pattern tutorial
Is decompilation an option? If yes you can use e.g. PostSharp or Mono Cecil to rewrite the classes in question and add the there the code you want to have them.
I am curios why you do not want to use the standard OO approach like derivation. It is definitely not hacking.
The "cleanest" OO solution is to use aggregation and encapsulate the Entity classes inside objects where you can fully control what you can do with the data and how you want to manipulate or query it. You have reached "heaven" when your aggregation class does not need to expose the internal Entity class anymore because your class is powerful enough to support all necessary operations with the right abstractions.
If the classes you want to extend are sealed then you need to think hard why the writers of these classes did not want you to extend them.
Eric Lippert has a nice post about the usages of the sealed keyword.
...
Now, I recognize that developers are highly practical people who just
want to get stuff done. Being able to extend any class is convenient,
sure. Typical developers say "IS-A-SHMIZ-A, I just want to slap a
Confusticator into the Froboznicator class". That developer could
write up a hash table to map one to the other, but then you have to
worry about when to remove the items, etc, etc, etc -- it's not rocket
science, but it is work.
Obviously there is a tradeoff here. The tradeoff is between letting
developers save a little time by allowing them to treat any old object
as a property bag on the one hand, and developing a well-designed,
OOPtacular, fully-featured, robust, secure, predictable, testable
framework in a reasonable amount of time -- and I'm going to lean
heavily towards the latter. Because you know what? Those same
developers are going to complain bitterly if the framework we give
them slows them down because it is half-baked, brittle, insecure, and
not fully tested!
...
Yours,
Alois Kraus
You could have your GUI assembly define extension methods on the entity classes. With appropriate using directives, this would mean the consuming code would not know or care where the methods were actually defined.
A slight annoyance would be the non-existence of extension properties, so even things that are conceptually properties would have to be implemented as methods.
It would look a little like this:
In Service assembly
public class FooDTO
{
public string Name { get; set; }
}
In GUI assembly
internal static class Extensions
{
// Artificial example!
public static int GetNameLength(this FooDTO foo)
{
return foo.Name.Length;
}
}
// Consuming code
int myFooNameLength = myFooDTO.GetNameLength();

How to better organize classes/packages in a framework so that the client of my application can easily extend them?

Let's assume I am in charge of developing a Scrabble game, being that one of the principal requirements of the client is the ability to later try out different ways and modes of the game. I already made a design that is flexible enough to support those kinds of changes. The only question left is what to expose to the client(objects' access modifiers), and how to organize it (how to expose my objects in namespaces/packages).
How should I define things such that the client can both easily use my standard implementation (a standard Scrabble game, and yet be able to make all the modifications that he wants? I guess what I need is a kind of framework, on which he can work on.
I organized my classes/interfaces in a non-strict layered system:
Data Types
Contains basic data types that might be used in the whole system. This package and its members can be accessed by anyone in the system. All its members are public.
Domain
Contains all the interfaces I've defined and that might be useful to be able to make client's new Scrabble's implementations. Also contains value types, like Piece, that are used in the game. All its members are public.
Implementations
Contains all the needed classes/code to implement my standard Scrabble game in a Implementations.StandardScrabble package. If the client decides to implement other variants of the game, he can create them in Implementations.XYZ, for example.
These classes are all package protected and the only thing that is available to the outside of the package is a Game façade. Uses both Domain and Data Types packages.
UI
Contains the UI class that I have implemented so that both the client and the users of the program can run the game (my implementation). Can access all the other layers.
There are several drawbacks to the way I am organizing things, the most obvious being that if the client wants to create its own version of the game, he will have to basically implement almost everything by himself(I share in the Domain the interfaces, but he can do almost nothing with them). I feel I should maybe pass all the Implementation's classes to the Domain and then only have a Façade that builds up my standard Scrabble in the Implementations namespace?
How would you approach this? Is there any recomended reading on how to build this kind of programs (basically, frameworks)?
Thanks
I think that you're trying to give too much freedom to a client. This must be making things that difficult for you to handle. Based on what you have described it seems that a client will be able to modify almost all parts of your game - model, logic, UI... I think it would be better to restrict modifiable areas in your application but expose some via general Plugin interface set. This would make it easier for a user as well - he will only need to learn how plugins work, not the entire application's logic. Define areas for your plugins if you want - UI plugin, game mode plugin and so on. Many production applications and games work in such way (recall Diablo II and that AMAZING variety of plugins it has!).
For the algorithms and strategies I would define interfaces and default implementations, and provide abstract superclasses which are extended by you own implementations, so that all the boilerplate code is in the abstract superclass. In addition I would allow the client to subclass your impl. Just make more than one impl, and you see what to place where.
But most important: Give your client the code. If he needs to understand where to place his code, he should be able to see what you have coded, too. No need to hide stuff.
Whatever design you come up with, I would err on the side of hiding as much of the implementation as possible. Once you expose an implementation, you cannot take it back (unless you're ready to wage a flame war with your client base). You can always provide default implementations later as you see fit.
Generally, I'd start with only providing thin interfaces. Then, before providing abstract classes, I might offer utility classes (e.g., Factories, Builders, etc.).
I'd recommend reading Effective Java by Josh Bloch for useful general practices when designing object-oriented code.
MVC/Compund Pattern
You may release earlier version of your package.
later on you can upgrade it based on user requirement.
If you are using MVC or other compound pattern wisely, I believe you also can upgrade your package easily.

How Can I Learn when to build my own Interfaces [duplicate]

This question already has answers here:
Closed 12 years ago.
Possible Duplicates:
Interfaces: Why can’t I seem to grasp them?
How will I know when to create an interface?
I am using C# and I know what are the interfaces and how syntatically use them,etc.
but what I have not learned yet is that when I am tasked to write a project, create a component,... How should I learn better about interfaces so when I want to do something I be able to Think about using them in my design...or for example I want to learn about dependency injection or even using mocking objects for testing, these are all related to good understanding of interfaces and know when and how to use them ... Can you plase provide me some good advice, reading,... then can help me with that?
Use interfaces when you have several things that can perform a common set of actions. How they do those actions can be different, but when as far as using the classes they act the same.
A good real world example is like a network drive vs a regular hard drive. Either way you can perform basic file operations. How they're actually done is different, but most of the time when you want to do something on a drive you don't care if it's a network drive or a physical one. That's an interface.
In hardware, different keyboards are designed differently, they (could) have buttons in different locations, but none of that matters to the computer. The computer's view of a keyboard's interface is the same regardless of any aspects other than it sends key strokes.
What is the interface these things must have in common if they are going to be used in the same way?
If you can answer that then you are on your way to design and using the interface properly in real life scenarios.
The goal of interfaces is to reduce coupling between components of your application. By using interface, you are binding to a contract instead of an implementation. This means that you can change the implementation as you see fit, provided you follow the same contract.
For example, it is considered good practice to use IList<T> instead of List<T>, because IList<T> only states that you need something that acts like a list. This way, other implementations of lists can be substituted without affecting your code. (For example, NHibernate, an object mapping and data access library, uses this to allow lazy loading of collections.)
Excellent candidates for interfaces are classes that interact with external systems (File system, database, network, web services, etc...). If you directly use those systems in your code, you will have trouble testing and refactoring.
I personally find interfaces especially useful in dependency injection and testing scenarios. Since you already understand what interfaces are, you should be able to understand dependency injection. Reading on those concepts will help you recognize good candidates for interfaces.
It's really something that you learn to use with experience.
I've found understanding how interfaces are used in plugin architectures really helpful.
Lots of links out there, e.g. : http://www.codeproject.com/KB/cs/c__plugin_architecture.aspx
Try to imagine how you might write that sort of architecture without using interfaces - then you might fully appreciate what they bring to the table.
If using a a TDD-like workflow, interfaces are often used to define the requirements an object has of another object that it will eventually use. Using interfaces in this fashion allows them to be used to create 'seams' in your application where logic can be replaced/inserted/etc.
One way of thinking about interfaces in this fashion is to think of your objects as sending messages to one another, and that the interfaces are the definitions of the messages that can be sent.

What should be on a checklist that would help someone develop good OO software?

I have used OO programming languages and techniques years ago (primarily on C++) but in the intervening time haven't done much with OO.
I'm starting to make a small utility in C#. I could simply program it all without using good OO practice, but it would be a good refresher for me to apply OO techniques.
Like database normalization levels, I'm looking for a checklist that will remind me of the various rules of thumb for a 'good' object oriented program - a concise yes/no list that I can read through occasionally during design and implementation to prevent me from thinking and working procedurally. Would be even more useful if it contained the proper OO terms and concepts so that any check item is easily searchable for further information.
What should be on a checklist that would help someone develop good OO software?
Conversely, what 'tests' could be applied that would show software is not OO?
Objects do things. (Most important point in the whole of OOP!) Don't think about them as "data holders" - send them a message to do something. What verbs should my class have? The "Responsibility-Driven Design" school of thinking is brilliant for this. (See Object Design: Roles, Responsibilities, and Collaborations, Rebecca Wirfs-Brock and Alan McKean, Addison-Wesley 2003, ISBN 0201379430.)
For each thing the system must do, come up with a bunch of concrete scenarios describing how the objects talk to each other to get the job done. This means thinking in terms of interaction diagrams and acting out the method calls. - Don't start with a class diagram - that's SQL-thinking not OO-thinking.
Learn Test-Driven Development. Nobody gets their object model right up front but if you do TDD you're putting in the groundwork to make sure your object model does what it needs to and making it safe to refactor when things change later.
Only build for the requirements you have now - don't obsess about "re-use" or stuff that will be "useful later". If you only build what you need right now, you're keeping the design space of things you could do later much more open.
Forget about inheritance when you're modelling objects. It's just one way of implementing common code. When you're modelling objects just pretend you're looking at each object through an interface that describes what it can be asked to do.
If a method takes loads of parameters or if you need to repeatedly call a bunch of objects to get lots of data, the method might be in the wrong class. The best place for a method is right next to most of the fields it uses in the same class (or superclass ...)
Read a Design Patterns book for your language. If it's C#, try "Design Patterns in C#" by Steve Metsker. This will teach you a series of tricks you can use to divide work up between objects.
Don't test an object to see what type it is and then take action based on that type - that's a code smell that the object should probably be doing the work. It's a hint that you should call the object and ask it to do the work. (If only some kinds of objects do the work, you can simply have "do nothing" implementations in some objects... That's legitimate OOP.)
Putting the methods and data in the right classes makes OO code run faster (and gives virtual machines a chance to optimise better) - it's not just aesthetic or theoretical. The Sharble and Cohen study points this out - see http://portal.acm.org/citation.cfm?doid=159420.155839 (See the graph of metrics on "number of instructions executed per scenario")
Sounds like you want some basic yes/no questions to ask yourself along your way. Everyone has given some great "do this" and "think like that" lists, so here is my crack at some simple yes/no's.
Can I answer yes to all of these?
Do my classes represent the nouns I am concerned with?
Do my classes provide methods for actions/verbs that it can perform?
Can I answer no to all of these?
Do I have global state data that could either be put into a singleton or stored in class implementations that work with it?
Can I remove any public methods on a class and add them to an interface or make them private/protected to better encapsulate the behavior?
Should I use an interface to separate a behavior away from other interfaces or the implementing class?
Do I have code that is repeated between related classes that I can move into a base class for better code reuse and abstraction?
Am I testing for the type of something to decide what action to do? If so can this behavior be included on the base type or interface that the code in question is using to allow more effect use of the abstraction or should the code in question be refactored to use a better base class or interface?
Am I repeatedly checking some context data to decided what type to instantiate? If so can this be abstracted out into a factory design pattern for better abstraction of logic and code reuse?
Is a class very large with multiple focuses of functionality? If so can I divide it up into multiple classes, each with their own single purpose?
Do I have unrelated classes inheriting from the same base class? If so can I divide the base class into better abstractions or can I use composition to gain access to functionality?
Has my inheritance hierarchy become fearfully deep? If so can I flatten it or separate things via interfaces or splitting functionality?
I have worried way too much about my inheritance hierarchy?
When I explain the design to a rubber ducky do I feel stupid about the design or stupid about talking to a duck?
Just some quick ones off the top of my head. I hope it helps, OOP can get pretty crazy. I didn't include any yes/no's for more advanced stuff that's usually a concern with larger apps, like dependency injection or if you should split something out into different service/logic layers/assemblies....of course I hope you at least separate your UI from your logic.
Gathered from various books, famous C# programmers, and general advice (not much if any of this is mine; It is in the sense that these are various questions i ask myself during development, but that's it):
Structs or Classes? Is the item you're creating a value of it's own, make it a struct. If it's an "object" with attributes and sub-values, methods, and possibly state then make it an object.
Sealed Classes: If you're going to be creating a class and you don't explicitly need to be able to inherit from it make it sealed. (I do it for the supposed performance gain)
Don't Repeat Yourself: if you find yourself copy-past(a/e)ing code around then you should probably (but not always) rethink your design to minimize code duplication.
If you don't need to provide a base implementation for a given abstract class turn it into an interface.
The specialization principle: Each object you have should only do one thing. This helps avoid the "God-object".
Use properties for public access: This has been debated over and over again, but it's really the best thing to do. Properties allow you to do things you normally can't with fields, and it also allows you more control over how the object is gotten and set.
Singletons: another controversial topic, and here's the idea: only use them when you Absolutely Need To. Most of the time a bunch of static methods can serve the purpose of a singleton. (Though if you absolutely need a singleton pattern use Jon Skeet's excellent one)
Loose coupling: Make sure that your classes depend on each other as little as possible; make sure that it's easy for your library users to swap out parts of your library with others (or custom built portions). This includes using interfaces where necessary, Encapsulation (others have mentioned it), and most of the rest of the principles in this answer.
Design with simplicity in mind: Unlike cake frosting, it's easier to design something simple now and add later than it is to design complex now and remove later.
I might chuck some or all of this out the door if i'm:
Writing a personal project
really in a hurry to get something done (but i'll come back to it later.... sometime..... ;) )
These principles help guide my everyday coding and have improved my coding quality vastly in some areas! hope that helps!
Steve McConnell's Code Complete 2 contains a lot of ready to use checklists for good software construction.
Robert C. Martin's Agile Principles, Patterns, and Practices in C# contains a lot of principles for good OO desgin.
Both will give you a solid foundation to start with.
Data belongs with the code that operates on it (i.e. into the same class). This improves maintainability because many fields and methods can be private (encapsulation) and are thus to some degree removed from consideration when looking at the interaction between components.
Use polymorphism instead of conditions - whenever you have to do different things based on what class an object is, try to put that behaviour into a method that different classes implement differently so that all you have to do is call that method
Use inheritance sparingly, prefer composition - Inheritance is a distinctive feature of OO programming and often seen as the "essence" of OOP. It is in fact gravely overused and should be classified as the least important feature
Have I clearly defined the
requirements? Formal requirements documentation may not be necessary, but you should have a clear vision before you begin coding. Mind-mapping tools and prototypes or design sketches may be good alternatives if you don't need formal documentation. Work with end-users and stakeholders as early as possible in the software process, to make sure you are implementing what they need.
Am I reinventing the wheel? If you are coding to solve a common problem, look for a robust library that already solves this problem. If you think you might already have solved the problem elsewhere in your code (or a co-worker might have), look first for an existing solution.
Does my object have a clear, single purpose? Following the principle of Encapsulation, an object should have behavior together with the data that it operates on. An object should only have one major responsibility.
Can I code to an interface? Design By Contract is a great way to enable unit testing, document detailed, class-level requirements, and encourage code reuse.
Can I put my code under test? Test-Driven Development (TDD) is not always easy; but unit tests are invaluable for refactoring, and verifying regression behavior after making changes. Goes hand-in-hand with Design By Contract.
Am I overdesigning? Don't try to code a reusable component. Don't try to anticipate future requirements. These things may seem counterintuitive, but they lead to better design. The first time you code something, just implement it as straightforwardly as possible, and make it work. The second time you use the same logic, copy and paste. Once you have two working sections of code with common logic, you can easily refactor without trying to anticipate future requirements.
Am I introducing redudant code? Don't Repeat Yourself (DRY) is the biggest driving principal of refactoring. Use copy-and-paste only as a first step to refactoring. Don't code the same thing in different places, it's a maintenance nightmare.
Is this a common design pattern, anti-pattern, or code smell? Be familiar with common solutions to OO design problems, and look for them as you code - but don't try to force a problem to fit a certain pattern. Watch out for code that falls into a common "bad practice" pattern.
Is my code too tightly coupled? Loose Coupling is a principle that tries to reduce the inter-dependencies between two or more classes. Some dependencies are necessary; but the more you are dependent on another class, the more you have to fix when that class changes. Don't let code in one class depend on the implementation details of another class - use an object only according to its contract.
Am I exposing too much information? Practice information hiding. If a method or field doesn't need to be public, make it private. Expose only the minimum API necessary for an object to fulfill its contract. Don't make implementation details accessible to client objects.
Am I coding defensively? Check for error conditions, and Fail Fast. Don't be afraid to use exceptions, and let them propagate. In the event your program reaches an unexpected state, it's much, much better to abort an operation, log a stack trace for you to work with, and avoid unpredictable behavior in your downstream code. Follow best practices for cleaning up resources, such as the using() {} statement.
Will I be able to read this code in six months? Good code is readable with minimal documentation. Put comments where necessary; but also write code that's intuitive, and use meaningful class, method, and variable names. Practice good coding style; if you're working on a team project, each member of the team should write code that looks the same.
Does it still work? Test early, test often. After introducing new functionality, go back and touch any existing behavior that might have been affected. Get other team members to peer review and test your code. Rerun unit tests after making changes, and keep them up to date.
One of the best sources would be Martin Fowler's "Refactoring" book which contains a list (and supporting detail) of object oriented code smells that you might want to consider refactoring.
I would also recommend the checklists in Robert Martin's "Clean Code".
SOLID
DRY
TDD
Composition over inheritance
Make sure you read up and understand the following
Encapsulation
(Making sure you only expose the minimal state and functionality to get the job done)
Polymorphism
(Ability for derived objects to behave like their parents)
The difference between and interface and an abstract class
(An abstract class allows
functionality and state to be shared
with it's descendants, an interface
is only the promise that the
functionality will be implemented)
I like this list, although it might be a little dense to be used as a checklist.
UML - Unified Modeling Language, for object modeling and defining the structure of and relationships between classes
http://en.wikipedia.org/wiki/Unified_Modeling_Language
Then of course the programming techniques for OO (most already mentioned)
Information Hiding
Abstraction
Interfaces
Encapsulation
Inheritance / Polymorphism
Some of the rules are language agnostic, some of the rules differ from language to language.
Here are a few rules and comments that contradict some other the previously posted rules:
OO has 4 principles:
Abstraction, Encapsulation, Polymorphism and Inheritence.
Read about them and keep them in mind.
Modelling - Your classes are supposed to model entities in the problem domain:
Divide the problem to sub-domains (packages/namespaces/assemblies)
then divide the entities in each sub-domain to classes.
Classes should contain methods that model what objects of that type do.
Use UML, think about the requirements, use-cases, then class diagrams, them sequences.
(applicable mainly for high-level design - main classes and processes.)
Design Patterns - good concept for any language, implementation differs between languages.
Struct vs. class - in C# this is a matter of passing data by value or by reference.
Interface vs. base-class, is a base-class, does an interface.
TDD - this is not OO, in fact, it can cause a lack of design and lead to a lot of rewriting. (Scrum for instance recommends against it, for XP it is a must).
C#'s Reflection in some ways overrides OO (for example reflection based serialization), but it necessary for advanced frameworks.
Make sure classes do not "know of" other classes unless they have to, dividing to multiple assemblies and being scarce with references helps.
AOP (Aspect Oriented Programming) enhances OOP, (see PostSharp for instance) in a way that is so revolutionary that you should at least look it up and watch their clip.
For C#, read MS guidelines (look up guidelines in VS's MSDN help's index),
they have a lot of useful guidelines and conventions there
Recommended books:
Framework Design Guidelines: Conventions, Idioms, and Patterns for Reusable .NET Libraries
C# 3.0 in a Nutshell

Should you create an interface when there (currently) is only going to be one class that implements it?

Should you always create an interface if there's a possibility that there might be something else that could use it, or wait until there's an actual need for it then refactor to use an interface?
Programming to an interface generally seems like sound advice, but then there's YAGNI...
I guess maybe it depends on the situation. Right now I have an object representing a folder that can contain recipes or other folders. Instead of using Folder directly, should I worry about implementing something like IContainer? In case in the future I want to have a recipe that refers to other sub recipes (say an apple pie recipe that is also a container for a pie crust recipe)
It always depends on the situation. If you KNOW there is going to be another class using the interface, then yes, create the interface class to save time later. However, if you are not sure (and most of the time you aren't) then wait till you need it.
Now that doesn't mean to ignore the possibility of the interface - think about the object's public methods and such with an eye toward making an interface later, but don't clutter your codebase with anything that you don't actually NEED.
Think of an interface as a contract to define semantics, or a concept. That's a general approach and not really language specific. In context of OO, if you are working in a single inheritance model, there is an excellent case to be made for preferring interfaces over classes for defining your object model, since that single super class pathway is fairly precious and you want to save it for something more 'substantial' than defining properties that are exposed on an object, or methods.
To have IContainer semantics (contract) is a fairly poor reason to make an interface out of your folder; better to have your folder (if it is doing any non-trivial logic) 'implement' the (likely already existing) IContainer or ICollection interface in your language's core frameworks.
As always, the better choice is fairly dependent on the specific problem. In case of your recipes that are also folders (?!) you are probably thinking of a parent-child, or composition, relationship -- a semantic that can (and should) be expressed using interfaces if you will have other elements in your system 'operate' on things that are composed using that sort of semantics.
There is a bit of overhead (programming wise) with interfaces, and, if you find yourself when you are done with nothing more than a set of Woof and IWoof classes and interfaces, then you'll know you probably didn't need to express your problem in terms of interfaces -- simple classes would have been sufficient.
As a rule, for any I, you should have at least a couple of concrete classes (with more meaningful names other than IImpl, or ).
Hope that helps.
There will be always a test that use it, right (you do unit tests, don't you?). Which means it's always N + 1 classes that use it, where N is number of classes that use your class in application.
Another purpose of interface besides dependency injection is separation of concern so that your class may actually implement multiple interfaces.
Keep all of that in mind but you can always have interface(s) introduced later via refactoring if not implemented in the beginning.
Generally, you shouldn't bother with creating an interface if only one class is going to implement it, even if you anticipate a possible class for it since there may be implementation issues that won't come up until the class is actually tested in a scenario, in which case a prematurely created interface may have too many memebrs or may be missing a member.
For example, the .NET Framework Bas Class Library team has admitted to prematurely designing ICollection when it included a SyncRoot property. For the later generic ICollection<T> they decided to remove it (http://blogs.msdn.com/bclteam/archive/2005/03/15/396399.aspx).
If you are going to create a mock object implementing the same interface then that would count as a second implementation that justifies creating the inteface. Not all unit tests warrant a mock-style interface, though.
I would say it depends more on how many places you're going to use the class, and less on how many classes might possibly implement the interface. If you're only using Folder in one or two places then I would say wait until there's an actual need for the interface before you implement it and refactor. However, if Folder is going to be used in 100 different places, then you can save some time by programming to an interface up front.
A lot of the people have already outlined very sound advice.
One thing I'd like to add is that if you are looking to avoid direct hard dependencies on concrete classes then interfaces will help by providing loose coupling.
If you are creating a plug-in based architecture then interfaces are definitely the way to go. Also, if you are planning to write unit tests either side by side or later down the line, you will probably notice that code which calls into your folder class(es) will have to carry around a concrete implementation for the calling code to be testable.
If your concrete implementation of the folder class(es) is in turn talking to a DB or a service then you will need to have that carried over into your tests as well which will get unwieldy very quickly.
Just my 2 cents.

Categories

Resources