Persist Data by Programming Against Interface

Interface between Database and File persistence

Your teacher give you a right hint, when you need a few ways to storage data of your application simple made this logic separately from another logic of application and hide it behind interface. Your program doesn't need to know how and where you store data, it only want to pass data to storage and retrieve. Even more if you have problems with serialization or something with storage part of application you may push it apart and concentrate on another logic after define contract with help of application saves and reads data. In example when you build a new PC you may assembly it in random order or even have only half of all parts in same time because all parts (hdd, memory, gpu, etc...) have own interfaces and all implementations from any company obeys to it's common interface.

Code of your application will be something like this

class GameClass {
private final Dao dao;

GameClass(Dao dao) { this.dao = dao; }

void gameMethod() {
Car car = new Car();
dao.save(car);
}

}

As you can see GameClass don't know what kind of implementation of Dao here, it only relies on contract.

Hibernate: Persist class as Interface

You can implement an attribute converter for each your particular implementation of IRole interface and then use them.

  @Convert(converter=RoleA.class)
@Column(name="role_id_a")
private IRole roleA;

@Convert(converter=RoleB.class)
@Column(name="role_id_b")
private IRole roleB;

Persist a Java instance of an Interface in a database

If that's really all you know about the object, then all you can really do is store it in a bytea field and retrieve it again later when needed.

Use bytea not text. It's faster for binary data (no collations or natural language support) and it supports storing zero (null) bytes, unlike text.

This should be an absolute last resort way to store data in a DB. It always leads to pain. Someone will come along and ask "ok, now write a query where you find all objects of type com.mycompany.Apple with their colour property set to "red". You will have to reply "sorry, I can't do that, the database just sees a pile of binary gibberish". You will be told "Do it anyway". So you read every object out of the database, deserialize it, check its type, check its properties by reflection and discard it or keep it based on the result. The database gets bigger and this gets slower and slower. So you start adding columns to cache information about the objects in the DB, but then they start getting out of sync with the stored data because some code forgets to update them...

I've written queries that poke around in bytea strings to manually deserialize and examine parts of Java objects before. Horrible stuff. Do not recommend.

If you can possibly do so, use a more practical serialisation of the object structure, like json. Something you can query in a practical manner from the database when you are inevitably asked to do so.

What does it mean to program to an interface?

There are some wonderful answers on here to this questions that get into all sorts of great detail about interfaces and loosely coupling code, inversion of control and so on. There are some fairly heady discussions, so I'd like to take the opportunity to break things down a bit for understanding why an interface is useful.

When I first started getting exposed to interfaces, I too was confused about their relevance. I didn't understand why you needed them. If we're using a language like Java or C#, we already have inheritance and I viewed interfaces as a weaker form of inheritance and thought, "why bother?" In a sense I was right, you can think of interfaces as sort of a weak form of inheritance, but beyond that I finally understood their use as a language construct by thinking of them as a means of classifying common traits or behaviors that were exhibited by potentially many non-related classes of objects.

For example -- say you have a SIM game and have the following classes:

class HouseFly inherits Insect {
void FlyAroundYourHead(){}
void LandOnThings(){}
}

class Telemarketer inherits Person {
void CallDuringDinner(){}
void ContinueTalkingWhenYouSayNo(){}
}

Clearly, these two objects have nothing in common in terms of direct inheritance. But, you could say they are both annoying.

Let's say our game needs to have some sort of random thing that annoys the game player when they eat dinner. This could be a HouseFly or a Telemarketer or both -- but how do you allow for both with a single function? And how do you ask each different type of object to "do their annoying thing" in the same way?

The key to realize is that both a Telemarketer and HouseFly share a common loosely interpreted behavior even though they are nothing alike in terms of modeling them. So, let's make an interface that both can implement:

interface IPest {
void BeAnnoying();
}

class HouseFly inherits Insect implements IPest {
void FlyAroundYourHead(){}
void LandOnThings(){}

void BeAnnoying() {
FlyAroundYourHead();
LandOnThings();
}
}

class Telemarketer inherits Person implements IPest {
void CallDuringDinner(){}
void ContinueTalkingWhenYouSayNo(){}

void BeAnnoying() {
CallDuringDinner();
ContinueTalkingWhenYouSayNo();
}
}

We now have two classes that can each be annoying in their own way. And they do not need to derive from the same base class and share common inherent characteristics -- they simply need to satisfy the contract of IPest -- that contract is simple. You just have to BeAnnoying. In this regard, we can model the following:

