Amazon Interview Question
Software Engineer / DevelopersCountry: -
Interview Type: Phone Interview
@Anonymous: For abstract factory implementation, we can refer to implementation at www dot allapplabs dot com.
class RawMaterial {
private boolean isWooden;
private boolean isMetallic;
private boolean isPlastic;
public RawMaterial(boolean isWooden, boolean isMetallic, boolean isPlastic) {
this.isPlastic = isPlastic;
this.isWooden = isWooden;
this.isMetallic = isMetallic;
}
//provide set/get methods for 3 variables here
}
class Dimension{
private double length;
private double breadth;
private double height;
public RawMaterial(double length, double breadth,double height) {
this.length = length;
this.breadth = breadth;
this.height = height;
}
//provide set/get methods for 3 variables here
}
class Table {
private RawMaterial rawMaterial;
private Dimension dimension;
private int id;
private String details; //info abt this table
public Table(int id, String details){
this.id = id;
this.details = details;
}
// provide setter and getter for rawMaterial, id, details
}
// Similarly have Chair, Bench classes here and
// provide fields and set/get methods here
If you have Room class, Table, Chair, Bench will become composite objects of Room [have hashtable of Tables, methods like addTable(id, details), addChair(id, details) etc...
your second class 'dimension' has public rawmaterial...I guess it was a constructor and hence should have been named dimension...but its too small of an issue.. I guess everyone reading this knows that :)
Nice.
public abstract class Furniture
{
int length;
int breadth;
int height;
RawMaterial type;
}
class Table extends Furniture
{
}
class Chair extends Furniture
{
}
enum RawMaterial
{
WOOD,METAL,PLASTIC;
}
Decorates will be useful when u are trying to extend some property of object not modify, here we might need totally different implementation for these products. The answers to this question might be very specific depending on interviewers thinking, but to start with one suggest a generic class:
class Furniture<Material>{
}
Now extend this class to support product specific requirements.
let me layout an idea here.
Please read through the complete solution patiently.
We will define a high level class called "part".
Now every part will have a list of pointers to other "parts".
The "part" class will have an evaluate function
which will evaluate the entire part (part and its sub parts)
based on its atributes,dimensions,etc.
class part
{
char* inputMaterial;
part* subparts[10];
void Evaluate();/*Evaluates a part and the sub part*/
}
class chair : part
{
int _height;
int _base_length;
int base_width;
chair(char* material,char* config_string /*"seat backrest leg1 leg2"*/)
{
if(material=="plastic")
{
_height=20;
_base_length=40;
_base_width=60;
if(config_string.Substr("seat")
{
table->subparts[0]=new seat("plastic",_base_length,_base_width);
}
if(config_string.Substr("backrest")
{
table->subparts[1]=new backrest("plastic",_height);
}
if(config_string.Substr("leg1"))
{
table->subpart[2]=new leg1("plastic",(_height/2));
}
if(config_string.Substr("leg2"))
{
table->subpart[3]=new leg2("plastic",(_height/2));
}
if(config_string.Substr(""))
{
}
}
class seat :part
{
seat()
{
/*uses interface material to source plastic beams */
}
}
The key thing to note here:
1) The type is defined at run time,what class type defines chair:
a chair is an object of type: seat,backrest and two legs.
Note that based on user input we will decide the type of chair will not constitute armrests.
2) the "part" is an atomic entity that helps you define your type. So your chair type is defined
in terms of a collection /set of parts
3) why create run time types ?
It helps you set a policy for evaluating constraints. For. (E.g). you could create constraints across sub parts
( In the above example, the length of legs could be twice the height used for backrest). and.. you could create
constraints from parents to children ( from chair to leg,leg's position =chair's position + (30,40,50) )
now lets say we modify the chair's position, we obviously evaluate the chair,now becoz the legs are part of my chair
(our type definition for chair: seat,backrest and two legs) the legs move along with my chair.
you don't have to evaluate the legs separately, they have already moved !!
But if you modify the backrest's height, of course the legs constraints say the leg's height will also have to change.
a modify of backrest will trigger evaluate on backrest. This DOES NOT CHANGE the leg's height.
The leg's height will change only when either the leg is evaluated or when the whole chair is evaluated.
In practical scenarios, this lets some one working on the "leg" module to continue until he is "ready" to accept the update
changes from outside (in this case , the backrest)
Its' long., but hope it makes sense. I dont understand why amazon asks these questions!
Create an interface for Type of furniture as :
public abstract rawMaterialType{
private boolean ismetal;
private boolean isWood;
...........
//create public getters/setters for the above
}
Now create three concrete classes (for individual objects like table, chair, etc) which extends the above rawMaterialType class and .assign the corresponding raw material typr to each object instantiated form the second class.
public abstract class Furniture {
String color = "";
String price = "";
}
public abstract class PlasticFurniture extends Furniture {
}
public abstract class WoodenFurntiure extends Furniture {
}
public class PlasticChair extends PlasticFurniture {
public PlasticChair(String col, String p) {
color = col;
price = p;
}
}
public class WoodenChair extends WoodenFurntiure {
public WoodenChair(String col, String p) {
color = col;
price = p;
}
}
public abstract class FurnitureFactory {
public abstract Furniture createChair();
public abstract Furniture createTable();
}
//
public class WoodenFurnitureFactory extends FurnitureFactory {
@Override
public Furniture createChair() {
return new WoodenChair("Red","1000");
}
@Override
public Furniture createTable() {
return new WoodenTable("Red","1000");
}
}
//
public class PlasticFurnitureFactory extends FurnitureFactory {
@Override
public Furniture createChair() {
return new PlasticChair("Red","1000");
}
@Override
public Furniture createTable() {
return new PlasticTable("Red","1000");
}
}
public class FurnitureMakerFactory {
private static FurnitureFactory factory = null;
static FurnitureFactory getFactory(String choice) {
if (choice.equals("wooden")) {//TODO: create a Constant file
factory = new WoodenFurnitureFactory();
} else if (choice.equals("plastic")) {
factory = new PlasticFurnitureFactory();
}
return factory;
}
}
//client
public class Client {
public static void main(String[] args) {
FurnitureFactory pf=FurnitureMakerFactory.getFactory("wooden");
Furniture product=pf.createChair();
}
}
public abstract class Furniture {
String color = "";
String price = "";
}
public abstract class PlasticFurniture extends Furniture {
}
public abstract class WoodenFurntiure extends Furniture {
}
public class PlasticChair extends PlasticFurniture {
public PlasticChair(String col, String p) {
color = col;
price = p;
}
}
public class WoodenChair extends WoodenFurntiure {
public WoodenChair(String col, String p) {
color = col;
price = p;
}
}
public abstract class FurnitureFactory {
public abstract Furniture createChair();
public abstract Furniture createTable();
}
//
public class WoodenFurnitureFactory extends FurnitureFactory {
@Override
public Furniture createChair() {
return new WoodenChair("Red","1000");
}
@Override
public Furniture createTable() {
return new WoodenTable("Red","1000");
}
}
//
public class PlasticFurnitureFactory extends FurnitureFactory {
@Override
public Furniture createChair() {
return new PlasticChair("Red","1000");
}
@Override
public Furniture createTable() {
return new PlasticTable("Red","1000");
}
}
public class FurnitureMakerFactory {
private static FurnitureFactory factory = null;
static FurnitureFactory getFactory(String choice) {
if (choice.equals("wooden")) {//TODO: create a Constant file
factory = new WoodenFurnitureFactory();
} else if (choice.equals("plastic")) {
factory = new PlasticFurnitureFactory();
}
return factory;
}
}
//client
public class Client {
public static void main(String[] args) {
FurnitureFactory pf=FurnitureMakerFactory.getFactory("wooden");
Furniture product=pf.createChair();
}
}
public abstract class Furniture {
String color = "";
String price = "";
}
public abstract class PlasticFurniture extends Furniture {
}
public abstract class WoodenFurntiure extends Furniture {
}
public class PlasticChair extends PlasticFurniture {
public PlasticChair(String col, String p) {
color = col;
price = p;
}
}
public class WoodenChair extends WoodenFurntiure {
public WoodenChair(String col, String p) {
color = col;
price = p;
}
}
public abstract class FurnitureFactory {
public abstract Furniture createChair();
public abstract Furniture createTable();
}
//
public class WoodenFurnitureFactory extends FurnitureFactory {
@Override
public Furniture createChair() {
return new WoodenChair("Red","1000");
}
@Override
public Furniture createTable() {
return new WoodenTable("Red","1000");
}
}
//
public class PlasticFurnitureFactory extends FurnitureFactory {
@Override
public Furniture createChair() {
return new PlasticChair("Red","1000");
}
@Override
public Furniture createTable() {
return new PlasticTable("Red","1000");
}
}
public class FurnitureMakerFactory {
private static FurnitureFactory factory = null;
static FurnitureFactory getFactory(String choice) {
if (choice.equals("wooden")) {//TODO: create a Constant file
factory = new WoodenFurnitureFactory();
} else if (choice.equals("plastic")) {
factory = new PlasticFurnitureFactory();
}
return factory;
}
}
//client
public class Client {
public static void main(String[] args) {
FurnitureFactory pf=FurnitureMakerFactory.getFactory("wooden");
Furniture product=pf.createChair();
}
}
I think in this case the decorate design pattern will be a good choice to design the class structure. Make table, chair and bench as subclasses of a common superclass, and wood, metal and plastic as decorators.
It's tempting to make a simple model of abstract product where material is modeled as enum. However, a more complicate URL is abstract factory. This is depends on functions the interviewer want. If all function is material cost, the enum is sufficient. If there are more than just a cost such as strength, assemble manual, etc. or you might want to have sale a patio set. Then, abstract factory is a better choice.
- Anonymous September 23, 2011