SOLID principals in D

2018-06-16 Thread FromAnotherPlanet via Digitalmars-d
Hi, I come from a C# background and have been looking at D. How 
well does D implement solid principals? I've grown to really 
enjoy the SOLID style.


For those unfamiliar, SOLID is an acronym for:

 - Single purpose: Meaning every unit of code (whether it's a 
function or class) should only

have one reason to change.

 - Open/Close principal: Things should be open to extension but 
closed to modification. The example I like to use is some sort of 
IConverter object. Things can implement IConverter, but if you 
need a new way to 'convert' things, you don't extend an existing 
object, but instead create a new class that implements IConverter.


 - Liskov substitution principle: Essentially says if I have a 
method/function that takes a base class, then the behavior of 
that method shouldn't change when passing in derived objects. I 
think the term people like to use is whether or not you use a 
base/derived class it shouldn't effect the 'correctness' of the 
program.


 - Interface segregation principal: Essentially breaking the 
program up into smaller interfaces. Sometimes only consistent of 
one or two methods/properties (can feed into 'S' of SOLID quite 
nicely).


 - Dependency inversion principle: Things should depend on 
abstractions not concretions. Strongly enables dependency 
injection.


D seems to have all of the features *required* to make this 
happen, but I guess the real question is the last two, and more 
specifically the last one.


Re: SOLID principals in D

2018-06-16 Thread FromAnotherPlanet via Digitalmars-d
On Saturday, 16 June 2018 at 19:20:30 UTC, FromAnotherPlanet 
wrote:
Hi, I come from a C# background and have been looking at D. How 
well does D implement solid principals? I've grown to really 
enjoy the SOLID style.


For those unfamiliar, SOLID is an acronym for:

 - Single purpose: Meaning every unit of code (whether it's a 
function or class) should only

have one reason to change.

 - Open/Close principal: Things should be open to extension but 
closed to modification. The example I like to use is some sort 
of IConverter object. Things can implement IConverter, but if 
you need a new way to 'convert' things, you don't extend an 
existing object, but instead create a new class that implements 
IConverter.


 - Liskov substitution principle: Essentially says if I have a 
method/function that takes a base class, then the behavior of 
that method shouldn't change when passing in derived objects. I 
think the term people like to use is whether or not you use a 
base/derived class it shouldn't effect the 'correctness' of the 
program.




Also if there is any good literature that explains the 'D' way of 
going about these principals or even how it enhances them that 
would be helpful.
 - Interface segregation principal: Essentially breaking the 
program up into smaller interfaces. Sometimes only consistent 
of one or two methods/properties (can feed into 'S' of SOLID 
quite nicely).


 - Dependency inversion principle: Things should depend on 
abstractions not concretions. Strongly enables dependency 
injection.


D seems to have all of the features *required* to make this 
happen, but I guess the real question is the last two, and more 
specifically the last one.





Re: SOLID principals in D

2018-06-16 Thread evilrat via Digitalmars-d
On Saturday, 16 June 2018 at 19:20:30 UTC, FromAnotherPlanet 
wrote:
Hi, I come from a C# background and have been looking at D. How 
well does D implement solid principals? I've grown to really 
enjoy the SOLID style.


For those unfamiliar, SOLID is an acronym for:

 - Single purpose: Meaning every unit of code (whether it's a 
function or class) should only

have one reason to change.

 - Open/Close principal: Things should be open to extension but 
closed to modification. The example I like to use is some sort 
of IConverter object. Things can implement IConverter, but if 
you need a new way to 'convert' things, you don't extend an 
existing object, but instead create a new class that implements 
IConverter.


 - Liskov substitution principle: Essentially says if I have a 
method/function that takes a base class, then the behavior of 
that method shouldn't change when passing in derived objects. I 
think the term people like to use is whether or not you use a 
base/derived class it shouldn't effect the 'correctness' of the 
program.


 - Interface segregation principal: Essentially breaking the 
program up into smaller interfaces. Sometimes only consistent 
of one or two methods/properties (can feed into 'S' of SOLID 
quite nicely).


 - Dependency inversion principle: Things should depend on 
abstractions not concretions. Strongly enables dependency 
injection.


D seems to have all of the features *required* to make this 
happen, but I guess the real question is the last two, and more 
specifically the last one.


I am still not a D pro, so some thoughts maybe a bit off...