class DiningRoom {

DiningRoom(Person[] diningPeople, IPest[] pests) { ... }

void ServeDinner() {
when diningPeople are eating,

foreach pest in pests
pest.BeAnnoying();
}
}

Here we have a dining room that accepts a number of diners and a number of pests -- note the use of the interface. This means that in our little world, a member of the pests array could actually be a Telemarketer object or a HouseFly object.

The ServeDinner method is called when dinner is served and our people in the dining room are supposed to eat. In our little game, that's when our pests do their work -- each pest is instructed to be annoying by way of the IPest interface. In this way, we can easily have both Telemarketers and HouseFlys be annoying in each of their own ways -- we care only that we have something in the DiningRoom object that is a pest, we don't really care what it is and they could have nothing in common with other.

This very contrived pseudo-code example (that dragged on a lot longer than I anticipated) is simply meant to illustrate the kind of thing that finally turned the light on for me in terms of when we might use an interface. I apologize in advance for the silliness of the example, but hope that it helps in your understanding. And, to be sure, the other posted answers you've received here really cover the gamut of the use of interfaces today in design patterns and development methodologies.

What do programmers mean when they say, Code against an interface, not an object.?

Consider:

class MyClass
{
//Implementation
public void Foo() {}
}

class SomethingYouWantToTest
{
public bool MyMethod(MyClass c)
{
//Code you want to test
c.Foo();
}
}

Because MyMethod accepts only a MyClass, if you want to replace MyClass with a mock object in order to unit test, you can't. Better is to use an interface:

interface IMyClass
{
void Foo();
}

class MyClass : IMyClass
{
//Implementation
public void Foo() {}
}

class SomethingYouWantToTest
{
public bool MyMethod(IMyClass c)
{
//Code you want to test
c.Foo();
}
}

Now you can test MyMethod, because it uses only an interface, not a particular concrete implementation. Then you can implement that interface to create any kind of mock or fake that you want for test purposes. There are even libraries like Rhino Mocks' Rhino.Mocks.MockRepository.StrictMock<T>(), which take any interface and build you a mock object on the fly.

Persist collection of interface using Hibernate

JPA annotations are not supported on interfaces. From Java Persistence with Hibernate (p.210):

Note that the JPA specification
doesn’t support any mapping annotation
on an interface! This will be resolved
in a future version of the
specification; when you read this
book, it will probably be possible
with Hibernate Annotations.

