Ok this is a bit more theoretical question.
I have PlayerRepository. This is a class that is used to make actions on my SQLite database. I've implemented there actions like select, insert, update etc.
public PlayerRepository(Context context) {
super(context, com.fixus.portals.model.Player.class);
open();
}
super in constructor is cause PlayerRepository extends Repository which is also my class. The most important part of Repository is this one
public class Repository<T> {
protected static SQLiteDatabase db = null;
protected static MainHelper helper = null;
protected Context context;
private Class<T> type;
public Repository(Context context, Class<T> classz) {
this.type = classz;
this.context = context;
if(helper == null) {
helper = new MainHelper(context.getApplicationContext());
}
}
public static void open() {
if(db == null) {
db = helper.getWritableDatabase();
}
}
}
As you can see when I create the repository I'm opening DB if it wasn't open before. To do that I need to pass the Context of the application/activity. That is not a problem.
BUT sometimes I want to use my repository out side of an activity. In some kind of tool class that need to get data. So I have two ways that I can think about
I get the data in activity and pass it to my tool class/method so I don't need to use repository in it. This is not very flexible
I need to pass context to my tool class/method. But that means that every kind of operation need to receive a context and I'm not sure this is a good way
Am I missing something ? is there any better way to handle it ?
You always need a Context to access the SQLite database so what u could do is change the constructor of that specific tool class and pass a new instance of PlayerRepository as a parameter. This prevents your tool class of needing a context itself.
Imo if u have multiple classes using the database best approach is to create a new class whose only job is doing database actions and put all the needed action inside that one.
Just create an object of this database class with the Context of the current activity the to Tools and PlayerRepository constructors. This way neither your PlayerRepository or Tools classes need Context and both can make actions on the database.
Even if you should really need Context in PlayerRepository it is always best to keep all database related functions centralized in a single class.
I understand that this is an old question but still i'll write for those like me who will pass by this in future.
In order to get rid of the context problem with repository pattern used for accessing database you can implement DI (Dependency Injection) pattern in your project. There are many reasons to do such and that question illustrates one of them.
If you implement DI you would have only one instance of database repository amongst the entire module (or app). This instance would be created in a class which has context, and injected to those classes where needed.
One of the simpliest approaches for using DI is to use Dagger 2 library. All of the related information you could find on their site.
Related
I'm writing an application meant to manage a database using both JDBC and JPA for an exam. I would like the user to select once at the beginning the API to use so that all the application will use the selected API (whether it be JPA or JDBC).
For the moment I decided to use this approach:
I created an interface for each DAO class (e.g. interface UserDAO) with all needed method declarations.
I created two classes for each DAO distinguished by the API used (e.g UserDAOImplJDBC and UserDAOImplJPA). Both of them implement the interface (in our case, UserDAO).
I created a third class (e.g. UserDAOImpl) that extends the JDBC implementation class. In all my code I've been always using this class. When I wanted to switch to the JPA I just had to change in all DAO classes the extends ***ImplDAOJDBC to extends ***ImplDAOJPA.
Now, as I'm starting having many DAO classes it's starting being complicate to modify the code each time.
Is there a way to change all extends faster?
I was considering adding an option in the first screen (for example a radioGroup) to select JDBC or JPA. But yet I have no idea how to make it work without having to restructure all code. Any idea?
Use a factory to get the appropriate DAO, every time you need one:
public class UserDaoFactory {
public UserDao create() {
if (SomeSharedSingleton.getInstance().getPersistenceOption() == JDBC) {
return new UserDAOImplJDBC();
}
else {
return new UserDAOImplJPA();
}
}
}
That's a classic OO pattern.
That said, I hope you realize that what you're doing there should really never be done in a real application:
there's no reason to do the exact same thing in two different ways
the persistence model of JPA and JDBC is extremely different: JPA entities are managed by the JPA engine, so every change to JPA entities is transparently made persistent. That's not the case with JDBC, where the data you get from the database is detached. So the way to implement business logic is very different between JPA and JDBC: you typically never need to save any change when using JPA.
You got 1 and 2 right, but 3 completely wrong.
Instead of having Impl extending one of the other implementations, choose which implementation to initialize using a utility method, for example. That's assuming you don't use Dependency Injection framework such as Spring.
UserDAO dao = DBUtils.getUserDAO();
public class DBUtils {
public static boolean shouldUseJdbc() {
// Decide on some configuration what should you use
}
public static UserDAO getUserDAO() {
if (shouldUseJdbc()) {
return new UserDAOImplJDBC();
}
else {
return new UserDAOImplJPA();
}
}
}
This is still jus an examle, as your DAOs don't need to be instantiated each time, but actually should be singletons.
I've followed the example at https://www.playframework.com/documentation/2.5.x/JavaCache and I can successfully access the cache, but I only seem to be able to do this from a controller method. Specifically:
#Inject
public OverviewController(CacheApi cache) { this.lookupCache = cache; }
From the controller actions, I can then interrogate the cache as needed via lookupCache.
My problem is that I need this functionality a few layers deeper in the application, and I'd really like to prevent passing a reference to lookupCache through several other constructors.
The documentation seems to suggest the capability of adding this injection on any "component", which would give me what I want, but if I try the same injection on some other class:
public class DropDownCache {
private CacheApi lookupCache;
#Inject
public DropDownCache(CacheApi cache) { this.lookupCache = cache; }
}
...then any time I instantiate DropDownCache, I have to supply the CacheApi instance. This tells me that the controller is magically being instantiated with this reference, I just don't know how to access it.
Does anyone have any pointers on where the controllers get their instance of CacheApi from?
I'm new to OSGi and I'm interested in retrofitting some of my jars as OSGi bundles.
However I do not want to introduce additional dependencies to any osgi-specific libraries.
As such annotations are out of the question as are programmatic calls to bundle contexts and what not.
I have found a near match to my requirements in declarative services which allows me to expose my lower level bundles without impacting dependencies however at the higher level (where i actually need to consume the services) i'm still a bit stuck.
I understand that the component xml can be used to declare implementations of services (which i already use for my lower level jars) but also to inject service instances into a specific POJO.
Now my question: how do I get access to the osgi-managed POJO which has the services injected into it? Is it at all possible without introducing new dependencies or do I have to do it programmatically?
If the latter is the case can someone point me in the direction of some code to do it, in other words the component-equivalent of bundleContext.getServiceReference()?
UPDATE
To clarify, if you take the fifth part of this tutorial: http://www.vogella.com/articles/OSGiServices/article.html
He declares a component.xml file which uses reference binding to inject a service into the object QuoteConsumer.
Great, now how do I get an instance of QuoteConsumer that has the necessary services injected into it, I can't very well do "new QuoteConsumer()" right?
UPDATE2
Currently I am registering the instance created by osgi as a static variable which can be requested, I'm thinking this is not the best method especially because I can't set the constructor to private. (the latter would at least result in a true singleton)
Basically the Factory class has:
private void activate() {
instance = this;
}
UPDATE3
A full example of a factory:
public class Factory {
private static Factory instance;
public static Factory getInstance() {
if (instance == null)
instance = new Factory();
return instance;
}
private MyInterface implementation;
public void setMyInterface(MyInterface implementation) {
this.implementation = implementation;
}
public void unsetMyInterface(MyInterface implementation) {
implementation = null;
}
public MyInterface getMyInterface() {
if (implementation == null) {
ServiceLoader<MyInterface> serviceLoader = ServiceLoader.load(MyInterface.class);
Iterator<MyInterface> iterator = serviceLoader.iterator();
if (iterator.hasNext())
implementation = iterator.next();
else
implementation = new MyInterfaceStub();
}
return implementation;
}
#SuppressWarnings("unused")
private void activate() {
instance = this;
}
#SuppressWarnings("unused")
private void deactivate() {
instance = null;
}
}
Any client code can then do:
Factory.getInstance().getMyInterface();
and receive the OSGi loaded service, the SPI loaded one or a stub.
You can still manually set the service instance if necessary.
UPDATE4
To clarify further: this pattern is not meant for applications that are designed from the ground up to be run in an OSGi container but rather for low level libraries that have to run everywhere and even when on an OSGi container must not assume that all consumers are actually using OSGi.
You sound confused ... :-) A service is a replacement for static factories so your factory should not have to exist.
The whole idea of DS is that for each component:
wait until its dependencies are met
create an instance
bind the instance to its dependencies
call activate on the instance
register the instance as a service
So whenever you get a service managed by DS it already is injected (bound) with its dependencies. So as long as you stay with service dependencies you never need static factories ... The whole idea of service is that you do NOT have static factories and can only work with (injected) instances. One of the best parts of OSGi is that you rarely work with factories.
One remark about the requirement not to use annotations. The OSGi annotations are class time only, they do not create a runtime dependency. I strongly suggest to use them since they make services as lightweight as a class and are typesafe in contrast to XML.
One trick to use the annotations and not clutter your code is to create extend your implementation classes that you want to be an OSGi component and add the annotations on this class.
To access a service, you declare a reference to it from another component:
#Reference
public void setFoo(Foo foo) {
this.foo = foo;
}
You might find the Bndtools tutorial will help to clarify the concepts.
I'd say you are on the right track. You can use a static field if it is convenient.
The important thing is that you make the rest of your code deal with the QuoteConsumer appearing and disappearing. So, put in your activator the code to do what you need to do when the QuoteConsumer is available (register it in some field, call some initialization code, I don't know) and put in your deactivate the code you need to indicate that the QuoteConsumer is no longer available.
I'm trying to write a framework where arbitrary bean classes are injected with classes from my API, and they can interact with both those classes as well have triggered callbacks based on defined annotations. Here's an example bean:
#Experiment
static class TestExperiment {
private final HITWorker worker;
private final ExperimentLog log;
private final ExperimentController controller;
#Inject
public TestExperiment(
HITWorker worker,
ExperimentLog expLog,
ExperimentController controller
) {
this.worker = worker;
this.expLog = expLog;
this.controller = controller;
}
#SomeCallback
void callMeBack() {
... do something
log.print("I did something");
}
}
I'm trying to use Guice to inject these beans and handle the interdependencies between the injected classes. However, I have two problems:
One of the classes I pass in (HITWorker) is already instantiated. I couldn't see how to move this to a Provider without significantly complicating my code. It is also persistent, but not to the Guice-defined session or request scope, so I am managing it myself for now. (Maybe if the other issues are overcome I can try to put this in a provider.)
More importantly, I need a reference to the other injected classes so I can do appropriate things to them. When Guice injects them, I can't access them because the bean class is arbitrary.
Here's some really bad code for what I basically need to do, which I am sure is violating all the proper dependency injection concepts. Note that hitw is the only instance that I need to pass in, but I'm creating the other dependent objects as well because I need references to them. With this code, I'm basically only using Guice for its reflection code, not its dependency resolution.
private void initExperiment(final HITWorkerImpl hitw, final String expId) {
final ExperimentLogImpl log = new ExperimentLogImpl();
final ExperimentControllerImpl cont = new ExperimentControllerImpl(log, expManager);
// Create an experiment instance with specific binding to this HITWorker
Injector child = injector.createChildInjector(new AbstractModule() {
#Override
protected void configure() {
bind(HITWorker.class).toInstance(hitw);
bind(ExperimentLog.class).toInstance(log);
bind(ExperimentController.class).toInstance(cont);
}
});
Object experimentBean = child.getInstance(expClass);
expManager.processExperiment(expId, experimentBean);
// Initialize controller, which also initializes the log
cont.initialize(expId);
expManager.triggerStart(expId);
tracker.newExperimentStarted(expId, hitw, cont.getStartTime());
}
Am I screwed and just have to write my own injection code, or is there a way to do this properly? Also, should I just forget about constructor injection for these bean classes, since I don't know what they contain exactly anyway? Is there any way to get the dependencies if I am asking Guice to inject the bean instead of doing it myself?
For context, I've been reading the Guice docs and looking at examples for several days about this, to no avail. I don't think I'm a complete programming idiot, but I can't figure out how to do this properly!
Your "experiment" seems to be something like a "request" in the sense that it has a defined lifecycle and some associated stuff the experiment can pull in at will.
Therefore I think you should wrap all that into a custom scope as described in the docs about Custom Scopes. This matches your case in several points:
You can "seed" the scope with some objects (your HITWorker)
The lifecycle: do "enter scope" before you setup the experiment and "exit scope" after you finished your work.
Access to "shared" stuff like ExperimentLog and ExperimentController: Bind them to the scope. Then both the framework and the experiment instance can simple #Inject them and get the same instance.
I have some Android projects and most of them are connected with SQLite databases. I'm interested is it a good programming practice (or a bad habbit) to use some static class like "DatabaseHelper.class" in which I would have all static method related for database manipulation. For example
public static int getId(Context context, String name) {
dbInit(context);
Cursor result = db.rawQuery("SELECT some_id FROM table WHERE some_name = '" + name + "'", null);
result.moveToFirst();
int id = result.getInt(result.getColumnIndex("some_id"));
result.close();
return id;
}
where dbInit(context) (which is used in all my static methods for database manipluation) is
private static void dbInit(Context context) {
if (db == null) {
db = context.openOrCreateDatabase(DATABASE_NAME, Context.MODE_PRIVATE, null);
}
}
Then when I need something I can easily call those method(s) with for example
int id = DatabaseHelper.getId(this, "Abc");
EDIT: Do I have to use dbClose on every connection or leave it open per-activity and close per-activity? So do I have change that upper code to something like this?
...
dbClose();
return id;
}
private static void dbClose() {
if (db != null) {
db.close();
}
}
I would suggest you get into the habit of getting a database connection every time you need one, and releasing it back when you are done with it. The usual name for such a facility is a "database connection pool".
This moves the connection logic out of your actual code and into the pool, and allow you to do many things later when you need them. One simple thing, could be that the pool logs how long time a connection object was used, so you can get information about the usage of the database.
Your initial pool can be very simple if you only need a single connection.
I would definitely have your database related code in a separate class, but would really recommend against using a static class or Singleton. It might look good at first because of the convenience, but unfortunately it tightly couples your classes, hides their dependencies, and also makes unit testing harder.
The drawbacks section in wikipedia gives you a small overview of why you might want to explore other techniques. You can also head over here or over there where they give concrete examples of a class that uses a database access singleton, and how using dependency injection instead can solve some of the issues I mentioned.
As a first step, I would recommend using a normal class that you instantiate in your constructor, for ex:
public class MyActivity extends Activity {
private DBAccess dbAccess;
public MyActivity() {
dbAccess = new DBAccess(this);
}
}
As a second step, you might want to investigate frameworks like RoboGuice to break the hard dependency. You code would look something like:
public class MyActivity extends Activity {
#Inject private DBAccess dbAccess;
public MyActivity() {
}
}
Let us know if you want more details!
If you're going to use a singleton the very minimum requirement is that you make it stateless/threadsafe. If you use your getId method as it stands concurrent invocations could potentially cause all manner of strange bugs...
dbInit(context);
May be called for Thread A which then stops processing before hitting the query statement. Subsequently Thread B executes getId and also calls dbInit passing in a different context all together. Thread A would then resume and attempt to execute the query on B's context.
Maybe this isn't a problem in your application but I'd recommend sticking a synchronized modifier on that getId method!