Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Add more behaviour without creating new classes

This was the question asked in an interview.

There is a Label with a property Text
In one page a label is simple Label, in other pages it may handle any one or combination of the below actions
Clickable
Resizable
Draggable

How do you design this label component that applies OOP design Principle & Design Pattern?

I said that I would create the following:

public class Label
{
  public string Text{get;set;}
}
public interface IClickable
{
 void Click();
}

public interface IDraggable
{
 void Drag();
}
public interface IResizable
{
 void Resize();
}

So that if the client want Resizable Label

public class ResizableLabel:Label,IResizable
{
  ....
}

same way ClickableLable, DraggableLabel

However, I feel that this is the incorrect approach, because I do not want to add those concrete classes. I want to avoid having ClickableAndDraggableLabel or ClickableDraggableResizableLabel.

Is there any design pattern that would solve this problem without adding these concrete classes?

like image 269
Billa Avatar asked Apr 19 '13 07:04

Billa


People also ask

What are the three behavioral patterns?

Design patterns are divided into three fundamental groups: Behavioral, Creational, and. Structural.

What would you do to get the Behaviour of decorator classes?

Decorator design pattern allows us to dynamically add functionality and behavior to an object without affecting the behavior of other existing objects within the same class. We use inheritance to extend the behavior of the class.

What kind of pattern makes objects behave differently based on different contexts?

Today's pattern is the State pattern, which allows objects to behave in different ways depending on internal state. State is used when you need a class to behave differently, such as performing slightly different computations, based on some arguments passed through to the class.


1 Answers

I would use Decorator pattern. It is used extensivelly in .net world for different kind of streams, that allow you to compose encrypted, zipped, text stream wrappers for byte stream, for example. class diagram is taken from wiki

enter image description here

Example for you situation is not so trivial in implementation, but usage doen't require another classes for new compising behavior:

// Define other methods and classes here
public class Label
{
    public string Text{get;set;}

    public virtual void MouseOver(object sender, EventArgs args) { /*some logic*/ }
    public virtual void Click(object sender, EventArgs args) {  /*some logic*/ }

    //other low level events
}

public class ClikableLabel : Label
{
    private Label _label;

    public ClikableLabel(Label label)
    {
        _label = label; 
    }

    public override void Click(object sender, EventArgs args) 
    {   
        //specific logic
        _label.Click(sender, args);
    }
}

public class DraggableLabel : Label
{
    private Label _label;

    public DraggableLabel(Label label)
    {
        _label = label; 
    }

    public override void Click(object sender, EventArgs args) 
    {   
        //specific logic
        _label.Click(sender, args);
    }
}
public class ResizableLabel : Label
{
    private Label _label;

    public ResizableLabel(Label label)
    {
        _label = label; 
    }

    public override void MouseOver(object sender, EventArgs args) 
    {   
        //specific logic
        _label.MouseOver(sender, args);
    }

    public override  void Click(object sender, EventArgs args) 
    {
        //specific logic
        _label.Click(sender, args);
    }
}

now you can

var clickableDragableLabel = new ClikableLabel(new DraggableLabel(new Label{Text = "write me!"}));

var makeItResizable = new ResizableLabel(clickableDragableLabel);
like image 98
Ilya Ivanov Avatar answered Nov 15 '22 13:11

Ilya Ivanov