last day (14 days later) » 

12:39 AM
7
A: Decorator for cars

Mat's MugYou are mixing up concepts here. The decorator pattern gets much easier to understand when you think in terms of interfaces rather than concrete types. Take your car there: public interface ICar { void Drive(); void Stop(); void Park(); } Now, what you have is a very hard-to-follo...

 
May I rewrite some of the code on top of the post where the section is or should i just rewrite the post for better understanding on the pattern ??
 
@noob1992 if it's going to make the answers moot, an edit of the question is likely to get rolled back (see meta). If you make substantial improvements based on feedback you got here, feel free to ask a new question.
 
I was implying to remove my decorator class as it served no purpose and to remove the op code from it. Initially I will add the code revised for better understanding ??
As I do not understand the decorator pattern yet...
 
This Q+A (the canonical "cake" decorator example) might help. Removing the no-op decorator class from the OP will invalidate answers, and get rolled back; I warmly recommend making a new post.
 
So i should make a new post reading the above statement
 
12:39 AM
Yes, make a new post that incorporates the feedback you got.
hi!
 
Hello @Mat'sMug I was wondering why so should an interface be hidden from the class
 
what do you mean?
I see you're interested in dependency injection - that's great! the DI principle says "depend on abstractions, not concrete types"
interfaces make great abstractions
 
As to this comment here -> Now if you want a squeaking Lamborghini, you can have one, and the car won't even know about it.
and yes I am very much so indeed lol
dependency injection is a hard to learn thing but i rather like a challenge
 
if I may recommend a read: Dependency Injection in .NET, by Mark Seemann. It's excellent.
 
I will look that book up at once
 
12:44 AM
anyway, the Decorator Pattern isn't about DI though
 
Really ? How so
 
DI is really nothing more than depending on abstractions - constructor-injecting dependencies as abstractions
like I did here:
private readonly ICar _car;

public Foobar(ICar car)
{
    _car = car;
}

public void TestDrive()
{
    _car.Drive();
    _car.Stop();
    _car.Park();
}
This Foobar class depends on an abstraction - some ICar. Anything that satisfies that interface can work.
 
And what is abstractions in this event
 
here the abstraction is the ICar interface
 
Alright
 
12:47 AM
public interface ICar
{
    void Drive();
    void Stop();
    void Park();
}
could be a Tesla, a Lamborghini, ...or a Ford Fiesta
 
So we depend on this interface ?
 
consider this:
private readonly LamborghiniCar _car;

public Foobar(LamborghiniCar car)
{
    _car = car;
}
 
ok
 
now we depend on a concrete type
and all of a sudden, a Ford Fiesta won't work
all good?
 
I see what abstraction is meaning to have different types of objects of type (in this case) ICar . and yes
 
12:50 AM
now, ICar could be implemented by a LamborghiniCar or a FordFiestaCar
but we're interested in the Decorator pattern now
class SqueakyBrakesDecorator : ICar
{
    private readonly ICar _car;

    public SqueakyBrakesDecorator(ICar car) {
        _car = car;
    }

    public void Drive()
    {
        _car.Drive();
    }

    public void Stop()
    {
        Console.WriteLine("Squeeeeeeak!");
        _car.Stop();
    }

    public void Park()
    {
        _car.Park();
    }
}
This decorator decorates any ICar
 
oki
ok
 
when the Stop method is called, is squeaks
and it's implementing the ICar interface
 
Hello @SirPython
Alright
 
so the TestDrive method in the Foobar class above, doesn't care what the concrete type is, right?
 
right
 
12:53 AM
that's why the decorator pattern is cool: it implements the same interface it's extending
class SqueakyBrakesDecorator : ICar
{
    private readonly ICar _car;

