I found this question in Glassdoor and CareerCup, this is an OOP design question.
Many people claim to have solved it using different design patterns.
I think It can be solved either with bridge pattern or decorator pattern.
In the original question the base class is derived by 4 classes: 1. WoodChair
2. WoodTable
3. MetalChair
4. MetalTable
Can you please say:
Which design pattern will you use? or how (don't have to use a design pattern)
Original Question:
You are on a team that is creating a program to model stress on furniture. Your task is to model the behavior of furniture under abuse such as excessive weight or application of fire.
Someone has already created a prototype with a base class
Furniture
, and four derived classesWoodChair
,SteelChair
,WoodTable
, andSteelTable
.We will need to start adding other furniture like couches, beds, bookcases, and desks, and also new materials such as plastic, cloth, rubber, etc. Try to improve the class design - you are free to modify it however you wish since it is only a prototype.
applyWeight(double x, double y, double weight, double seconds);
the furniture becomes unusable if enough weight is applied; the algorithm depends on shape of furniture, and the location where the weight is applied
applyFire(double x, double y, double fireStrength, double seconds);
the furniture becomes unusable if it is made of wood, and fire is applied long enough; wood will change from brown to black if it is burnt (whether or not the furniture becomes unusable)
Color getColor(); // possible values: Gray, Brown, Black, etc FurnitureState getState(); // possible values: OK, UNUSABLE<br>
Please comment on my implementation of the decorator Pattern. And OOP design.
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace JobInterviewTests
{
[TestClass]
public class DecoratorPatternTest
{
[TestMethod]
public void DecoratorPatternUnitTest()
{
Furniture temp = new BaseChair();
temp = new WoodDecorator(temp,10);
temp.applyFire(0, 0, 20, 10);
Assert.AreEqual(Color.Black, temp.getColor());
}
}
public abstract class Furniture
{
protected Color _color;
protected FurnitureState _state = FurnitureState.OK;
protected double _breakThreshold;
public abstract void applyWeight(double x, double y, double weight, double seconds);
public abstract void applyFire(double x, double y, double fireStrength, double seconds);
public Color getColor()
{
return _color;
}
public FurnitureState getState()
{
return _state;
}
}
public enum FurnitureState
{
OK,
UNUSABLE
}
public enum Color
{
Gray,
Brown,
Black
}
public class BaseChair : Furniture
{
public BaseChair()
{
_color = Color.Brown;
_breakThreshold = 10.0;
}
public override void applyWeight(double x, double y, double weight, double seconds)
{
if (x * y * weight * seconds > _breakThreshold)
{
_state = FurnitureState.UNUSABLE;
}
}
public override void applyFire(double x, double y, double fireStrength, double seconds)
{
}
}
public class BaseTable : Furniture
{
public BaseTable()
{
_color = Color.Gray;
_breakThreshold = 15.0;
}
public override void applyWeight(double x, double y, double weight, double seconds)
{
if (x * y * weight * seconds > _breakThreshold)
{
_state = FurnitureState.UNUSABLE;
}
}
public override void applyFire(double x, double y, double fireStrength, double seconds)
{
}
}
public abstract class BaseDecorator : Furniture
{
Furniture _furniture = null;
protected BaseDecorator(Furniture furniture)
{
_furniture = furniture;
}
public override void applyFire(double x, double y, double fireStrength, double seconds)
{
_furniture.applyFire(x, y, fireStrength, seconds);
}
public override void applyWeight(double x, double y, double weight, double seconds)
{
_furniture.applyFire(x, y, weight, seconds);
}
}
public class WoodDecorator : BaseDecorator
{
double _fireThreshold;
public WoodDecorator(Furniture furniture, double fireThreshold)
: base(furniture)
{
_fireThreshold = fireThreshold;
}
public override void applyFire(double x, double y, double fireStrength, double seconds)
{
if (x + y + fireStrength * seconds > _fireThreshold)
{
_color = Color.Black;
}
base.applyFire(x, y, fireStrength, seconds);
}
}
}