I'm trying to undersatnd how to use Props correctly. My first thought was that Props objects contain some property of the actor being created. These properties might include the actor's field values as well as some deployment related information (e.e.g which dispatcher to use). The later has nothing to do with the actual actor and therefore should be shipped independent.
But in the documentation said the the good practice is to use static factory method within the actor like this (documentation removed):
public class DemoActor extends UntypedActor {
public static Props props(final int magicNumber) {
return Props.create(new Creator<DemoActor>() {
private static final long serialVersionUID = 1L;
#Override
public DemoActor create() throws Exception {
return new DemoActor(magicNumber);
}
});
}
}
I think this is not quite good if for instance we want to use one dispatcher now, and the requirements will change at some point in the future. It will lead to modifying the Actor class which is (in my opinion) incorrect.
The static factory method, I believe, may be particularly useful for Java, which tends to get quite verbose with Akka. While the code you've shown is for the Actor class, you will also usually have some Inversion-of-Control style configuration or bootstrapper class where you typically set up the actor system and then the actors with the ActorSystem#actorOf class.
Now, after retrieving the base Props instance from the Actor's props factory method you can configure it a bit to your purposes (Props is immutable but have methods returning modified instances). In case you need a different dispatcher then you will just modify your bootstrapper class from something like this:
ActorSystem system = ...;
system.actorOf(DemoActor.props(42), "demo-with-default-dispatcher");
to:
system.actorOf(DemoActor.props(42).withDispatcher("DemoDispatcher"), "demo-with-configured-dispatcher");
(these are just minimal code snippets but I think you get the idea)
Related
My question is the same as this one except it is for Java, specifically applied to properties. Ideally I would like to create one instance of Properties, and call the methods from all of the classes without creating new instances. I would also want to read from a single instance of properties so I only have a single source of the truth.
I have read the API for Properties and it doesn't answer my question.
This question indicates I need to include the reference in the class constructor. Is there a better way??
The fisrt link, "this one" is a link to the Oracle documentation...
If you want to load your properties only once, you should use the singleton pattern. But be carefull that this pattern can be an anti-pattern and may make your unit tests more complex.
To avoid those drawbacks it is better to pass the reference to your properties via a constructor.
/* This is your singleton. It takes care of loading the properties only once and can delegate access method to it */
public class Configuration {
private static Configuration instance; // created only once
public static getInstance() {
instance = // Read the Singelton pattern to create it only once
}
private Properties properties; // loaded only once
public String get(String key) {
return properties.getProperty(key);
}
}
public class Component {
private final Configuration cfg;
public Component (Configuration cfg) {
this.cfg = cfg;
}
}
public class StarterOrDiContainer {
// ..
Component component = new Component(cfg.getInstance());
}
Let's take the system properties as example. In this implementation http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/lang/System.java#System.getProperty%28java.lang.String%29, the properties are just stored in a static class attribute. Either make this attribute public or create public accessor methods. Short answer: just make it static.
You can initialize static data with static initializers, if things get a little bit more complex. (https://docs.oracle.com/javase/tutorial/java/javaOO/initial.html)
This question is about a correct usage of Guice #Assisted and #Provides and also, how to do it.
The current design I refer to is something like this:
The class in the top of the hierarchy is also the only class that is exposed to the client (basically, the public API), its looks something like that:
public class Manager{
public Manager(int managerId, ShiftFactory sf, WorkerFactory wf);
// methods ...
}
As you probably understand, id is provided by the user on creation time (#Assisted?)
but the others are not, they are just factories.
The class Manager creates instances of the class Shift.
The class Shift creates instances of the class Worker.
Now, in order to create the class Shift we use its constructor:
public Shift(int managerId, int shiftId, WorkerFactory wf);
shiftId provided by the Manager and the rest are the same objects from Manager's constructor.
In order to create Worker we use 2 static factory methods (but it can be changed..):
public Worker createWorkerTypeA(int shiftId, int workerId)
public Worker createWorkerTypeB(int shiftId, int workerId)
workerId provided by the Shift class. and the rest is delegated from Shift constructor.
What is the correct, Guice-y way to do it?
Where should I put #Assisted? #Provides?
I really would like a code example of that, including the abstract module, because the code exmaples i've seen so far are not understandable to me just yet.
Thanks
At a high level, what you want is for your factories to hide the predictable dependencies so you only have to specify the ones that change. Someone who has an instance of the Factory should only have to pass in data, not factories or dependencies. I picture the interface like this.
interface ManagerFactory {
Manager createManager(int managerId);
}
interface ShiftFactory {
Shift createShift(int managerId, int shiftId);
}
interface WorkerFactory { // The two methods here might be difficult to automate.
Worker createWorkerA(int managerId, int shiftId, int workerId);
Worker createWorkerB(int managerId, int shiftId, int workerId);
}
class Manager {
#Inject ShiftFactory shiftFactory; // set by Guice, possibly in constructor
private final int managerId; // set in constructor
Shift createShift(int shiftId) {
shiftFactory.createWorkerA(this.managerId, shiftId); // or B?
}
}
class Shift {
#Inject WorkerFactory workerFactory; // set by Guice, possibly in constructor
private final int managerId; // set in constructor
private final int shiftId; // set in constructor
Worker createWorker(int workerId) {
shiftFactory.createShift(this.managerId, this.shiftId, workerId);
}
}
Note here that Manager doesn't care at all about workers—it doesn't create them, so unlike in your question, you don't have to accept a WorkerFactory just to pass it along to your Shift. That's part of the appeal of dependency injection; you don't have to concern a middle-manager (middle-Manager?) with its dependencies' dependencies.
Note also that none of the Factory interfaces or implementations are even slightly visible to your public API outside of constructors. Those are implementation details, and you can follow along the object hierarchy without ever calling one from outside.
Now, what would a ManagerFactory implementation look like? Maybe like this:
class ManualManagerFactory {
// ShiftFactory is stateless, so you don't have to inject a Provider,
// but if it were stateful like a Database or Cache this would matter more.
#Inject Provider<ShiftFactory> shiftFactoryProvider;
#Override public Manager createManager(int managerId) {
return new Manager(managerId, shiftFactoryProvider.get());
}
}
...but that's largely boilerplate, and possibly much more so when there are a lot of injected or non-injected parameters. Guice can do it for you, instead, as long as you still provide your ManagerFactory interface and you annotate a constructor:
class Manager {
private final ShiftFactory shiftFactory; // set in constructor
private final int managerId; // set in constructor
#Inject Manager(ShiftFactory shiftFactory, #Assisted int managerId) {
this.shiftFactory = shiftFactory;
this.managerId = managerId;
}
// ...
}
// and in your AbstractModule's configure method:
new FactoryModuleBuilder().build(ManagerFactory.class);
That's it. Guice creates its own reflection-based ManagerFactory implementation by reading the return type of the Manager method, matching that to the #Inject and #Assisted annotations and the interface method parameters, and figuring it out from there. You don't even need to call the implement method on FactoryModuleBuilder unless Manager were an interface; then you'd have to tell Guice which concrete type to create.
For kicks and grins, let's see the same thing with Google's code-generating AutoFactory package:
#AutoFactory(
className = "AutoManagerFactory", implementing = {ManagerFactory.class})
class Manager {
private final ShiftFactory shiftFactory; // set in constructor
private final int managerId; // set in constructor
#Inject Manager(#Provided ShiftFactory shiftFactory, int managerId) {
this.shiftFactory = shiftFactory;
this.managerId = managerId;
}
// ...
}
Almost identical, right? This will generate a Java class (with source code you can read!) that inspects the Manager class and its constructors, reads the #Provided annotations (n.b. #Provided is the opposite of FactoryModuleBuilder's #Assisted), and delegates to the constructor with its combination of parameters and injected fields. Two other advantages to Auto, which works with Guice as well as Dagger and other JSR-330 Dependency Injection frameworks:
This is normal Java code free of the reflection in Guice and its FactoryModuleBuilder; reflection performance is poor on Android, so this can be a nice performance gain there.
With code generation, you don't even need to create a ManagerFactory interface--without any parameters to #AutoFactory you would wind up with a final class ManagerFactory { ... } that has exactly the behavior Guice would wire up through FactoryModuleBuilder. Of course, you can customize the name and interfaces yourself, which might also help your developers as generated code sometimes doesn't appear well to tools and IDEs.
UPDATE to answer comments:
Regarding createWorker: Yes, sorry, copypaste error.
Regarding automation: It's because neither Assisted Inject nor AutoFactory has a great way to delegate to static methods, or to work with constructors that have identical assisted (user-provided) arguments. This is a case where you might have to write a Factory of your own.
Regarding Manager not needing a WorkerFactory: The only reason Manager would require WorkerFactory is if it's creating either a ShiftFactory or a Shift itself by calling the constructor. Note that my example does neither of those: You're letting the dependency injection framework (Guice) provide the dependencies, which means that the WorkerFactory is hiding in the ShiftFactory that Guice is already providing.
I need to implement a solution as part of Test framework & I am considering singleton pattern for reasons explained below. However, I am not able to achieve my intended solution & therefore would need some suggestions/inputs on possible implementations.
Problem Statement :
I have a environment (env of the product I am testing) configuration properties file which I want to load & make the value of the parameters accessible globally to the test framework.
I figured using the singleton pattern because these properties are one-time values (should report an exception if tried to initialize more than once), should be available globally & have an one-point access to the methods.
However, the list of properties/parameters is really long & therefore it's wise to break it into modules (classes). For the below explanation, I tried with composition.
For e.g.
public class Configuration {
private static Configuration configObj;
private static Database dbDetails;
private static Machine macDetails;
//...
//... many more modules
public static synchronized void createInstance(Properities envProps){
//Should create only one instance of Configuration
// and should also initialize Database & Machine objects.
}
public static Configuration getConfigObject(){
return configObj;
}
}
public class Database {
private static String dbConnectString;
public Database(String dbcs){
dbConnectString = dbcs;
}
public static String getDbConnectString(){
return dbConnectString;
}
}
public class Machine {
private static String hostname;
private static String loginUsername;
public Machine(String hostname,String loginUsername){
this.hostname = hostname; //It may include some trimming/cleaning
this.loginUsername = loginUsername;
}
public static String getHostName(){
return hostname;
}
}
PS: Just a sample typed-in code for the understanding of my problem statement.
Expectation : The expectation now is that when trying to get the hostname, I should have a single point of access via Configuration static object (assuming that I have initialized all member variables successfully) i.e.
String hostname = Configuration.getHostname();
OR
String hostname = Configuration.getConfigObject().getHostname();
Current Issue :
How to create one static object that will refer to all methods using either composition or inheritance (Conceptually, composition would be the right approach).
Multiple Inheritance would have solved the issue but Java doesn't support so ruled out. Cannot consider Interfaces either because overriding all methods is tedious & lengthy & the parameters/methods will keep changing over-time.
All suggestions are welcome even if it requires to scrap this design pattern & try something different.
You will not be able to "automatically" delegate static calls to modules. And even if the calls were not static, as you stated, Java does not support multiple inheritance.
Option 1:
Have your main Configuration class provide static methods that return instances to your modules. Whenever you want to read a configuration entry, first get the module instance, then query the entry itself:
Configuration.getDatabaseConfiguration().getServerName();
This method has the advantage that it is very clear which part of your configuration you are referring to. If you would just use Configuration.getServerName(), you cannot distingish whether you want to retrieve the database's server name, or the webserver's.
Option 2:
If you are able to use Java 8 and your configuration is large, but very simple (statically known at compile time or extractable from very few instances), you could consider using the new default interface methods (https://blog.idrsolutions.com/2015/01/java-8-default-methods-explained-5-minutes/).
You would then create an interface for each module, where all getters have default implementations. Your main configuration class would implement all the module interfaces without overriding any of the methods. This way all configuration entries can be queried from one object, but you still have to obtain this object by a static method. This is as close to multiple inheritance as you can get. I would definitely recommend option 1 though.
Initialize a singleton by configure file is suitable or not?
I notice that the constructor of singleton should not have any parameter, the reason is that if you need use parameters to configure your object, probably that should not be singleton. Seems this sentence very famous, but indeed there are serval cases are special:e.g.
We design a simple distributed system to deal with tons of users' query:
only one central server
n sub servers, each sub server connecting to central server
there is no connections between sub servers
Obviously, we may design the "central server" as singleton, the details like this:
enum ServerType;
abstract class Server;
class CentralServer inherit from Server;(CentralServer is singleton)
class SubServer inherit from Server;
class Query;
... ... ...
But the central server need some configuration, such as:
serverName
description
portNum-ipAddress map
the list of its sub servers
the size of BlockingQueue
... ... ...
How to initialize the central server by these properties?
My current solution:
using the configure file to finish this part job.
I define another class called Configuration.
So the current constructor of central server like this:
class CentralServer extends Server implements Runnable, ....... {
....
....
private static CentralServer _instance;
private CentralServer () {
super();
....
serverName = Configuration.getCentralServerName();
description = Configuration.getCentralServerDescription();
Configuration.initCentralServerPortNumIpMap(portNumIpMap);
Configuration.initCentralServerSubServersList(subServersList);
sizeBlockingQueue = Configuration.initCentralServerBlockingQueueSize();
....
}
public CentralServer getInstance() {
if (_instance == null) {
_instance = new CentralServer();
}
return _instance;
}
....
....
}
The Configuration class, will read and analyze configuration-file, to get out of configuration info.
My Question:
Initialize singleton like this suitable or not, if not, please
give out more suitable approach
I also need configure all sub servers, so seems the Configuration
class is too heavy, should I split the Big Configuration class into
two sub class? class CentralConfiguration, and class
SubConfiguration?
Unfortunately, your implementation for a Singelton is WRONG!! Simply because it is not thread safe.
public CentralServer getInstance() {
if (_instance == null) { // race condition possible here
_instance = new CentralServer();
}
return _instance;
}
Two threads might enter this critical section and evaluate _instance==null to true, and two different instances will be created.
You can simply instantiate your instance statically.
private final static CentralServer INSTANCE = new CentralServer();
public static CentralServer getInstance() {
return INSTANCE;
}
However, the best way to implement singeltons is to use enums
public enum CentralServer { // the best way to implement singletons, due to the author of Effective Java
INSTANCE;
private CentralServer() {
}
}
This gives you serialisation for free.
However, I dont think that you need a singelton at all, singeltons are usually Anti patterns.
Check this out.
In your code, CentralServer has a high dependency on Configuration which I don't think is a good thing, you should see Configuration as a dependency
class CentralServer{
private final Configuration serverConf;
private CentralServer(Configuration serverConf){ // inject configuration
this.serverConf = serverConf;
}
public static CentralServer createCentralServer(Configuration serverConf){ // static factory perhaps
return new CentralServer(serverConf);
}
}
This will give you more flexibility to change or mock configuration. I think Factory pattern would be more appropriate here.
It is perfectly acceptable to make use of external resources during the initialization of your singleton. A common user of the Singleton pattern is loggers and they are almost always configured from external data files.
It does make initialization more complicated but it is not impossible to make a fully tread-safe singleton that accesses external resources such as configuration files. They can even make use of other singletons such as connection pools if their configuration requires database access.
The other answers to this question correctly deal with the actual problems with your singleton initialization.
Initialize singleton like this suitable or not, if not, please give
out more suitable approach:
It is not a suitable approach, because the implementation is not threadsafe yet and it can be broken f.e. via reflection. You should consider reading Effective Java by Joshua Bloch on this topic.
Better would be to create an enum singleton, because this approach is more flexible for later changes, has threadsafe instanciating and is unbreakable.
EDIT: example .
I also need configure all sub servers, so seems the Configuration
class is too heavy, should I split the Big Configuration class into
two sub class? class CentralConfiguration, and class SubConfiguration?
For configuration purposes, there is usually a config.xml file or a config.properties file somewhere to read important preconfigurations. After creating an instance, you should extract the information from such a file and write out necessary changes when shutting down. But as always, many ways lead to rome.
I am designing a complex Configuration class as part of an API design. The Configuration class roughly looks like this.. (I ignored generics/access modifiers etc)
class Configuration {
One obj1;
Two obj2;
}
class One {
List<Double> values;
}
class Two {
double value;
Map<String, Double> data;
}
This is what I want to accomplish:
I want users to be able to create this Configuration class the first time easily and submit to server.
Then they can change any part of this class and send the updated configuration to the server.
What design patterns to use and avoid?
Is it better to make this class Immutable and use builder pattern?
Or just provide all kinds of modification methods On Configuration class so they can modify the same Configuration class (at all levels) in-place without having to create a new Configuration class for every update. I think Builder pattern is good for Immutable classes only.
Questions:
Is there any way to exploit Builder pattern for this type of scenarios?
Or is it better to provide mutator methods on Configuration class like I mentioned above?
Or are there any other better patterns available?
I think you should use prototype pattern:
in your code you can add map that hold all types of configurations
the map will have a key called "currentConfiguration" and the value will be the configuration that should be loaded. the map can also contains other configurations that can be stored in the map and can replace the current configuration if needed.
once you fetch configuration from the map you simply clone the configuration object and the user can do what ever he pleased with that. after the changes he can save the configuration in the map with speicifc name. so the user can get configuration object that is quite close that what he needs and configure it accordingly.
the code should look like this:`public class CloudRepository {
private Map<String, Configuration> rep;
public CloudRepository(Configuration current){
rep = new HashMap<String, Configuration>();
rep.put("current", current);
}
public Configuration getConfiguration(String string){
return (Configuration) rep.get(string).clone();
}
public void addConfiguration(String name, Configuration conf){
rep.put(name, conf);
}
public void replaceCurrentConfiguration(Configuration conf){
rep.put("current", conf);
}
}
you can also write more code to handle history for your configurations.
you can also consider making this class singleton