miiworld2
miiworld2

Reputation: 306

C# decorator pattern and wrapping issues

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

Answers (2)

code4life
code4life

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

Niyoko
Niyoko

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

Related Questions