Reputation: 306
I am having a problem wrapping my code return values. So basically I am trying to display the following output:
Morg, type, xy, paddle
My code is in C#, and based on my code below, these outputs are based on my return values which are in string. I'm using them in hope to test my program to see if it works. Well so far it works but not the way I want. I only get to display the type return value, but I can't seem to display the rest of it.
This is what it gives me.
type
But the one at the very top is the one I want to display as output. Not just the type.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication3
{
class Program
{
static void Main(string[] args)
{
MorgReader myMorg = new FileReader();
MorgReader myMorg2 = new MorgType(new MorgXY(new MorgMovement(new FileReader())));
Console.WriteLine(myMorg.Read());
Console.WriteLine(myMorg2.Read());
}
}
// THE MAIN ABSTRACT CLASS //
abstract class MorgReader
{
public abstract string Read();
}
// THE CLASS THAT WILL READ THE FILE //
class FileReader : MorgReader
{
public override string Read()
{
return "Morg";
}
}
// MY READER DECORATOR //
abstract class ReaderDecorator : MorgReader
{
private MorgReader wrappedReader;
protected ReaderDecorator(MorgReader wrapped)
{
wrappedReader = wrapped;
}
protected MorgReader WrappedReader
{ get { return wrappedReader; } }
}
class MorgType : ReaderDecorator
{
public MorgType(MorgReader wrapped) : base(wrapped)
{ }
public override string Read()
{
return "type";
}
}
class MorgXY : ReaderDecorator
{
public MorgXY(MorgReader wrapped) : base(wrapped)
{ }
public override string Read()
{
return "x,y";
}
}
class MorgMovement : ReaderDecorator
{
public MorgMovement(MorgReader wrapped) : base(wrapped)
{ }
public override string Read()
{
return "paddle";
}
}
}
Upvotes: 1
Views: 322
Reputation: 15794
I think that your decorator pattern is missing... well, decorations (LOL). So decorate your abstract class descendants, like so:
class MorgType : ReaderDecorator
{
public MorgType(MorgReader wrapped) : base(wrapped)
{ }
public override string Read()
{
return WrappedReader == null ? "type" : WrappedReader.Read() + ",type";
}
}
class MorgXY : ReaderDecorator
{
public MorgXY(MorgReader wrapped) : base(wrapped)
{ }
public override string Read()
{
return WrappedReader == null ? "x,y" : WrappedReader.Read() + ",x,y";
}
}
class MorgMovement : ReaderDecorator
{
public MorgMovement(MorgReader wrapped) : base(wrapped)
{ }
public override string Read()
{
return WrappedReader == null ? "paddle" : WrappedReader.Read() + ",paddle";
}
}
And you should see the result that you are expecting for myMorg2
, which was a comma-delimited output that you described in your post.
Upvotes: 1
Reputation: 7672
Change your ReaderDecorator
class
abstract class ReaderDecorator : MorgReader
{
private MorgReader wrappedReader;
protected ReaderDecorator(MorgReader wrapped)
{
wrappedReader = wrapped;
}
protected MorgReader WrappedReader
{ get { return wrappedReader; } }
public override string Read()
{
var wrapped = WrappedReader.Read();
if (!string.IsNullOrEmpty(wrapped))
wrapped += ", ";
return wrapped + ReadImpl();
}
// template method
protected abstract string ReadImpl();
}
Implement ReadImpl
in concrete class like this
class MorgType : ReaderDecorator
{
public MorgType(MorgReader wrapped) : base(wrapped)
{ }
protected override string ReadImpl()
{
return "type";
}
}
If you don't want to introduce ReadImpl
method, then you should override Read
method in every concrete class like this
public override string Read()
{
var wrapped = WrappedReader.Read();
if (!string.IsNullOrEmpty(wrapped))
wrapped += ", ";
return wrapped + "type";
}
Upvotes: 2