Hi Adam

Really appreciate your ideas and code samples! Thank you.

These are interesting angles to take and I'm definitely trying to see how 
this can fit my specific case. I'll be most likely bound to Java 7 so the 
composition approach is more possible (though using interfaces with default 
methods is interesting). It's a bit of a struggle though as while 
composition does come on top (of inheritance) in many cases, in this 
specific case inheritance seems like a classic fit. I'm using it mainly for 
code reuse but there are multiple levels of derived classes where 90 
percent of the code is in the parent class and the rest is overridden by 
the children.

An equivalent to your example would be:

class DbAccess
class SqlServerAccess extends DbAccess
class SqlServer2012Access extends SqlServerAccess

where 
DbAccess implements all that is needed to access any database (say, over 
JDBC) - run ad-hoc queries, use JDBC metadata interface, etc. Almost all of 
the code is here.
SqlServerAccess inherits all of DbAccess functionality but perhaps 
overrides a single routine that needs to use a sqlserver specific syntax 
(e.g, use TOP instead of LIMIT for getting sample data).
SqlServer2012Access inherits all of the above, but also adds another call 
for using a feature that only exists in this version.

so it's a classic 'is-a' case (in IMO at least), and assuming that some 
cases have 4 or 5 levels of inheritance - composition is no longer trivial.
It could be though that redesigning/rearranging the classes in a different 
way logically will change that. Like you, I'm not a big fan of inheritance 
with many hierarchy levels.

Thx
Alon




On Wednesday, January 14, 2015 at 11:26:21 PM UTC+2, Adam wrote:
>
> Hi,
> I guess the correct answer is "it depends" J, but I can describe what we 
> use right now, as we're also using Akka (and seeing as it's been very 
> rewarding to do so we do it more and more), but are confined to Java.So 
> first of all, I would recommend against inheritance.
> That route quickly becomes very tangled and results in a huge hierarchy of 
> classes with way too many methods.
>
> We typically use composition.
> I assume the real issue is cases where you want to reuse code that relies 
> on running inside an Actor.
> Unfortunately UntypedActor is not an interface, so it's indeed difficult 
> to mix in behavior.However, since a class method is really not much more 
> than a static method that implicitly accepts the "this" pointer (some 
> languages like python and Ada even work that way and specify all arguments 
> explicitly), your actors can contain other classes that either have methods 
> which accept an UntypedActor as a parameter, or accept it in their 
> constructor.
>
> We use that often for synchronous paths.
>
> An example:
>
> public class DbAccess {
>     private final UntypedActor owner;
>     public DbAccess(UntypedActor owner) {
>         this.owner = owner;
>     }
>
>     //methods for DB access
> }
>
> public class Auth {
>     private final UntypedActor owner;
>     public Auth(UntypedActor owner) {
>         this.owner = owner;
>     }
>
>     //methods for Authentication
> }
>
>
> public class MyActor extends UntypedActor{
>     private final DbAccess db = new DbAccess(this);
>     private final Auth auth = new Auth(this);
>
>     public void onReceive(Object msg){
>         //use the shared logic of db and auth wherever needed
>     }
> }
>
> (One nasty issue here is that the constructor of MyActor is sending "this" 
> before it's fully constructed, so it's probably better to move the 
> initialization of dependencies to preStart, but I kept the code shorter 
> here)
>
> There are exceptions to this rule.
>
> For example, if you wanted to override any of the UntypedActor methods 
> (e.g. we do that for one-off actors so they will stop in case of an 
> unhandled message), you'd have to use inheritance, so in some cases we do 
> use that, but we try to keep it down to as few levels of it as possible.
>
>
> Another alternative if you're using Java 8 AND your methods don't rely on 
> state, is to use interfaces with default methods,as a poor man's 
> replacement for Scala traits.
>
> In that case, if you wanted to rely on running inside an actor you could 
> require actors to implement a single interface that exposes the this 
> pointer and then add as many interfaces with default methods as you wish.
> For example:
>
> public interface ActorExposer {
>     public UntypedActor getActor();
> }
>
> public interface DbUser extends ActorExposer{
>     //methods for DB access
>     public default ...
> }
>
> public class Auth extends ActorExposer{
>     //methods for Authentication
>     public default ...
> }
>
>
> public class MyActor implements DbUser, Auth{
>     public void onReceive(Object msg){
>         //use the shared logic of db and auth whereever needed
>     }
>
>     @Override
>     public UntypedActor getActor() {
>         return this;
>     }
> }
>
>
>
>
> Finally, for asynchronous paths we simply use more actors, but I assume 
> that was already obvious to you and you were asking about the previous part 
> of my answer.
> I hope this helps.
>
>
> Adam.
>
>   
>
> On Tuesday, January 13, 2015 at 10:46:45 PM UTC+2, Alon Goldshuv wrote:
>>
>> (newbie question)
>>
>> Hi,
>>
>> I'd like to write a set of Actors that behave very similarly, however 
>> have a few differences as well. 
>> In plain java world I'd write an Abstract parent class that includes all 
>> of the shared behavior, have each child class extend it, and override only 
>> the class methods that differ from the abstract class implementation.
>>
>> I'm not sure how to do it in Akka - Java. I've seen a very similar 
>> question and a really nice answer here 
>> <http://stackoverflow.com/questions/17383827/how-do-i-best-share-behavior-among-akka-actors>,
>>  
>> but it's using scala, and scala traits.
>>
>> My initial thought was something like:
>>
>> public abstract class MyParentActor(...) extends UntypedActor {
>>     ...
>>     <few class methods and their implementations>
>> }
>>
>>
>> public class MyChildActor1(...) extends MyParentActor {
>>     super(...);
>>     <some class methods>
>>
>>     public void onReceive(msg) {
>>       <use class or MyParentActor methods>
>>     }
>> }
>>
>> Is that a good idea? will that work?
>>
>> BTW, since the project has yet to start, I'm not tied to a specific Akka 
>> version, so I assume 2.3.8.
>>
>> Thanks in advance!
>> Alon.
>>
>>

-- 
>>>>>>>>>>      Read the docs: http://akka.io/docs/
>>>>>>>>>>      Check the FAQ: 
>>>>>>>>>> http://doc.akka.io/docs/akka/current/additional/faq.html
>>>>>>>>>>      Search the archives: https://groups.google.com/group/akka-user
--- 
You received this message because you are subscribed to the Google Groups "Akka 
User List" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to akka-user+unsubscr...@googlegroups.com.
To post to this group, send email to akka-user@googlegroups.com.
Visit this group at http://groups.google.com/group/akka-user.
For more options, visit https://groups.google.com/d/optout.

Reply via email to