You can create a wrapper that encapsulates objectify specific code.
here is an example
Step1- wrap objectify API
http://code.google.com/p/listwidget/source/browse/trunk/src/main/java/com/listwidget/server/service/ObjectifyDao.java
Step2- use it :
http://code.google.com/p/listwidget/source/browse/trunk/src/main/java/com/listwidget/server/service/ItemListDao.java
http://code.google.com/p/listwidget/source/browse/trunk/src/main/java#java%2Fcom%2Flistwidget%2Fserver%2Fservice
http://code.google.com/p/listwidget/
if you want to wrap CRUD operation it is simple.
however as Objectify grows, it does not make sense to wrap Objectify,
because Objectify itself is a wrapper around low level Datastore API.
ask yourself, do you need to wrap Hibernate code for example? no.
it is best to declare an interface that specifies all the DataAccess
operations.
then have different implementation of this interface for specific
persistence mechanism.
public interface EmployeeDAO{
List<Employee> findAllEmployees();
Employee findEmployeeById(Long id);
}
public class EmployeeDAOImplObjectify implements EmployeeDAO {
//objectify specific code here
Employee findEmployeeById(Long id){
//method containing the implementation
}
}
public class AccountDAOImplObjectify implements AccountDAO {
//objectify specific code here
or to take it to the very extreme,
we can have dozens of implementation for Employee DAO interface,
for different underlying persistence mechanisms
(Relational vs Non-Relational, for different vendors, mapping
frameworks)
in the code below, the term Repository is used in place of DAO, (it is
part of Spring lingo)
//EmployeeDAO
public interface EmployeeRepository {
List<Employee> findAllEmployees();
Employee findEmployeeById(Long id);
....
}
this is a bit extreme, but
// marker interfaces for Google App Engine BigTable Datastore
public interface GAEDataStoreRepository {}
public interface ObjectifyRepository extends GAEDataStoreRepository{}
public interface TwigPersistRepository extends
GAEDataStoreRepository{}
//marker interfaces for SQL RDBMS
public interface SQLRepository{}
public interface OracleRepository extends SQLRepository{}
public interface HibernateRepository extends SQLRepository{}
now in package:
com.project.dao.objectify.employee
public class ObjectifyEmployeeRepository implements
EmployeeRepository, ObjectifyRepository{
///here you put all the concrete Objectify specific API. ofy()
}
public class ObjectifyAccountRepository implements AccountRepository,
ObjectifyRepository{
//implementation
}
if you later decided to use an RDBMS, you can write
public class HibernateEmployeeRepository implements
EmployeeRepository, HibernateRepository{}
public class HibernateAccountRepository implements AccountRepository,
HibernateRepository{}
the idea is that rest of the application interacts with
EmployeeRepository(EmployeeDAO API),
rather than interacting with the classes that contains the low level
implementation details.
it is the Object Oriented best practice of programming to the
interfaces, since an interface defines a contract that clients of this
API can rely on.
(clients for example web-tier/GUI)
from their point of view it does not matter whether the data is stored
in a local file, local database, or somewhere on the cloud.
they know if they call findEmployeeById, passing it an ID, they will
get an Employee object, and cant care less where or how this Employee
Object was retrieved.
as a result you can swap underlying persistence mechanism without
affecting the rest of your application.
I therefore suggest you define a DAO interface for each of your
entities, and then implement this interface,
putting all the objectify specific code in this implementation.
You can then use the interface in other part of your app (eg. web
tier) instead of the concrete implementation class, what this means
is that other part of your app "depend" on the interface not
implementation,
which contributes to loose coupling, and clean separation of
responsibilities.