(intro part)
The "true D" guru's would tell you "in D your typical code would 
be mostly ranges(or templates) instead of classes", there is a 
good portion truth, but IMHO I find it overly attached.
D uses duck typing for ranges, which means for example very basic 
(input) range have this protocol of 3 primitives - popFront(), 
front, empty
Ranges heavily used in conjunction with templates, and templates 
is static thing, but with clever use of duck typing and that 
range protocol usually you don't care about specific type at all 
when dealing with ranges. Of course there is polymorphic 
interface(as in C#) for ranges too.



Now how it applies to S and O? Ranges is basically an essence of 
S principle, they do exactly single thing, and most functions 
taking ranges as well.
Just look at this "Sort lines" or some other examples on main 
page:

-
stdin
  .byLineCopy
  .array
  .sort!((a, b) => a > b) // descending order
  .each!writeln;
--
stdin is console input stream, what happens next? all four 
functions above operates on ranges, and you can clearly tell what 
is their purpose. In this simple example they started operate on 
stdin, but in no way limited to it. It can be file, network 
stream or whatever else as long it is implements range protocol. 
Even though these functions may have different interface this is 
still the possibility for open/close principle. (yep, I agree 
this isn't the best example)


(sorry, this part is not about SOLID at all)
This is how most of standard library built, sure this isn't C# 
BCL and there is so very few things comparing to it, and there is 
very few use of polymorthic types in it, but it is highly generic 
because of use of templates.


But enough about standard library, you are not forced to do 
everything that way, there is of course classes and interfaces, 
they work same as in C#, mostly. In own code you can do pretty 
much anything you can in C# (not actually sure what you can't) 
using classes and interfaces.


I skip the Liskov principle. Classes and interfaces is enough to 
cover it, but again D is not limited to them, so you may even 
find your own discoveries.



A word about DI in both D and D in SOLID:
This isn't actually limited to just classes, basically it means 
that you(client code) provide dependencies(whatever things needed 
to be operational) for function/class you use to do the work, so 
they don't just 'new' it on their own.
There is even a DI framework[1] (don't mind the names in API, I 
think it is heavily inspired by Java's Spring)



Since you are coming from C# background the current state of 
tooling may shock you, the standard library is not a swiss knife 
and doesn't have all the goodies BCL has, I even pointed out 
there is not that much OOP stuff and polymorphism in it. There is 
also some language design choices that may surprise(both good and 
not so good ways) you.




[1] https://code.dlang.org/packages/aedi






Re: SOLID principals in D

2018-06-16 Thread Joakim via Digitalmars-d

On Sunday, 17 June 2018 at 01:38:17 UTC, evilrat wrote:
On Saturday, 16 June 2018 at 19:20:30 UTC, FromAnotherPlanet 
wrote:
Hi, I come from a C# background and have been looking at D. 
How well does D implement solid principals? I've grown to 
really enjoy the SOLID style.


For those unfamiliar, SOLID is an acronym for:

 - Single purpose: Meaning every unit of code (whether it's a 
function or class) should only

have one reason to change.

 - Open/Close principal: Things should be open to extension 
but closed to modification. The example I like to use is some 
sort of IConverter object. Things can implement IConverter, 
but if you need a new way to 'convert' things, you don't 
extend an existing object, but instead create a new class that 
implements IConverter.


 - Liskov substitution principle: Essentially says if I have a 
method/function that takes a base class, then the behavior of 
that method shouldn't change when passing in derived objects. 
I think the term people like to use is whether or not you use 
a base/derived class it shouldn't effect the 'correctness' of 
the program.


 - Interface segregation principal: Essentially breaking the 
program up into smaller interfaces. Sometimes only consistent 
of one or two methods/properties (can feed into 'S' of SOLID 
quite nicely).


 - Dependency inversion principle: Things should depend on 
abstractions not concretions. Strongly enables dependency 
injection.


D seems to have all of the features *required* to make this 
happen, but I guess the real question is the last two, and 
more specifically the last one.


I am still not a D pro, so some thoughts maybe a bit off...

(intro part)
The "true D" guru's would tell you "in D your typical code 
would be mostly ranges(or templates) instead of classes", there 
is a good portion truth, but IMHO I find it overly attached.
D uses duck typing for ranges, which means for example very 
basic (input) range have this protocol of 3 primitives - 
popFront(), front, empty
Ranges heavily used in conjunction with templates, and 
templates is static thing, but with clever use of duck typing 
and that range protocol usually you don't care about specific 
type at all when dealing with ranges. Of course there is 
polymorphic interface(as in C#) for ranges too.



Now how it applies to S and O? Ranges is basically an essence 
of S principle, they do exactly single thing, and most 
functions taking ranges as well.
Just look at this "Sort lines" or some other examples on main 
page:

-
stdin
  .byLineCopy
  .array
  .sort!((a, b) => a > b) // descending order
  .each!writeln;
--


Thought I'd add a link to Walter's good article laying out the 
case for such component programming with ranges:


http://www.drdobbs.com/architecture-and-design/component-programming-in-d/240008321


Re: SOLID principals in D

2018-06-17 Thread Jacob Shtokolov via Digitalmars-d
On Saturday, 16 June 2018 at 19:20:30 UTC, FromAnotherPlanet 
wrote:
 - Interface segregation principal: Essentially breaking the 
program up into smaller interfaces. Sometimes only consistent 
of one or two methods/properties (can feed into 'S' of SOLID 
quite nicely).


 - Dependency inversion principle: Things should depend on 
abstractions not concretions. Strongly enables dependency 
injection.


D seems to have all of the features *required* to make this 
happen, but I guess the real question is the last two, and more 
specifically the last one.


Then D supports everything you need (and even better, just look 
at interface with contracts: 
https://dlang.org/spec/interface.html)


Interface segregation example: 
https://run.dlang.io/gist/6aa1710dd5a8327f20e605b0ac3b978f


Keep in mind that D doesn't support multiple inheritance, so if 
you want to follow DRY principle, you need to use interfaces + 
template mixins to make it happen (so in this point D is way 
better than the plain Java, because D's templates mixins are like 
traits).


Dependency injection is also supported. However, D doesn't supply 
any DI containers in its standard library, so you have to rely on 
3rd-party components, or implement it on your own.


Look at this page: 
https://wiki.dlang.org/Dependency_Injection_Containers
The most popular and actively maintained are "aedi" and 
"poodinis".


Re: SOLID principals in D

2018-06-17 Thread FromAnotherPlanet via Digitalmars-d
What's the differences in the approaches between SOLID and 
component programming? Are they orthogonal? Or can they be used 
together?


Re: SOLID principals in D

2018-06-17 Thread Joakim via Digitalmars-d

On Sunday, 17 June 2018 at 12:24:35 UTC, FromAnotherPlanet wrote:
What's the differences in the approaches between SOLID and 
component programming? Are they orthogonal? Or can they be used 
together?


It looks like they have some overlap, but are not the same. SOLID 
seems focused on OOP, whereas component programming isn't and has 
its own abstraction of ranges. I suggest you read the article and 
contrast them for yourself, as I'm not that familiar with SOLID.