After reading an interesting article, I have a few questions around this. Please refer to Common Pitfall #8: Pretending Java is more like C (i.e. not understanding OOP) on [zero-turn-around]
I agree to the authors solution for the pitfall. I face a similar issue with my code (abuse of instanceof). But I cannot implement the code as the author has suggested. My scenario is as below
I have JMS as a messaging bus.
Messages float around the system. Listener typically listen to the messages.
All the messages have a single parent IMessage.
I use instanceof to distinguish between messages.
The listeners typically do domain specific business logic.
If I agree with the authors solution, I will have to implement domain specific business logic in the Message classes, which I think will bloat my light-weight message objects. Not just that, I will now have many references (composition) in my message objects which I think is unfair as the message objects will now have business (domain) behavior in it.
What is the reasonable solution to this problem? Example code below
public void onMessage(IMessage mssg)
{
if(mssg instanceof MoPn){
...
} else if(mssg instance of MoZn){
...
} else if(mssg instance of MoLn){
...
}
}
One reasonable solution is creating listeners that know to work with specific type of message.
Here is the interface.
interface MessageListener<M extends IMessage> {
void onMessage(M message);
}
Here is a skeleton of one of the classes:
class MoZnListener implements MessageListener<MoZn> {
public void onMessage(MoZn message) {
}
}
Now you can create mapping between messages and listeners. You can use properties file, hard coded map, annotations. It is up to you. Once you have it you can implement one JMS message listener that looks like
class MessageEntryPoint implements MessageListener {
public void onMessage(Message message) {
getMessageHandler(message).onMessage(message.getObject());
}
}
Now your system is extandable. No instanceof. To introduce new message type you just have to create appropriate class that implements IMessage and listener that supports it.
BTW more comments.
Using I as to mark interface is not java-style.
I am not familiar with your domain and probably name like MoPn is self-explainable for you, but IMHO it is not. Try to use more self explainable identifiers.
This might upset some purists, but I believe that using a language with OO features doesn't necessarily mean you have to apply OO to everything.
Messages are simply schema. They carry data. Forcing object-orientation upon structures that merely carry data from one place to another can be an anti-pattern as well.
Separating the logic from the data model is sometimes seen as being against OOP but is sometimes necessary for decoupling. The code sending the message doesn't need to know anything about how to respond to the message.
Some of the other problems with instanceof are that it's hard to find what needs updating when adding a new type, and there's no way to make sure all cases are covered. These problems can be solved by adding some new interfaces:
interface Message {
void callHandler(MessageHandler handler);
}
interface MessageHandler {
default void onMoPn(MoPn message) {
}
default void onMoZn(MoZn message) {
}
}
class MoPn implements Message {
public void callHandler(MessageHandler handler) {
handler.onMoPn(this);
}
}
class Mozn implements Message {
public void callHandler(MessageHandler handler) {
handler.onMoZn(this);
}
}
and add a handler:
class MessageHandlerImpl implements MessageHandler {
public void onMoPn(MoPn message) {
System.out.println("MoPn message: " + message);
}
}
When you get a message, you can call the handler like:
MessageHandler handler = new MessageHandlerImpl()
Message message = new MoPn();
message.callHandler(handler);
Related
I try to understand the SOLID principles and therefore implemented some java snippets. My concern is the OCP at the moment. Having following samples,
public abstract class Bakery
{
public abstract Bakegood bake();
}
/******************************************/
public class BreadBakery extends Bakery {
#Override
public Bakegood bake() {
return new Bread();
}
}
/******************************************/
public class CakeBakery extends Bakery {
#Override
public Bakegood bake() {
return new Cake();
}
}
/******************************************/
how can I create the right bakery. Assume a customer comes to the bakery and says: "I'd have two cakes, please!", how can I then instantiate the CakeBakery. Of course I can create an abstract factory like:
public static Bakery createBakery(final String orderedBakegood)
{
switch(bakegood)
{
case "Cake": return new CakeBakery();
case "Bread": return new BreadBakery();
default: throw new InvalidBakeryException();
}
}
But I don't want to use switch or if statements. Is there any other possibility or am I completely wrong with the understanding?
Open/closed principle says:
Software entities (classes, modules, functions, etc.) should be open
for extension, but closed for modification.
So whenever you introduce a new Bakery, you should not modify existing code. You can use something like a registry for your Bakery classes. If you need to add a new Bakery, just extend Bakery class and register it (e.g. at startup). Hence no "if" or "switch" modification is required. Moreover, adding a new Bakery does not require changing the internals of the registry or the code that is calling the registry.
Furthermore, this technique is not dependent on the way you register your components. You can do it programatically, with a configuration file (xml, ...), via classpath scanning, ...
You can see this approach in the Spring framework a lot. Basically the Spring framework is a great source of many design principles.
Here you can see a very simple registry implementation.
public class BakeryRegistry {
private Map<String, Bakery> mapping = new HashMap<>();
public BakeryRegistry() {
loadDefaultMappingFromConfigFile();
}
public Bakery getBakery(String name) {
return mapping.get(name);
}
public void registerBakery(String name, Bakery bakery) {
mapping.put(name, bakery);
}
private void loadDefaultMappingFromConfigFile() {
...
}
}
Maybe article Killing Switch Statements With A Registry can help. It is based on JavaScript but the principle is the same.
The contrived abstraction is causing the problem here. Customers will not ask the bakery for abstract "baked goods", because all baked goods are not substitutable. Bread is not a substitute for cake, and vice versa. Wrapping these two different products into one inheritance hierarchy is a violation of the Liskov Substitution Principle.
The SOLID principles are interrelated, so applying OCP will be difficult or impossible without applying LSP first. See the introduction to LSP where Robert Martin describes inheritance as being critical to OCP, and goes on to describe LSP as being critical to inheritance.
This could get a little bit complicated and I'm not that experienced with Observables and the RX pattern so bear with me:
Suppose you've got some arbitrary SDK method which returns an Observable. You consume the method from a class which is - among other things - responsible for retrieving data and, while doing so, does some caching, so let's call it DataProvider. Then you've got another class which wants to access the data provided by DataProvider. Let's call it Consumer for now. So there we've got our setup.
Side note for all the pattern friends out there: I'm aware that this is not MVP, it's just an example for an analogous, but much more complex problem I'm facing in my application.
That being said, in Kotlin-like pseudo code the described situation would look like this:
class Consumer(val provider: DataProvider) {
fun logic() {
provider.getData().subscribe(...)
}
}
class DataProvider(val sdk: SDK) {
fun getData(): Consumer {
val observable = sdk.getData()
observable.subscribe(/*cache data as it passes through*/)
return observable
}
}
class SDK {
fun getData(): Observable {
return fetchDataFromNetwork()
}
}
The problem is, that upon calling sdk.subscribe() in the DataProvider I'm already triggering the Observable's subscribe() method which I don't want. I want the DataProvider to just silently listen - in this example the triggering should be done by the Consumer.
So what's the best RX compatible solution for this problem? The one outlined in the pseudo code above definitely isn't for various reasons one of which is the premature triggering of the network request before the Consumer has subscribed to the Observable. I've experimented with publish().autoComplete(2) before calling subscribe() in the DataProvider, but that doesn't seem to be the canonical way to do this kind of things. It just feels hacky.
Edit: Through SO's excellent "related" feature I've just stumbled across another question pointing in a different direction, but having a solution which could also be applicable here namely flatMap(). I knew that one before, but never actually had to use it. Seems like a viable way to me - what's your opinion regarding that?
If the caching step is not supposed to modify events in the chain, the doOnNext() operator can be used:
class DataProvider(val sdk: SDK) {
fun getData(): Observable<*> = sdk.getData().doOnNext(/*cache data as it passes through*/)
}
Yes, flatMap could be a solution. Moreover you could split your stream into chain of small Observables:
public class DataProvider {
private Api api;
private Parser parser;
private Cache cache;
public Observable<List<User>> getUsers() {
return api.getUsersFromNetwork()
.flatMap(parser::parseUsers)
.map(cache::cacheUsers);
}
}
public class Api {
public Observable<Response> getUsersFromNetwork() {
//makes https request or whatever
}
}
public class Parser {
public Observable<List<User>> parseUsers(Response response) {
//parse users
}
}
public class Cache {
public List<User> cacheUsers(List<User> users) {
//cache users
}
}
It's easy to test, maintain and replace implementations(with usage of interfaces). Also you could easily insert additional step into your stream(for instance log/convert/change data which you receive from server).
The other quite convenient operator is map. Basically instead of Observable<Data> it returns just Data. It could make your code even simpler.
I'm new to akka and I'm trying akka on java. I'd like to understand unit testing of business logic within actors. I read documentation and the only example of isolated business logic within actor is:
static class MyActor extends UntypedActor {
public void onReceive(Object o) throws Exception {
if (o.equals("say42")) {
getSender().tell(42, getSelf());
} else if (o instanceof Exception) {
throw (Exception) o;
}
}
public boolean testMe() { return true; }
}
#Test
public void demonstrateTestActorRef() {
final Props props = Props.create(MyActor.class);
final TestActorRef<MyActor> ref = TestActorRef.create(system, props, "testA");
final MyActor actor = ref.underlyingActor();
assertTrue(actor.testMe());
}
While this is simple, it implies that the method I want to test is public. However, considering actors should communicate only via messages, my understanding that there is no reason to have public methods, so I'd made my method private. Like in example below:
public class LogRowParser extends AbstractActor {
private final Logger logger = LoggerFactory.getLogger(LogRowParser.class);
public LogRowParser() {
receive(ReceiveBuilder.
match(LogRow.class, lr -> {
ParsedLog log = parse(lr.rowText);
final ActorRef logWriter = getContext().actorOf(Props.create(LogWriter.class));
logWriter.tell(log, self());
}).
matchAny(o -> logger.info("Unknown message")).build()
);
}
private ParsedLog parse(String rowText) {
// Log parsing logic
}
}
So to test method parse I either:
need it to make package-private
Or test actor's public interface, i.e. that next actor LogWriter received correct parsed message from my actor LogRowParser
My questions:
Are there any downsides on option #1? Assuming that actors communicating only via messages, encapsulation and clean open interfaces are less important?
In case if I try to use option #2, is there a way to catch messages sent from actor in test downstream (testing LogRowParser and catching in LogWriter)? I reviewed various examples on JavaTestKit but all of them are catching messages that are responses back to sender and none that would show how to intercept the message send to new actor.
Is there another option that I'm missing?
Thanks!
UPD:
Forgot to mention that I also considered options like:
Moving logic out of actors completely into helper classes. Is it common practice with akka?
Powermock... but i'm trying to avoid it if redesign is possible
There's really no good reason to make that method private. One generally makes a method on a class private to prevent someone who has a direct reference to an instance of that class from calling that method. With an actor instance, no one will have a direct reference to an instance of that actor class. All you can get to communicate with an instance of that actor class is an ActorRef which is a light weight proxy that only allows you to communicate by sending messages to be handled by onReceive via the mailbox. An ActorRef does not expose any internal state or methods of that actor class. That's sort of one of the big selling points of an actor system. An actor instance completely encapsulates its internal state and methods, protecting them from the outside world and only allows those internal things to change in response to receiving messages. That's why it does not seem necessary to mark that method as private.
Edit
Unit testing of an actor, IMO, should always go through the receive functionality. If you have some internal methods that are then called by the handling in receive, you should not focus on testing these methods in isolation but instead make sure that the paths that lead to their invocation are properly exercised via the messages that you pass during test scenarios.
In your particular example, parse is producing a ParsedLog message that is then sent on to a logWriter child actor. For me, knowing that parse works as expected means asserting that the logWriter received the correct message. In order to do this, I would allow the creation of the child logWriter to be overridden and then do just that in the test code and replace the actor creation with a TestProbe. Then, you can use expectMsg on that probe to make sure that it received the expected ParsedLog message thus also testing the functionality in parse.
As far as your other comment around moving the real business for the actor out into a separate and more testable class and then calling that from in the actor, some people do this, so it's not unheard of. I personally don't, but that's just me. If that approach works for you, I don't see any major issues with it.
I had the same problem 3 years ago, when dealing with actors : the best approach i found was to have minimum responsability to the actor messenging responsability.
The actor will receive the message and choose the Object's method to call or the message to send or the exception to throw and that's it.
This way it will be very simple to mock up either the services called by the actor and the input to those services.
I'm searching for a simple Java implementation of Udi Dahan's
Domain Events pattern and infrastructure as detailed in this article.
It's pretty simple and I've implemented my own interpretation, however I'm a Java novice and don't want to be bitten by any mistakes due to inexperience with the language.
The only Java implementation I've found is in the Jdon Framework, but it's a little too heavyweight for my current in my project.
Thanks!
I have been looking for a solution to the same problem in Java EE for a while now. I looked at Axon and jdon (the page doesn't really bode well either :)). Both involve Event Sourcing which I could not "sell" to my employers/customers. I wanted to have Domain Events though since I very much got used to them in .NET/C# projects. So I came up with the following...
I used a similar static DomainEvents object to give me access to a publishing mechanism without the actual implementation details leaking all over my domain model entities. So the calls something like this:
DomainEvents.fire(new MySampleEvent(...some params...));
A pattern and mechanism that is available in CDI spec are the Events with #Observes that allow you to respond to certain events in normal beans with all the service available. That is similar to what I was used to when using DI frameworks like Castle Windsor where I could register generic handlers by interface. So I've got the observers (handlers, listeners, whatever you want to call them) covered. Example:
#Stateless
public class MySampleEventObserver {
public void listen(#Observes MySampleEvent event) {
...
doSomethingWithEvent();
}
}
Now for the publishing (firing in CDI) part. Since there is no way to access CDI in entities (with good reason!) I resolved to using JNDI and BeanManager. I used JNDI to get the BeanManager and use it's fireEvent method. To put bean manager resolving (as seen here) in code:
public class BeanHelper {
public static BeanManager getBeanManager() {
try {
InitialContext initialContext = new InitialContext();
return (BeanManager) initialContext.lookup("java:comp/BeanManager");
} catch (NamingException e) {
e.printStackTrace();
return null;
}
}
}
The final step is the DomainEvents object itself:
public class DomainEvents {
private static boolean mNopMode = false;
public static void setNopMode() {
mNopMode = true;
}
public static void reset() {
mNopMode = false;
}
public static <TDomainEvent> void fire(TDomainEvent event) {
if (mNopMode) {
return;
}
BeanManager manager = BeanHelper.getBeanManager();
manager.fireEvent(event);
}
}
The setNopMode and reset parts are there for testing purposes when there is no context. Manual mocking basically. Set it into NOP operation mode before unit tests and reset after them.
Works fine as a POC. Don't know if there are any serious limitations to it's use though. I leave async bus interactions and similar to the listeners implementation.
Would love any comments.
I'm currently looking at using Googles Guava EventBus to do something similar to the "Salvation" article you reference.
Using it similar to the "How to raise domain events" would look something like this, almost exactly the same as the article:
public class Customer
{
public void DoSomething()
{
MyEventBus.post(new CustomerBecamePreferred() { Customer = this });
}
}
I don't know whether or not you'd consider this as an "implementation of Udi Dahan's Domain Events pattern".
It doesn't require implementing any interfaces; event handlers are marked with annotations and the class is registered with the EventBus with MyEventBus.register(aListenerObject)
In the real world what do people use this for (to solve what types of problems)? Can I see some example code of these working together? All I can find is code about cats and dogs speaking or people drinking milk or coffee...
Do people really implement polymorphism with interfaces? What for?
Sure,
Below is concrete example of the "Observer" pattern, using classes and interfaces to accomplish polymorphic behavior in a logger system:
interface ILogger{
public void handleEvent (String event);
}
class FileLogger implements ILogger{
public void handleEvent (String event){
//write to file
}
}
class ConsoleLogger implements ILogger{
public void handleEvent (String event){
System.out.println( event );
}
}
class Log {
public void registerLogger (ILogger logger){
listeners.add(logger);
}
public void log (String event){
foreach (ILogger logger in listeners){
logger.handleEvent(event); //pass the log string to both ConsoleLogger and FileLogger!
}
}
private ArrayList<ILogger> listeners;
}
Then, you could use it as follows:
public static void main(String [] args){
Log myLog();
FileLogger myFile();
ConsoleLogger myConsole();
myLog.registerLogger( myFile );
myLog.registerLogger( myConsole );
myLog.log("Hello World!!");
myLog.log("Second log event!");
}
Hope this helps your understanding of interfaces and polymorphism.
Map<String,Person> peopleByName = new HashMap<String,Person>();
If, down the road, I decide the memory overhead of HashMap is too much, I can re-do this as a TreeMap, and live with the slightly more expensive lookup times
Map<String,Person> peopleByName = new TreeMap<String,Person>();
Because peopleByName is a Map, not a TreeMap or a HashMap, all my calls are guaranteed to work on either map regardless of implementation.
This is best illustrated with the following example
public class CatsAndDogsDrinkingMilkAndCoffee {
// what, no? :-(
}
interface Request {
Response execute();
}
interface Response {
String serialize();
}
class RequestProcessor {
void processRequest(Request r) {
logger.log("Request: " + r);
Response s = r.execute();
logger.log("Response: " + s);
connectionManager.write(r.serialize());
}
}
Say in this example, RequestProcesor doesn't need to know about implementations of Request and Response
Have a look at the code for Map/AbstractMap/HashMap as an example. You will find thousands of other examples in the JDK source which comes with the JDK (in src.zip)
imagine "somebody" designed a huge program, with lotsa code. suppose that "that somebody" used interfaces in the design of some controller logic. now you are hired to work with this code which youve never seen before. you are asked to design a new controller class. all you need to do now is to implement the interface and make all its methods work.
if that somebody had not used interfaces, then not only would you have to redesign the controller, but you would probably need to redesign potentially the whole project because there is very strong coupling between the controller class and the rest of the classes. this will take you months just to understand the code, not to mention the new set of bugs you would probably introduce..
Almost any Java application with GUI uses it (but of course not only GUI...). For example, look at the source of android VideoView (this is the first comes to my mind...)
Another suggestion I'd have for "the real world" is in using spring batch. If you have a commonly used report format that follows a pattern like "pull data, create report, send to recipients" you can create an interface for your reports that enforces this standard. In this sense it works like a "template" that all batch reports would follow.
A boring example, but it's something I faced in my first year...
Have you wondered how LINQ in .net works ? It's all about Interfaces and polymorphism.
You need to work on projects then you will come to know about all this.