A possible solution would be to use an abstract Entity with a TABLE_PER_CLASS inheritance strategy (because you can't use a mapped superclass - which is not an entity - in associations). Something like this:

@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public abstract class AbstractAnimal {
@Id @GeneratedValue(strategy = GenerationType.TABLE)
private Long id;
...
}

@Entity
public class Lion extends AbstractAnimal implements Animal {
...
}

@Entity
public class Tiger extends AbstractAnimal implements Animal {
...
}

@Entity
public class Zoo {
@Id @GeneratedValue
private Long id;

@OneToMany(targetEntity = AbstractAnimal.class)
private Set<Animal> animals = new HashSet<Animal>();

...
}

But there is not much advantages in keeping the interface IMO (and actually, I think persistent classes should be concrete).

References

  • Annotations, inheritance and interfaces
  • using MappedSuperclass in relation one to many
  • Polymorphic association to a MappedSuperclass throws exception

What does program to interfaces, not implementations mean?

Interfaces are just contracts or signatures and they don't know
anything about implementations.

Coding against interface means, the client code always holds an Interface object which is supplied by a factory. Any instance returned by the factory would be of type Interface which any factory candidate class must have implemented. This way the client program is not worried about implementation and the interface signature determines what all operations can be done. This can be used to change the behavior of a program at run-time. It also helps you to write far better programs from the maintenance point of view.

Here's a basic example for you.

public enum Language
{
English, German, Spanish
}

public class SpeakerFactory
{
public static ISpeaker CreateSpeaker(Language language)
{
switch (language)
{
case Language.English:
return new EnglishSpeaker();
case Language.German:
return new GermanSpeaker();
case Language.Spanish:
return new SpanishSpeaker();
default:
throw new ApplicationException("No speaker can speak such language");
}
}
}

[STAThread]
static void Main()
{
//This is your client code.
ISpeaker speaker = SpeakerFactory.CreateSpeaker(Language.English);
speaker.Speak();
Console.ReadLine();
}

public interface ISpeaker
{
void Speak();
}

public class EnglishSpeaker : ISpeaker
{
public EnglishSpeaker() { }

#region ISpeaker Members

public void Speak()
{
Console.WriteLine("I speak English.");
}

#endregion
}

public class GermanSpeaker : ISpeaker
{
public GermanSpeaker() { }

#region ISpeaker Members

public void Speak()
{
Console.WriteLine("I speak German.");
}

#endregion
}

public class SpanishSpeaker : ISpeaker
{
public SpanishSpeaker() { }

#region ISpeaker Members

public void Speak()
{
Console.WriteLine("I speak Spanish.");
}

#endregion
}

alt text

This is just a basic example and
actual explanation of the principle is
beyond the scope of this answer.

EDIT

I have updated the example above and added an abstract Speaker base class. In this update, I added a feature to all Speakers to "SayHello". All speaker speak "Hello World". So that's a common feature with similar function. Refer to the class diagram and you'll find that Speaker abstract class implement ISpeaker interface and marks the Speak() as abstract which means that the each Speaker implementation is responsible for implementing the Speak() method since it varies from Speaker to Speaker. But all speaker say "Hello" unanimously. So in the abstract Speaker class we define a method that says "Hello World" and each Speaker implementation will derive the SayHello() method.

Consider a case where SpanishSpeaker cannot Say Hello so in that case you can override the SayHello() method for Spanish Speaker and raise proper exception.

Please note that, we have
not made any changes to Interface
ISpeaker. And the client code and
SpeakerFactory also remain unaffected
unchanged. And this is what we achieve by Programming-to-Interface.

And we could achieve this behavior by simply adding a base abstract class Speaker and some minor modification in Each implementation thus leaving the original program unchanged. This is a desired feature of any application and it makes your application easily maintainable.

public enum Language
{
English, German, Spanish
}

public class SpeakerFactory
{
public static ISpeaker CreateSpeaker(Language language)
{
switch (language)
{
case Language.English:
return new EnglishSpeaker();
case Language.German:
return new GermanSpeaker();
case Language.Spanish:
return new SpanishSpeaker();
default:
throw new ApplicationException("No speaker can speak such language");
}
}
}

class Program
{
[STAThread]
static void Main()
{
//This is your client code.
ISpeaker speaker = SpeakerFactory.CreateSpeaker(Language.English);
speaker.Speak();
Console.ReadLine();
}
}

public interface ISpeaker
{
void Speak();
}

public abstract class Speaker : ISpeaker
{

#region ISpeaker Members

public abstract void Speak();

public virtual void SayHello()
{
Console.WriteLine("Hello world.");
}

#endregion
}

public class EnglishSpeaker : Speaker
{
public EnglishSpeaker() { }

#region ISpeaker Members

public override void Speak()
{
this.SayHello();
Console.WriteLine("I speak English.");
}

#endregion
}

public class GermanSpeaker : Speaker
{
public GermanSpeaker() { }

#region ISpeaker Members

public override void Speak()
{
Console.WriteLine("I speak German.");
this.SayHello();
}

#endregion
}

public class SpanishSpeaker : Speaker
{
public SpanishSpeaker() { }

#region ISpeaker Members

public override void Speak()
{
Console.WriteLine("I speak Spanish.");
}

public override void SayHello()
{
throw new ApplicationException("I cannot say Hello World.");
}

#endregion
}

alt text

Programming against interfaces & Entity Framework 4.0

Well a better solution (in my opinion), is to do the following:

Create Repositories for your Entity Data Model, exposing either ICollection<T> or IQueryable<T>

Use interfaces on your Repository:

public interface IRepository
{
public ICollection<Person> Find(string name); // tighter, more maintanability
public IQueryable<Person> Find(); // full power! but be careful when lazy loading

Because of the interfaces, you can swap-in-out mocks, other ORM's:

public class MockRepo : IRepository
{
public List<Person> persons; // mimics entity set
}

There is only so much you can abstract away.

If your worried about using ObjectSet (which is tied to EF), use POCO's.

Look at some of my other questions for more info (as we're building this architecture right now).

Also, think about using Dependency Injection. Here, you can get the repository out of the business of managing the ObjectContext - you can inject the Repository a Unit of Work (which is a wrapper for ObjectContext - so multiple repositories, or aggregate roots, can handle the same context).

In our solution, nothing touches Entity Framework (or any persistence logic) apart from the Repositories, which are in a seperate assembly.

HTH.



Related Topics



Leave a reply



Submit