Jesper Jensen
Jesper Jensen

Reputation: 595

Interface implementation in to my project

STARTING QUESTION

My general understanding of Interfaces is fine, I’ve read hundreds of examples and different articles on this subject but I’m still on a hold, because all this reading still hasn't given me an answer to where to use this tool in my own project.

I'll try to come with a concrete example from my project on where I probably would have benefits from using Interfaces and hopefully someone could give me a concrete answer on how I should implement it.

My purpose with this project was to draw an image in A4 size and preview it in a PictureBox (resized) and then have a GUI to create and move a barcode (with a caption text underneath) on this image in the PictureBox.

Now I want to be able to draw another text object with same functionalities to move it around and show on the preview. But this will be a normal text and therefore it would have a different font and no caption. This could easily be done with a collection and a loop when drawing.

But what if I want to add more objects to this image, wouldn't it be a lot easier to maintain and extent, if I used Interfaces? I would also like to elaborate my programming, by learning how to use something a little bit more complex.

CURRENT APPROACH TO A SOLUTION

My main Interface

public interface IElementCreator
{
    int posX { get; set; }
    int posY { get; set; }
    StringFormat format { get; set; }
    string value { get; set; }
    Font font { get; set; }
    bool caption { get; set; }
    Font captionFont { get; set; }
}

My main class for creating an element

public class ElementBase : IElementCreator, IImageUpdater
{
    #region IElementCreator Variables

    private int _posX;
    private int _posY;
    private StringFormat _format;
    private string _value;
    private Font _font;
    private bool _caption;
    private Font _captionFont;

    #endregion

    #region IElementCreator Members

    public int posX
    {
        get { return _posX; }
        set { _posX = value; }
    }

    public int posY
    {
        get { return _posY; }
        set { _posY = value; }
    }

    public StringFormat format
    {
        get { return _format; }
        set { _format = value; }
    }

    public string value
    {
        get { return _value; }
        set { _value = value; }
    }

    public Font font
    {
        get { return _font; }
        set { _font = value; }
    }

    public bool caption
    {
        get { return _caption; }
        set { _caption = value; }
    }

    public Font captionFont
    {
        get { return _captionFont; }
        set { _captionFont = value; }
    }

    #endregion

    #region Constructor

    public ElementBase(int posX, int posY, StringFormat format, string value, Font font, bool caption, Font captionFont)
    {
        this.posX = posX;
        this.posY = posY;
        this.format = format;
        this.value = value;
        this.font = font;
        this.caption = caption;
        this.captionFont = captionFont;
    }

    #endregion

    public Image updatePreview(IElementCreator element, Image img)
    {
    }
}

Interface to update the preview image

public interface IImageUpdater
{
    Image updatePreview(IElementCreator element, Image img);
}

I've not been able to test this yet, I've made the code and I'll start testing later.

What I'm trying to achieve, is to have an interface to handle the creation of a basic text element. With this it should be possible to extent with new classes to handle text elements with different settings.

This is just a starting point and I know some code are missing for everything to make sence, but I just want to share and make sure that i'm not completely of track.

Upvotes: 2

Views: 877

Answers (2)

Sebastian Siek
Sebastian Siek

Reputation: 2075

What you could do if have a class which is responsible for creating image

public class ImageCreator : IImageCreator
{
    public Image CreatePreviewImg(string value, int fontSize, int x, int y)
    {
        //Your code goes here...
    }
}

then whenever you want to generate an image you could create an instance of image creator

IImageCreator imageCreator = new ImageCreator;
var preview = imageCreator.CreatePreviewImg(...);

thanks to this approach you could have multiple image creators implementing IImageCreator interface and your manager would decide which one to use.

Hope that give you an idea how to use interface in your project.

UPDATE *LATEST UPDATE AS OF 09/02/2012*

here's how the interface should look like

public interface IImageCreator
{
    public Image CreatePreviewImg(string value, int fontSize, int x, int y);
}

as soon as you implement interface to your class, you will have to write code for that method. so your class would look like :

this is your image item - an object you will pass to image creator (this object contains all values you need to generate an image) and it's interface below

    public class ImageSettings : IImageSettings 
    {
        public int posX { get; set; }
        public int posY { get; set; }
        public StringFormat format { get; set; }
        public string value { get; set; }
        public Font font { get; set; }
        public bool caption { get; set; }
        public Font captionFont { get; set; }
    }

    public interface IImageSettings 
    {
        int posX { get; set; }
        int posY { get; set; }
        StringFormat format { get; set; }
        string value { get; set; }
        Font font { get; set; }
        bool caption { get; set; }
        Font captionFont { get; set; }
    }


    public class ImageCreator : IImageCreator
    {

THIS IS NEW METHOD WHICH ACCEPTS TYPE OF AN INTERFACE INSTEAD OF PARAMS

        public Image CreatePreviewImg(IImageSettings imageSettings)
        {
            //ALL THE MAGIC HAPPENS HERE
        }

THIS IS THE OLD METHOD - NO LONGER REQUIRED public Image CreatePreviewImg(string value, int fontSize, int x, int y) { // Iniziate barcode font
PrivateFontCollection private_fonts = new PrivateFontCollection(); private_fonts.AddFontFile("FREE3OF9.TTF");

            //Image size A4 at 300dpi     
            Bitmap bm = new Bitmap(width, height);
            bm.SetResolution(300, 300);

            // Create rectangle for the canvas     
            RectangleF rectBg = new RectangleF(0, 0, width, height);

            // Load fonts     
            Font bcFont = new Font(private_fonts.Families[0], fontSize, FontStyle.Regular, GraphicsUnit.Point);
            Font valueFont = new Font("Tahoma", 12, FontStyle.Regular, GraphicsUnit.Point);

            // Set StringFormat for the text value     
            StringFormat sfValue = new StringFormat();
            sfValue.LineAlignment = StringAlignment.Far;
            sfValue.Alignment = StringAlignment.Center;

            // Set StringFormat for the barcode string     
            StringFormat sfBarcode = StringFormat.GenericTypographic;
            sfBarcode.FormatFlags = StringFormatFlags.NoClip;

            using (Graphics g = Graphics.FromImage(bm))
            {
                // Create rectangle to place the barcode and text     
                SizeF bcStringSize = g.MeasureString("*" + value + "*", bcFont);
                SizeF valueSize = g.MeasureString(value, valueFont);
                RectangleF recText = new RectangleF(x, y, (float)MeasureDisplayStringWidth(g, "*" + value + "*", bcFont), (float)(bcStringSize.Height + valueSize.Height));

                // Drawing the barcode and text     
                g.SmoothingMode = SmoothingMode.AntiAlias;
                g.TextRenderingHint = TextRenderingHint.AntiAlias;
                g.FillRectangle(new SolidBrush(Color.White), rectBg);
                g.DrawString("*" + value + "*", bcFont, new SolidBrush(Color.Black), recText, sfBarcode);

                g.DrawString(value, valueFont, new SolidBrush(Color.Black), recText, sfValue);
            }

            return bm;
        }
    }

Upvotes: 1

Security Hound
Security Hound

Reputation: 2551

But what if I want to add more objects to this image, wouldn't it be a lot easier to maintain and extent, if I used Interfaces? I would also like to elaborate my programming, by learning how to use something a little bit more complex.

That entirely depends if you are going to have multiple classes that implement the interface.

I see nothing in your code code that would warrent an interface. Have you considered reading a book on how to program in C# by chance? Reading examples is a horrible way of learning how to program, you need to understand the correct way to program, and often time that only comes from books written by people in the industry with decades worth of experience.

Upvotes: 0

Related Questions