- About Scala
- Documentation
- Code Examples
- Software
- Scala Developers
How to "Program to an interface, not an implementation" in Scala
Sun, 2012-02-05, 04:00
Hi Everyone,
I'm trying to figure out what's the best way to achieve "Program to an interface, not an implementation" in Scala.
For example I have a UserDao trait and two implementations of it, SqlUserDao and NoSqlUserDao. In my client code, I would like to use UserDao trait. In addition, I don't want my client code to know anything about SqlUserDao or NoSqlUserDao. I know I can have a factory/manager object that returns the appropriate implementation, but I wanted to see if there's a better way.
Thanks,
Drew
Sun, 2012-02-05, 07:21
#2
Re: How to "Program to an interface, not an implementation" in
Thanks Jean, I'm already aware of the cake pattern, I wanted to see if there is a better/less verbose way. Not really looking for DI if that makes sense.
Sun, 2012-02-05, 07:31
#3
Re: How to "Program to an interface, not an implementation" in
+1 for Cake Pattern. Using it all the time for testability. Take an Object, extract functionality into trait, inherit from that trait, and, in tests, or in a variety of objects, inject all your dependency.
I believe it is way cooler than this javaish "interface/class" dichotomy.
Thanks,
-Vlad
On Sat, Feb 4, 2012 at 7:30 PM, Jean-Francois Im <jfim@jean-francois.im> wrote:
I believe it is way cooler than this javaish "interface/class" dichotomy.
Thanks,
-Vlad
On Sat, Feb 4, 2012 at 7:30 PM, Jean-Francois Im <jfim@jean-francois.im> wrote:
Jonas Boner has a great post about the Cake pattern and alternatives in Scala.
http://jonasboner.com/2008/10/06/real-world-scala-dependency-injection-di/
On Sat, Feb 4, 2012 at 22:00, Drew Kutcharian <drew@venarc.com> wrote:
> Hi Everyone,
>
> I'm trying to figure out what's the best way to achieve "Program to an interface, not an implementation" in Scala.
>
> For example I have a UserDao trait and two implementations of it, SqlUserDao and NoSqlUserDao. In my client code, I would like to use UserDao trait. In addition, I don't want my client code to know anything about SqlUserDao or NoSqlUserDao. I know I can have a factory/manager object that returns the appropriate implementation, but I wanted to see if there's a better way.
>
> Thanks,
>
> Drew
Sun, 2012-02-05, 09:11
#4
Re: How to "Program to an interface, not an implementation" in
If you don't want to change the actual implementation based on
different environments (ie. using mocks for testing or whatnot), it's
possible to just mix the implementation in an object, baking it at
compile time into the classfile.
case class User(name:String)
trait Dao[T] {
def save(t:T);
}
trait UserDao extends Dao[User]
class NoSqlUserDao extends UserDao {
def save(user:User) {
println("Saved user " + user.name + " in NoSQL DB");
}
}
class SqlUserDao extends UserDao {
def save(user:User) {
println("Saved user " + user.name + " in SQL DB");
}
}
object UserDao extends SqlUserDao
object Demo extends App {
val user = User("Bob")
UserDao.save(user)
}
On Sun, Feb 5, 2012 at 01:15, Vlad Patryshev wrote:
> +1 for Cake Pattern. Using it all the time for testability. Take an Object,
> extract functionality into trait, inherit from that trait, and, in tests, or
> in a variety of objects, inject all your dependency.
>
> I believe it is way cooler than this javaish "interface/class" dichotomy.
>
> Thanks,
> -Vlad
>
>
>
> On Sat, Feb 4, 2012 at 7:30 PM, Jean-Francois Im
> wrote:
>>
>> Jonas Boner has a great post about the Cake pattern and alternatives in
>> Scala.
>>
>> http://jonasboner.com/2008/10/06/real-world-scala-dependency-injection-di/
>>
>> On Sat, Feb 4, 2012 at 22:00, Drew Kutcharian wrote:
>> > Hi Everyone,
>> >
>> > I'm trying to figure out what's the best way to achieve "Program to an
>> > interface, not an implementation" in Scala.
>> >
>> > For example I have a UserDao trait and two implementations of it,
>> > SqlUserDao and NoSqlUserDao. In my client code, I would like to use UserDao
>> > trait. In addition, I don't want my client code to know anything about
>> > SqlUserDao or NoSqlUserDao. I know I can have a factory/manager object that
>> > returns the appropriate implementation, but I wanted to see if there's a
>> > better way.
>> >
>> > Thanks,
>> >
>> > Drew
>
>
Sun, 2012-02-05, 10:11
#5
Re: How to "Program to an interface, not an implementation" in
Thanks Jean-Francois, this is more like what I was looking for. My only concern is that since UserDao object is extending SqlUserDao, wouldn't its implementation details leak into the client app? What I mean is wouldn't I be able to call methods that exist in SqlUserDao but not in UserDao trait? How can I enforce that UserDao object is only allowing it's clients to call only the methods defined in UserDao traitwithout marking those "other" methods private?
On Feb 5, 2012, at 12:09 AM, Jean-Francois Im wrote:
> If you don't want to change the actual implementation based on
> different environments (ie. using mocks for testing or whatnot), it's
> possible to just mix the implementation in an object, baking it at
> compile time into the classfile.
>
> case class User(name:String)
>
> trait Dao[T] {
> def save(t:T);
> }
>
> trait UserDao extends Dao[User]
>
> class NoSqlUserDao extends UserDao {
> def save(user:User) {
> println("Saved user " + user.name + " in NoSQL DB");
> }
> }
>
> class SqlUserDao extends UserDao {
> def save(user:User) {
> println("Saved user " + user.name + " in SQL DB");
> }
> }
>
> object UserDao extends SqlUserDao
>
> object Demo extends App {
> val user = User("Bob")
> UserDao.save(user)
> }
>
> On Sun, Feb 5, 2012 at 01:15, Vlad Patryshev wrote:
>> +1 for Cake Pattern. Using it all the time for testability. Take an Object,
>> extract functionality into trait, inherit from that trait, and, in tests, or
>> in a variety of objects, inject all your dependency.
>>
>> I believe it is way cooler than this javaish "interface/class" dichotomy.
>>
>> Thanks,
>> -Vlad
>>
>>
>>
>> On Sat, Feb 4, 2012 at 7:30 PM, Jean-Francois Im
>> wrote:
>>>
>>> Jonas Boner has a great post about the Cake pattern and alternatives in
>>> Scala.
>>>
>>> http://jonasboner.com/2008/10/06/real-world-scala-dependency-injection-di/
>>>
>>> On Sat, Feb 4, 2012 at 22:00, Drew Kutcharian wrote:
>>>> Hi Everyone,
>>>>
>>>> I'm trying to figure out what's the best way to achieve "Program to an
>>>> interface, not an implementation" in Scala.
>>>>
>>>> For example I have a UserDao trait and two implementations of it,
>>>> SqlUserDao and NoSqlUserDao. In my client code, I would like to use UserDao
>>>> trait. In addition, I don't want my client code to know anything about
>>>> SqlUserDao or NoSqlUserDao. I know I can have a factory/manager object that
>>>> returns the appropriate implementation, but I wanted to see if there's a
>>>> better way.
>>>>
>>>> Thanks,
>>>>
>>>> Drew
>>
>>
Sun, 2012-02-05, 10:21
#6
Re: How to "Program to an interface, not an implementation" in S
What's wrong with having factory methods returning an anonymous classes?
It's the best way to hide the implementation IMHO.
/Jesper Nordenberg
Drew Kutcharian skrev 2012-02-05 04:00:
> Hi Everyone,
>
> I'm trying to figure out what's the best way to achieve "Program to an interface, not an implementation" in Scala.
>
> For example I have a UserDao trait and two implementations of it, SqlUserDao and NoSqlUserDao. In my client code, I would like to use UserDao trait. In addition, I don't want my client code to know anything about SqlUserDao or NoSqlUserDao. I know I can have a factory/manager object that returns the appropriate implementation, but I wanted to see if there's a better way.
>
> Thanks,
>
> Drew
Sun, 2012-02-05, 11:21
#7
Re: How to "Program to an interface, not an implementation" in
On 2012, Feb 5, at 10:04 AM, Drew Kutcharian wrote:
> Thanks Jean-Francois, this is more like what I was looking for. My only concern is that since UserDao object is extending SqlUserDao, wouldn't its implementation details leak into the client app? What I mean is wouldn't I be able to call methods that exist in SqlUserDao but not in UserDao trait? How can I enforce that UserDao object is only allowing it's clients to call only the methods defined in UserDao traitwithout marking those "other" methods private?
The Java way of doing it would be to package SqlUserDao in a separate jar file, which you don't ship to your clients. This makes it a bit harder to break the architectural constraints, and comes with a hefty management overhead. You can reverse-engineer the innards of SqlUserDao if you get hold of it and call the hidden bits anyway.
You can use something like OSGi. The container will ensure that you don't get to call the private bits of a module. Again, there is a price connected to applying more technology to solve the problem.
The big question is: Why do you want to enforce your traits/interfaces to the point of forbidding access to the implementation? Why is that so important to you?
In my team, we have chosen not to apply more technology than we have to. We have business problems to solve, and hiding implementation details from people who can check out the code anyway is far down on the list of things we want to fix. We use code reviews and pair programming to enforce our architecture. This is not an issue since the team has agreed on the architecture as a team (or at least been in the meetings where we decided), and is collectively helping to move it forward.
The language is a bearer of that architecture, but does not enforce it. This is a feature - we may want to change our architecture in the future, and we want our tools to be able to encompass the new architecture as well, whatever it may turn out to be.
You have chosen a different path. Clearly, you are in a different position than we are. If you are in a position where you can describe it, I would love to hear about why you have chosen differently.
yours
Geir
Sun, 2012-02-05, 13:21
#8
Re: How to "Program to an interface, not an implementation" in S
Hi drew!
Besides the very nice advice from Geir, I would suggest you to take a
look at the concept of type classes. Here are some resources to get
started:
http://debasishg.blogspot.com/2011/03/pushing-envelope-on-oo-and-functio...
http://debasishg.blogspot.com/2010/06/scala-implicits-type-classes-here-...
http://debasishg.blogspot.com/2010/07/refactoring-into-scala-type-classe...
Regards Andreas
On Feb 5, 4:00 am, Drew Kutcharian wrote:
> Hi Everyone,
>
> I'm trying to figure out what's the best way to achieve "Program to an interface, not an implementation" in Scala.
>
> For example I have a UserDao trait and two implementations of it, SqlUserDao and NoSqlUserDao. In my client code, I would like to use UserDao trait. In addition, I don't want my client code to know anything about SqlUserDao or NoSqlUserDao. I know I can have a factory/manager object that returns the appropriate implementation, but I wanted to see if there's a better way.
>
> Thanks,
>
> Drew
Mon, 2012-02-06, 06:41
#9
Re: How to "Program to an interface, not an implementation" in
Thanks everyone for all the great comments. I spent today looking for alternatives and found https://github.com/dickwall/subcut which does pretty much what I wanted and more and in addition it's super light.
cheers,
Drew
On Feb 5, 2012, at 4:16 AM, Andreas Scheinert wrote:
> Hi drew!
> Besides the very nice advice from Geir, I would suggest you to take a
> look at the concept of type classes. Here are some resources to get
> started:
> http://debasishg.blogspot.com/2011/03/pushing-envelope-on-oo-and-functio...
> http://debasishg.blogspot.com/2010/06/scala-implicits-type-classes-here-...
> http://debasishg.blogspot.com/2010/07/refactoring-into-scala-type-classe...
>
> Regards Andreas
>
>
>
> On Feb 5, 4:00 am, Drew Kutcharian wrote:
>> Hi Everyone,
>>
>> I'm trying to figure out what's the best way to achieve "Program to an interface, not an implementation" in Scala.
>>
>> For example I have a UserDao trait and two implementations of it, SqlUserDao and NoSqlUserDao. In my client code, I would like to use UserDao trait. In addition, I don't want my client code to know anything about SqlUserDao or NoSqlUserDao. I know I can have a factory/manager object that returns the appropriate implementation, but I wanted to see if there's a better way.
>>
>> Thanks,
>>
>> Drew
Mon, 2012-02-06, 10:01
#10
Re: How to "Program to an interface, not an implementation" in S
Hello Drew,
You should take a look at Sindi: http://aloiscochard.github.com/sindi
It's an IoC container I'm developing and I've just released a new
version with a user guide: http://aloiscochard.github.com/sindi/guide/
I find this approach more flexible than the cake pattern (i.e.
Component system)
Let's me know what you think!
Cheers,
Alois Cochard
On Feb 5, 4:00 am, Drew Kutcharian wrote:
> Hi Everyone,
>
> I'm trying to figure out what's the best way to achieve "Program to an interface, not an implementation" in Scala.
>
> For example I have a UserDao trait and two implementations of it, SqlUserDao and NoSqlUserDao. In my client code, I would like to use UserDao trait. In addition, I don't want my client code to know anything about SqlUserDao or NoSqlUserDao. I know I can have a factory/manager object that returns the appropriate implementation, but I wanted to see if there's a better way.
>
> Thanks,
>
> Drew
Mon, 2012-02-06, 10:11
#11
Re: How to "Program to an interface, not an implementation" in S
The main advantage of Sindi over Subcut is the usage of a compiler
plugin which check dependencies at compile time, preventing compiling
an application/library with unsatisfied dependency.
It's very light too imo ;)
Cheers,
On Feb 6, 6:36 am, Drew Kutcharian wrote:
> Thanks everyone for all the great comments. I spent today looking for alternatives and foundhttps://github.com/dickwall/subcutwhich does pretty much what I wanted and more and in addition it's super light.
>
> cheers,
>
> Drew
>
> On Feb 5, 2012, at 4:16 AM, Andreas Scheinert wrote:
>
>
>
>
>
>
>
> > Hi drew!
> > Besides the very nice advice from Geir, I would suggest you to take a
> > look at the concept of type classes. Here are some resources to get
> > started:
> >http://debasishg.blogspot.com/2011/03/pushing-envelope-on-oo-and-func...
> >http://debasishg.blogspot.com/2010/06/scala-implicits-type-classes-he...
> >http://debasishg.blogspot.com/2010/07/refactoring-into-scala-type-cla...
>
> > Regards Andreas
>
> > On Feb 5, 4:00 am, Drew Kutcharian wrote:
> >> Hi Everyone,
>
> >> I'm trying to figure out what's the best way to achieve "Program to an interface, not an implementation" in Scala.
>
> >> For example I have a UserDao trait and two implementations of it, SqlUserDao and NoSqlUserDao. In my client code, I would like to use UserDao trait. In addition, I don't want my client code to know anything about SqlUserDao or NoSqlUserDao. I know I can have a factory/manager object that returns the appropriate implementation, but I wanted to see if there's a better way.
>
> >> Thanks,
>
> >> Drew
Mon, 2012-02-06, 17:11
#12
Re: How to "Program to an interface, not an implementation" in
If you have methods in SqlUserDao that are public and not part of the
UserDao trait, they will get mixed into the UserDao object and will be
available to clients. This does mean that all of the implementation
details of SqlUserDao should be done in protected/private defs, which
does not really seem like an onerous requirement. Since objects can't
be extended, this does ensure that whatever is not public will be
inaccessible to client code.
On Sun, Feb 5, 2012 at 04:04, Drew Kutcharian wrote:
> Thanks Jean-Francois, this is more like what I was looking for. My only concern is that since UserDao object is extending SqlUserDao, wouldn't its implementation details leak into the client app? What I mean is wouldn't I be able to call methods that exist in SqlUserDao but not in UserDao trait? How can I enforce that UserDao object is only allowing it's clients to call only the methods defined in UserDao traitwithout marking those "other" methods private?
>
>
>
> On Feb 5, 2012, at 12:09 AM, Jean-Francois Im wrote:
>
>> If you don't want to change the actual implementation based on
>> different environments (ie. using mocks for testing or whatnot), it's
>> possible to just mix the implementation in an object, baking it at
>> compile time into the classfile.
>>
>> case class User(name:String)
>>
>> trait Dao[T] {
>> def save(t:T);
>> }
>>
>> trait UserDao extends Dao[User]
>>
>> class NoSqlUserDao extends UserDao {
>> def save(user:User) {
>> println("Saved user " + user.name + " in NoSQL DB");
>> }
>> }
>>
>> class SqlUserDao extends UserDao {
>> def save(user:User) {
>> println("Saved user " + user.name + " in SQL DB");
>> }
>> }
>>
>> object UserDao extends SqlUserDao
>>
>> object Demo extends App {
>> val user = User("Bob")
>> UserDao.save(user)
>> }
>>
>> On Sun, Feb 5, 2012 at 01:15, Vlad Patryshev wrote:
>>> +1 for Cake Pattern. Using it all the time for testability. Take an Object,
>>> extract functionality into trait, inherit from that trait, and, in tests, or
>>> in a variety of objects, inject all your dependency.
>>>
>>> I believe it is way cooler than this javaish "interface/class" dichotomy.
>>>
>>> Thanks,
>>> -Vlad
>>>
>>>
>>>
>>> On Sat, Feb 4, 2012 at 7:30 PM, Jean-Francois Im
>>> wrote:
>>>>
>>>> Jonas Boner has a great post about the Cake pattern and alternatives in
>>>> Scala.
>>>>
>>>> http://jonasboner.com/2008/10/06/real-world-scala-dependency-injection-di/
>>>>
>>>> On Sat, Feb 4, 2012 at 22:00, Drew Kutcharian wrote:
>>>>> Hi Everyone,
>>>>>
>>>>> I'm trying to figure out what's the best way to achieve "Program to an
>>>>> interface, not an implementation" in Scala.
>>>>>
>>>>> For example I have a UserDao trait and two implementations of it,
>>>>> SqlUserDao and NoSqlUserDao. In my client code, I would like to use UserDao
>>>>> trait. In addition, I don't want my client code to know anything about
>>>>> SqlUserDao or NoSqlUserDao. I know I can have a factory/manager object that
>>>>> returns the appropriate implementation, but I wanted to see if there's a
>>>>> better way.
>>>>>
>>>>> Thanks,
>>>>>
>>>>> Drew
>>>
>>>
Mon, 2012-02-06, 17:31
#13
Re: How to "Program to an interface, not an implementation" in
You can use composition instead of inheritance in this case.
trait WrappedDao[A] extends Dao[A] { def underlying: Dao[A]
def save(a: A) = underlying.save(a) }
object UserDao extends WrappedDao[User] { val underyling = new SqlUserDao { }}
On Mon, Feb 6, 2012 at 11:07 AM, Jean-Francois Im <jfim@jean-francois.im> wrote:
trait WrappedDao[A] extends Dao[A] { def underlying: Dao[A]
def save(a: A) = underlying.save(a) }
object UserDao extends WrappedDao[User] { val underyling = new SqlUserDao { }}
On Mon, Feb 6, 2012 at 11:07 AM, Jean-Francois Im <jfim@jean-francois.im> wrote:
If you have methods in SqlUserDao that are public and not part of the
UserDao trait, they will get mixed into the UserDao object and will be
available to clients. This does mean that all of the implementation
details of SqlUserDao should be done in protected/private defs, which
does not really seem like an onerous requirement. Since objects can't
be extended, this does ensure that whatever is not public will be
inaccessible to client code.
On Sun, Feb 5, 2012 at 04:04, Drew Kutcharian <drew@venarc.com> wrote:
> Thanks Jean-Francois, this is more like what I was looking for. My only concern is that since UserDao object is extending SqlUserDao, wouldn't its implementation details leak into the client app? What I mean is wouldn't I be able to call methods that exist in SqlUserDao but not in UserDao trait? How can I enforce that UserDao object is only allowing it's clients to call only the methods defined in UserDao traitwithout marking those "other" methods private?
>
>
>
> On Feb 5, 2012, at 12:09 AM, Jean-Francois Im <jfim@jean-francois.im> wrote:
>
>> If you don't want to change the actual implementation based on
>> different environments (ie. using mocks for testing or whatnot), it's
>> possible to just mix the implementation in an object, baking it at
>> compile time into the classfile.
>>
>> case class User(name:String)
>>
>> trait Dao[T] {
>> def save(t:T);
>> }
>>
>> trait UserDao extends Dao[User]
>>
>> class NoSqlUserDao extends UserDao {
>> def save(user:User) {
>> println("Saved user " + user.name + " in NoSQL DB");
>> }
>> }
>>
>> class SqlUserDao extends UserDao {
>> def save(user:User) {
>> println("Saved user " + user.name + " in SQL DB");
>> }
>> }
>>
>> object UserDao extends SqlUserDao
>>
>> object Demo extends App {
>> val user = User("Bob")
>> UserDao.save(user)
>> }
>>
>> On Sun, Feb 5, 2012 at 01:15, Vlad Patryshev <vpatryshev@gmail.com> wrote:
>>> +1 for Cake Pattern. Using it all the time for testability. Take an Object,
>>> extract functionality into trait, inherit from that trait, and, in tests, or
>>> in a variety of objects, inject all your dependency.
>>>
>>> I believe it is way cooler than this javaish "interface/class" dichotomy.
>>>
>>> Thanks,
>>> -Vlad
>>>
>>>
>>>
>>> On Sat, Feb 4, 2012 at 7:30 PM, Jean-Francois Im <jfim@jean-francois.im>
>>> wrote:
>>>>
>>>> Jonas Boner has a great post about the Cake pattern and alternatives in
>>>> Scala.
>>>>
>>>> http://jonasboner.com/2008/10/06/real-world-scala-dependency-injection-di/
>>>>
>>>> On Sat, Feb 4, 2012 at 22:00, Drew Kutcharian <drew@venarc.com> wrote:
>>>>> Hi Everyone,
>>>>>
>>>>> I'm trying to figure out what's the best way to achieve "Program to an
>>>>> interface, not an implementation" in Scala.
>>>>>
>>>>> For example I have a UserDao trait and two implementations of it,
>>>>> SqlUserDao and NoSqlUserDao. In my client code, I would like to use UserDao
>>>>> trait. In addition, I don't want my client code to know anything about
>>>>> SqlUserDao or NoSqlUserDao. I know I can have a factory/manager object that
>>>>> returns the appropriate implementation, but I wanted to see if there's a
>>>>> better way.
>>>>>
>>>>> Thanks,
>>>>>
>>>>> Drew
>>>
>>>
Mon, 2012-02-06, 21:11
#14
Re: How to "Program to an interface, not an implementation" in
Hello Alois,
I did take a look at Sindi, it's looks good. Actually, as far as I can tell, Sindi, Scaldi and SubCut all do pretty much the same thing in almost the same way. I just picked subcut because I liked the API better. Subcut also has a compiler plugin just like the others.
cheers,
Drew
On Feb 6, 2012, at 12:55 AM, Alois Cochard wrote:
> Hello Drew,
>
> You should take a look at Sindi: http://aloiscochard.github.com/sindi
>
> It's an IoC container I'm developing and I've just released a new
> version with a user guide: http://aloiscochard.github.com/sindi/guide/
>
> I find this approach more flexible than the cake pattern (i.e.
> Component system)
>
> Let's me know what you think!
>
> Cheers,
>
> Alois Cochard
>
> On Feb 5, 4:00 am, Drew Kutcharian wrote:
>> Hi Everyone,
>>
>> I'm trying to figure out what's the best way to achieve "Program to an interface, not an implementation" in Scala.
>>
>> For example I have a UserDao trait and two implementations of it, SqlUserDao and NoSqlUserDao. In my client code, I would like to use UserDao trait. In addition, I don't want my client code to know anything about SqlUserDao or NoSqlUserDao. I know I can have a factory/manager object that returns the appropriate implementation, but I wanted to see if there's a better way.
>>
>> Thanks,
>>
>> Drew
Mon, 2012-02-06, 21:21
#15
Re: How to "Program to an interface, not an implementation" in
Yes, good idea.
On Feb 6, 2012, at 8:26 AM, Tom Switzer wrote:
On Feb 6, 2012, at 8:26 AM, Tom Switzer wrote:
You can use composition instead of inheritance in this case.
trait WrappedDao[A] extends Dao[A] { def underlying: Dao[A]
def save(a: A) = underlying.save(a) }
object UserDao extends WrappedDao[User] { val underyling = new SqlUserDao { }}
On Mon, Feb 6, 2012 at 11:07 AM, Jean-Francois Im <jfim@jean-francois.im> wrote:
If you have methods in SqlUserDao that are public and not part of the
UserDao trait, they will get mixed into the UserDao object and will be
available to clients. This does mean that all of the implementation
details of SqlUserDao should be done in protected/private defs, which
does not really seem like an onerous requirement. Since objects can't
be extended, this does ensure that whatever is not public will be
inaccessible to client code.
On Sun, Feb 5, 2012 at 04:04, Drew Kutcharian <drew@venarc.com> wrote:
> Thanks Jean-Francois, this is more like what I was looking for. My only concern is that since UserDao object is extending SqlUserDao, wouldn't its implementation details leak into the client app? What I mean is wouldn't I be able to call methods that exist in SqlUserDao but not in UserDao trait? How can I enforce that UserDao object is only allowing it's clients to call only the methods defined in UserDao traitwithout marking those "other" methods private?
>
>
>
> On Feb 5, 2012, at 12:09 AM, Jean-Francois Im <jfim@jean-francois.im> wrote:
>
>> If you don't want to change the actual implementation based on
>> different environments (ie. using mocks for testing or whatnot), it's
>> possible to just mix the implementation in an object, baking it at
>> compile time into the classfile.
>>
>> case class User(name:String)
>>
>> trait Dao[T] {
>> def save(t:T);
>> }
>>
>> trait UserDao extends Dao[User]
>>
>> class NoSqlUserDao extends UserDao {
>> def save(user:User) {
>> println("Saved user " + user.name + " in NoSQL DB");
>> }
>> }
>>
>> class SqlUserDao extends UserDao {
>> def save(user:User) {
>> println("Saved user " + user.name + " in SQL DB");
>> }
>> }
>>
>> object UserDao extends SqlUserDao
>>
>> object Demo extends App {
>> val user = User("Bob")
>> UserDao.save(user)
>> }
>>
>> On Sun, Feb 5, 2012 at 01:15, Vlad Patryshev <vpatryshev@gmail.com> wrote:
>>> +1 for Cake Pattern. Using it all the time for testability. Take an Object,
>>> extract functionality into trait, inherit from that trait, and, in tests, or
>>> in a variety of objects, inject all your dependency.
>>>
>>> I believe it is way cooler than this javaish "interface/class" dichotomy.
>>>
>>> Thanks,
>>> -Vlad
>>>
>>>
>>>
>>> On Sat, Feb 4, 2012 at 7:30 PM, Jean-Francois Im <jfim@jean-francois.im>
>>> wrote:
>>>>
>>>> Jonas Boner has a great post about the Cake pattern and alternatives in
>>>> Scala.
>>>>
>>>> http://jonasboner.com/2008/10/06/real-world-scala-dependency-injection-di/
>>>>
>>>> On Sat, Feb 4, 2012 at 22:00, Drew Kutcharian <drew@venarc.com> wrote:
>>>>> Hi Everyone,
>>>>>
>>>>> I'm trying to figure out what's the best way to achieve "Program to an
>>>>> interface, not an implementation" in Scala.
>>>>>
>>>>> For example I have a UserDao trait and two implementations of it,
>>>>> SqlUserDao and NoSqlUserDao. In my client code, I would like to use UserDao
>>>>> trait. In addition, I don't want my client code to know anything about
>>>>> SqlUserDao or NoSqlUserDao. I know I can have a factory/manager object that
>>>>> returns the appropriate implementation, but I wanted to see if there's a
>>>>> better way.
>>>>>
>>>>> Thanks,
>>>>>
>>>>> Drew
>>>
>>>
Tue, 2012-02-07, 09:11
#16
Re: How to "Program to an interface, not an implementation" in
Hello Drew,
Thanks for taking a look :)
But in fact, nor SubCut nor Scaldi does checking of dependency at compile time... SubCut plugin do some sugaring to add implicit automatically and I don't really know for Scaldi but I saw nothing like that in documentation.
Anyway have fun with SubCut!
Cheers,
On 6 February 2012 21:09, Drew Kutcharian <drew@venarc.com> wrote:
--
Alois Cochardhttp://aloiscochard.blogspot.comhttp://twitter.com/aloiscochard
Thanks for taking a look :)
But in fact, nor SubCut nor Scaldi does checking of dependency at compile time... SubCut plugin do some sugaring to add implicit automatically and I don't really know for Scaldi but I saw nothing like that in documentation.
Anyway have fun with SubCut!
Cheers,
On 6 February 2012 21:09, Drew Kutcharian <drew@venarc.com> wrote:
Hello Alois,
I did take a look at Sindi, it's looks good. Actually, as far as I can tell, Sindi, Scaldi and SubCut all do pretty much the same thing in almost the same way. I just picked subcut because I liked the API better. Subcut also has a compiler plugin just like the others.
cheers,
Drew
On Feb 6, 2012, at 12:55 AM, Alois Cochard wrote:
> Hello Drew,
>
> You should take a look at Sindi: http://aloiscochard.github.com/sindi
>
> It's an IoC container I'm developing and I've just released a new
> version with a user guide: http://aloiscochard.github.com/sindi/guide/
>
> I find this approach more flexible than the cake pattern (i.e.
> Component system)
>
> Let's me know what you think!
>
> Cheers,
>
> Alois Cochard
>
> On Feb 5, 4:00 am, Drew Kutcharian <d...@venarc.com> wrote:
>> Hi Everyone,
>>
>> I'm trying to figure out what's the best way to achieve "Program to an interface, not an implementation" in Scala.
>>
>> For example I have a UserDao trait and two implementations of it, SqlUserDao and NoSqlUserDao. In my client code, I would like to use UserDao trait. In addition, I don't want my client code to know anything about SqlUserDao or NoSqlUserDao. I know I can have a factory/manager object that returns the appropriate implementation, but I wanted to see if there's a better way.
>>
>> Thanks,
>>
>> Drew
--
Alois Cochardhttp://aloiscochard.blogspot.comhttp://twitter.com/aloiscochard
Tue, 2012-02-07, 10:01
#17
Re: How to "Program to an interface, not an implementation" in
Hi Alois,
I didn't look for compile time dependency checking. Didn't know that could be done. Can you link me to how it's done using Sindi?
Thanks,
Drew
On Feb 7, 2012, at 12:02 AM, Alois Cochard <alois.cochard@gmail.com> wrote:
I didn't look for compile time dependency checking. Didn't know that could be done. Can you link me to how it's done using Sindi?
Thanks,
Drew
On Feb 7, 2012, at 12:02 AM, Alois Cochard <alois.cochard@gmail.com> wrote:
Hello Drew,
Thanks for taking a look :)
But in fact, nor SubCut nor Scaldi does checking of dependency at compile time... SubCut plugin do some sugaring to add implicit automatically and I don't really know for Scaldi but I saw nothing like that in documentation.
Anyway have fun with SubCut!
Cheers,
On 6 February 2012 21:09, Drew Kutcharian <drew@venarc.com> wrote:
Hello Alois,
I did take a look at Sindi, it's looks good. Actually, as far as I can tell, Sindi, Scaldi and SubCut all do pretty much the same thing in almost the same way. I just picked subcut because I liked the API better. Subcut also has a compiler plugin just like the others.
cheers,
Drew
On Feb 6, 2012, at 12:55 AM, Alois Cochard wrote:
> Hello Drew,
>
> You should take a look at Sindi: http://aloiscochard.github.com/sindi
>
> It's an IoC container I'm developing and I've just released a new
> version with a user guide: http://aloiscochard.github.com/sindi/guide/
>
> I find this approach more flexible than the cake pattern (i.e.
> Component system)
>
> Let's me know what you think!
>
> Cheers,
>
> Alois Cochard
>
> On Feb 5, 4:00 am, Drew Kutcharian <d...@venarc.com> wrote:
>> Hi Everyone,
>>
>> I'm trying to figure out what's the best way to achieve "Program to an interface, not an implementation" in Scala.
>>
>> For example I have a UserDao trait and two implementations of it, SqlUserDao and NoSqlUserDao. In my client code, I would like to use UserDao trait. In addition, I don't want my client code to know anything about SqlUserDao or NoSqlUserDao. I know I can have a factory/manager object that returns the appropriate implementation, but I wanted to see if there's a better way.
>>
>> Thanks,
>>
>> Drew
--
Alois Cochardhttp://aloiscochard.blogspot.comhttp://twitter.com/aloiscochard
Wed, 2012-02-08, 09:21
#18
Re: How to "Program to an interface, not an implementation" in
Hi Drew,
Not everything is perfect, I'm working a lot on having complete checking and less boiler plate in version 0.5, I plan to write a blog post showing how compile time checking work.
In the mean time, I recommend simply taking the user guide project:https://github.com/aloiscochard/sindi/tree/0.4/sindi-examples/userguide
Compile it with SBT and the first thing you can check, is -in a context- trying to inject[T] a type who is not bound, i.e adding "inject[Info]" in the example "context.scala", the compiler will generate an error like: /userguide/src/main/scala/context.scala:21: type not bound: 'sindi.examples.userguide.context.Info'
You will see that the compiler print out a JSON representation of the dependency graph (proving how he analyzed them) this is due to specially "verbose" flag given to compiler plugin, you can check .sbt file to see how it's configured.
Don't hesitate to look at the documentation: http://aloiscochard.github.com/sindi/guide/basic.html ... and as you will read here, autowire isn't yet -completely- checked at compile time, it's planned for 0.5, it's totally feasible, but just take time - it's not that easy to work on AST ;).
Next cool feature to come in 0.5 is to automatically expose binding of module thru method, which will reduce the boiler plate you have to write when exposing module services.
And if you have futher question, could you please ask them on the dedicated mailing list: http://groups.google.com/group/sindi-users
Really looking forward your feedback, thanks a lot!
Cheers,
On 7 February 2012 09:52, Drew Kutcharian <drew@venarc.com> wrote:
--
Alois Cochardhttp://aloiscochard.blogspot.com http://twitter.com/aloiscochard
Not everything is perfect, I'm working a lot on having complete checking and less boiler plate in version 0.5, I plan to write a blog post showing how compile time checking work.
In the mean time, I recommend simply taking the user guide project:https://github.com/aloiscochard/sindi/tree/0.4/sindi-examples/userguide
Compile it with SBT and the first thing you can check, is -in a context- trying to inject[T] a type who is not bound, i.e adding "inject[Info]" in the example "context.scala", the compiler will generate an error like: /userguide/src/main/scala/context.scala:21: type not bound: 'sindi.examples.userguide.context.Info'
You will see that the compiler print out a JSON representation of the dependency graph (proving how he analyzed them) this is due to specially "verbose" flag given to compiler plugin, you can check .sbt file to see how it's configured.
Don't hesitate to look at the documentation: http://aloiscochard.github.com/sindi/guide/basic.html ... and as you will read here, autowire isn't yet -completely- checked at compile time, it's planned for 0.5, it's totally feasible, but just take time - it's not that easy to work on AST ;).
Next cool feature to come in 0.5 is to automatically expose binding of module thru method, which will reduce the boiler plate you have to write when exposing module services.
And if you have futher question, could you please ask them on the dedicated mailing list: http://groups.google.com/group/sindi-users
Really looking forward your feedback, thanks a lot!
Cheers,
On 7 February 2012 09:52, Drew Kutcharian <drew@venarc.com> wrote:
Hi Alois,
I didn't look for compile time dependency checking. Didn't know that could be done. Can you link me to how it's done using Sindi?
Thanks,
Drew
On Feb 7, 2012, at 12:02 AM, Alois Cochard <alois.cochard@gmail.com> wrote:
Hello Drew,
Thanks for taking a look :)
But in fact, nor SubCut nor Scaldi does checking of dependency at compile time... SubCut plugin do some sugaring to add implicit automatically and I don't really know for Scaldi but I saw nothing like that in documentation.
Anyway have fun with SubCut!
Cheers,
On 6 February 2012 21:09, Drew Kutcharian <drew@venarc.com> wrote:
Hello Alois,
I did take a look at Sindi, it's looks good. Actually, as far as I can tell, Sindi, Scaldi and SubCut all do pretty much the same thing in almost the same way. I just picked subcut because I liked the API better. Subcut also has a compiler plugin just like the others.
cheers,
Drew
On Feb 6, 2012, at 12:55 AM, Alois Cochard wrote:
> Hello Drew,
>
> You should take a look at Sindi: http://aloiscochard.github.com/sindi
>
> It's an IoC container I'm developing and I've just released a new
> version with a user guide: http://aloiscochard.github.com/sindi/guide/
>
> I find this approach more flexible than the cake pattern (i.e.
> Component system)
>
> Let's me know what you think!
>
> Cheers,
>
> Alois Cochard
>
> On Feb 5, 4:00 am, Drew Kutcharian <d...@venarc.com> wrote:
>> Hi Everyone,
>>
>> I'm trying to figure out what's the best way to achieve "Program to an interface, not an implementation" in Scala.
>>
>> For example I have a UserDao trait and two implementations of it, SqlUserDao and NoSqlUserDao. In my client code, I would like to use UserDao trait. In addition, I don't want my client code to know anything about SqlUserDao or NoSqlUserDao. I know I can have a factory/manager object that returns the appropriate implementation, but I wanted to see if there's a better way.
>>
>> Thanks,
>>
>> Drew
--
Alois Cochardhttp://aloiscochard.blogspot.comhttp://twitter.com/aloiscochard
--
Alois Cochardhttp://aloiscochard.blogspot.com http://twitter.com/aloiscochard
Jonas Boner has a great post about the Cake pattern and alternatives in Scala.
http://jonasboner.com/2008/10/06/real-world-scala-dependency-injection-di/
On Sat, Feb 4, 2012 at 22:00, Drew Kutcharian wrote:
> Hi Everyone,
>
> I'm trying to figure out what's the best way to achieve "Program to an interface, not an implementation" in Scala.
>
> For example I have a UserDao trait and two implementations of it, SqlUserDao and NoSqlUserDao. In my client code, I would like to use UserDao trait. In addition, I don't want my client code to know anything about SqlUserDao or NoSqlUserDao. I know I can have a factory/manager object that returns the appropriate implementation, but I wanted to see if there's a better way.
>
> Thanks,
>
> Drew