    public SqueakyBrakesDecorator(ICar car) {
        _car = car;
    }
it implements ICar, and takes in an ICar dependency through its constructor
(yes, that's constructor injection)
 
That is cool
I mean kinda
 
so now you can do var car = new SqueakyBrakesDecorator(new VolksGolf());
and get a squeaking Golf
 
so the parameter for the injection will depend on the interface or class but interface in this decorator pattern
*in this case
**the
 
lol
arrow up == edit
consider this:
class SqueakyBrakesDecorator : LamborghiniCar
{
    private readonly LamborghiniCar _car;

    public SqueakyBrakesDecorator(LamborghiniCar car) {
        _car = car;
    }
not as flexible isn't it?
 
No because its concrete
 
12:58 AM
exactly
 
No abstraction
for the interface
 
if you had a public abstract class Car : ICar, it could work though
 
true but we want functionality right
right so then we can use abstraction for creating dynamic objects on the fly
via Dependency Injection
 
hmm not quite
 
correct ?
 
12:59 AM
you're thinking DI interception I think
it's similar, but something else
 
alright
 
DI interception is like an on-the-fly decorator, yes
but before you get into DI interception, you need to understand the decorator ;-)
 
Yes
very much so
 
so, the decorator implementation receives the interface it's extending as a constructor argument, and then in each of the methods of the interface, it's just calling the same method on the received object.
    public void Drive()
    {
        _car.Drive();
    }
the decorator has an opportunity to "decorate" the call with something that could happen before and/or after that call
public void Stop()
{
    Console.WriteLine("Squeeeeeeak!");
    _car.Stop();
}
like the squeaky brakes do
 
on what received object though ?
Not to be annoying
 
1:12 AM
    private readonly ICar _car;

    public SqueakyBrakesDecorator(ICar car) {
        _car = car;
    }
the _car
 
so the received object is the interface
or the implementiation of the interface
 
if you want to implement a decorator for the ICar interface, you need to implement the ICar interface, and receive an ICar object.
class SqueakyBrakesDecorator : ICar
{
    private readonly ICar _car;

    public SqueakyBrakesDecorator(ICar car) {
        _car = car;
    }
hence SqueakyBrakesDecorator implements ICar, and receives an ICar object
 
right
 
I don't like the "car" example much
 
me either
 
1:16 AM
imagine some ITextReaderService interface with a Read(Stream) method
public string Read(Stream stream)
{
    _service.Read(stream);
}
the "decorated" call could be logging stuff and then the decorator would be a "LoggingTextReaderService"
you see?
 
LoggingTextReaderService ? where did we get that from
 
I don't know, I just made that up
 
ohh i see
Well that it is a class right for the decorator pattern
 
really, decorator is a useful tool for breaking down responsibility
say you had this TextReaderService responsible for reading that Stream, catching IOException and logging them. You could argue that such a TextReaderService has too many responsibilities
so you strip it down to its simplest, and decorate it with other responsibilities implemented in their own class
 
I don't think i'll ever get this decorator pattern down
 
1:21 AM
lol
yes you will
 
You will.
 
alright
i'm listening
 
which part is unclear at this point?
 
responsibility
 
ah
you've heard of the Single Responsibility Principle?
 
1:23 AM
no
I have not
 
ok
an object should have a single responsibility
methods should do one thing
 
what type of single responsibility
methods yes one thing
 
well, for example, that TextReaderService is responsible for reading a text file.
Logging exceptions is not its concern
 
Alright makes sense
 
so you make a TextReaderService class that does just what it says it does. and then when you say "hey but I need to catch and log these exceptions!", you make a separate class that's responsible for that.
and that's where the decorator pattern comes into play
so you make a LoggingTextReaderService that implements the same interface as the TextReaderService (say, ITextReaderService), and takes one instance in its constructor
 
1:27 AM
or that is the LoggingTextReaderService
 
right
it could have its own dependency, on some ILogger
 
Or ITextReaderService
right
 
public LoggingTextReaderService(ITextReaderService service, ILogger logger)
{
    _service = service;
    _logger = logger;
}
and then it would "decorate" the Read call:
 
alright so we are just making different interfaces that depend on the class decorator
 
public string Read(Stream stream)
{
    try
    {
        _service.Read(stream);
    }
    catch(IOException exception)
    {
        _logger.Error(exception);
    }
}
 
1:31 AM
or on the decorator class i meant
 
from the outside, the decorator looks like just any other ITextReaderService
(or ICar if you will)
that's the key: it presents the exact same interface as the one it's extending
you already had that part right in your OP
 
what's op stand for again
 
original post
 
oh
 
you'll see that quite a lot on Stack Exchange ;-)
 
1:34 AM
haha
 
sometimes "OP" can also refer to the author of the original post
 
oh i see
 
Original Poster.
 
yeah. gets confusing.
 
Context helps.
 
1:35 AM
#NamingIsHard
 
haha that must be hard for the stackoverflow group
 
BTW, @noob1992, your question helped me learn what the decorator is.
 
and isn't ;-)
 
Yep.
 
@Hosch250 really
 
1:37 AM
Yeah, I pretty much only know DI.
I've done abstract factory, but it still has a tendency to slip.
I've seen builder.
 
abstract factory is a very, very useful pattern for DI
 
Well I think @Mat'sMug post for the comment had a lot to do with it i'm sure !
 
like, you can't really make a working real-world app with DI without abstract factory
 
Actually, I figured it out pretty much from the answer bodies.
 
i meant answer
 
1:38 AM
Yeah.
 
yeah that's what i meant
 
BTW, are you taking a Computer Science class?
 
yeah
No
 
Oh.
 
Abstract Factory is one; Builder is another creational design pattern - if you're curious I have an implementation here:
7
Q: Building an IDE, block by -- er, mock by mock

Mat's MugThe opening sentence of an answer I received in my previous post snowballed, and led to completely ditching the previous approach. Mocking my IDE with a MockFactory worked ok, ...for some values of "ok" - the more components needed to be involved, the messier the setup code was getting. So inste...

 
1:41 AM
its rather embarrassing to admin that self taught:(
 
I'm self-taught too
 
So am I.
 
quite a bunch of us are actually
 
Oh well then haha
 
LOL, we are all self taught.
Don't worry, the courses are imbecilic.
 
1:42 AM
lol
 
You'll learn more and better self-teaching.
 
Yeah that's why i'm here
 
You'll learn more and better self-teaching on Code Review
 
to be taught i mean
 
best place to learn IMO
 
1:43 AM
I've taken one course on introductory Java (mandatory), and I'm taking several IT-related course (I'm an IT major).
I learn more on CR than I do in class.
 
IMO ?
 
In My Opinion
but hey, I'm biased... I'm a mod
like, I'm here every day
(although... I was here every day before being elected a mod anyway)
 
I haven't taken one class in any related computer science classes . is that bad ?
I think it should be bad
 
No.
 
like really bad
 
1:44 AM
It is good.
 
Well I'll take that into consideration
 
In class, you would have to comment every line.
 
lol
 
anyway, all we ask is that you get your code to work as intended. Write real working code, put it up for review - you'll quickly see how awesome this community is :)
 
In class, you would have to write full pseudocode before you open your IDE.
 
1:45 AM
to be honest I almost hammer-closed your question as "hypothetical code"... I hate that Car example :(
 
(What I did was write my programs with the comment on every line, then paste the program into Word and delete the code, leaving the comments :P)
 
haaha
 
@Hosch250 that's so dumb
 
@Mat'sMug I never said it was smart. Don't blame me.
 
what would be nice, is teachers that can teach properly so you don't need to un-learn everything once you get into the real world
 
1:47 AM
real world what is that like
 
Tough. Like, I don't know.
 
so anyway, @june1992 - welcome to Code Review. Feel free to hop into The 2nd Monitor anytime to say hi, we're always there :)

 The 2nd Monitor

General discussion about codereview.stackexchange.com - Welcom...
 

last day (14 days later) »