[JAVA]JAVA面試題目-寫出一個微波爐

JAVA面試題目-寫出一個微波爐

在網路上閒逛

看到這道JAVA的面試題目

用JAVA寫一個微波爐,注意物品正加熱時不能開門,帶皮帶殼食物不能被加熱。(用oop的思維撰寫)

所以手癢實作了這一道題目

既然是微波,那最多的大概就是食物了吧

1. 寫一個食物類別

public class Food {
	private String name = "";
	private boolean shell = false;
	private boolean skin = false;
	
	public Food(String name) {
		super();
		setName(name);
	}
	
	public String getName() {
		return name;
	}
	
	public void setName(String name) {
		this.name = name;
	}
	
	public boolean isShell() {
		return shell;
	}
	
	public void setShell(boolean shell) {
		this.shell = shell;
	}
	
	public boolean isSkin() {
		return skin;
	}
	
	public void setSkin(boolean skin) {
		this.skin = skin;
	}
}

類別中只有很簡單的名字和帶皮帶殼

2. 寫一個加熱的介面(策略模式)

public interface Heating {
	public void start(Food food) throws Exception;
}

會開這個介面是因為想要把加熱的部分從微波爐中抽離出來

這樣可以更動態的去替換加熱方式

3. 寫一個微波爐的介面

public interface Microwave {
	public boolean open();
	public boolean putFood(Food food);
	public Food getFood();
	public boolean close();
	public boolean startHeating();
}

把一整套流程各自拆成五個method

4. 寫一個狀態控制器類別和微波爐狀態介面(狀態模式)

public class MicrowaveContext {
	private MicrowaveState state = null;
	
	public MicrowaveContext(MicrowaveState state){
		this.state = state;
	}
 
	public void setState(MicrowaveState state) {
		this.state = state;
	}
 
	public void push() {
		state.push(this);
	}
 
	public void pull(){
		state.pull(this);
	}
	
	public boolean canOpen(){
		return state.canOpen();
	}
	
	public boolean canClose(){
		return state.canClose();
	}
	
	public boolean canPutFood(){
		return state.canPutFood();
	}
	
	public boolean canGetFood(){
		return state.canGetFood();
	}
	
	public boolean canHeating(){
		return state.canHeating();
	}
}

對應著五個動作的檢查,和狀態的切換method

public interface MicrowaveState {
	public void push(MicrowaveContext c);
	public void pull(MicrowaveContext c);
	public boolean canOpen();
	public boolean canClose();
	public boolean canPutFood();
	public boolean canGetFood();
	public boolean canHeating();
}

5. 寫第一種狀態

public class MicrowaveStepOne implements MicrowaveState {
 
	@Override
	public void push(MicrowaveContext c) {
		c.setState(new MicrowaveStepTwo());
	}
 
	@Override
	public void pull(MicrowaveContext c) {
		c.setState(new MicrowaveStepThree());
	}
 
	@Override
	public boolean canOpen() {
		return true;
	}
 
	@Override
	public boolean canClose() {
		return false;
	}
 
	@Override
	public boolean canPutFood() {
		return false;
	}
	
	@Override
	public boolean canGetFood() {
		return false;
	}
 
	@Override
	public boolean canHeating() {
		return false;
	}
 
}

除了開門其他都不允許

6. 寫第二種狀態

public class MicrowaveStepTwo implements MicrowaveState {
 
	@Override
	public void push(MicrowaveContext c) {
		c.setState(new MicrowaveStepThree());
	}
 
	@Override
	public void pull(MicrowaveContext c) {
		c.setState(new MicrowaveStepOne());
	}
 
	@Override
	public boolean canOpen() {
		return false;
	}
 
	@Override
	public boolean canClose() {
		return true;
	}
 
	@Override
	public boolean canPutFood() {
		return true;
	}
	
	@Override
	public boolean canGetFood() {
		return false;
	}
 
	@Override
	public boolean canHeating() {
		return false;
	}
 
}

能關門能放食物

7. 寫第三種狀態

public class MicrowaveStepThree implements MicrowaveState {
 
	@Override
	public void push(MicrowaveContext c) {
		c.setState(new MicrowaveStepFour());
	}
 
	@Override
	public void pull(MicrowaveContext c) {
		c.setState(new MicrowaveStepTwo());
	}
 
	@Override
	public boolean canOpen() {
		return false;
	}
 
	@Override
	public boolean canClose() {
		return true;
	}
 
	@Override
	public boolean canPutFood() {
		return false;
	}
	
	@Override
	public boolean canGetFood() {
		return true;
	}
 
	@Override
	public boolean canHeating() {
		return false;
	}
 
}

能關門能取出食物

8. 寫第四種狀態

public class MicrowaveStepFour implements MicrowaveState {
 
	@Override
	public void push(MicrowaveContext c) {
		c.setState(new MicrowaveStepFive());
	}
 
	@Override
	public void pull(MicrowaveContext c) {
		c.setState(new MicrowaveStepThree());
	}	
 
	@Override
	public boolean canOpen() {
		return true;
	}
 
	@Override
	public boolean canClose() {
		return false;
	}
 
	@Override
	public boolean canPutFood() {
		return false;
	}
 
	@Override
	public boolean canGetFood() {
		return false;
	}
 
	@Override
	public boolean canHeating() {
		return true;
	}
 
}

能開能加熱

8. 寫第五種狀態

public class MicrowaveStepFive implements MicrowaveState {
 
	@Override
	public void push(MicrowaveContext c) {
		c.setState(new MicrowaveStepOne());
	}
 
	@Override
	public void pull(MicrowaveContext c) {
		c.setState(new MicrowaveStepFour());
	}
 
	@Override
	public boolean canOpen() {
		return false;
	}
 
	@Override
	public boolean canClose() {
		return false;
	}
 
	@Override
	public boolean canPutFood() {
		return false;
	}
 
	@Override
	public boolean canGetFood() {
		return false;
	}
 
	@Override
	public boolean canHeating() {
		return false;
	}
 
}

甚麼都不能做

以上五種狀態代表的就是使用微波爐的一整套流程

9. 實作加熱介面

public class NormalHeating implements Heating {
 
	@Override
	public void start(Food food) throws Exception {
		if (food == null)
			throw new Exception("Please put the food in a microwave oven.");
		
		if (food.isShell() || food.isSkin())
			throw new Exception("The food with a shell or skin.");
		
		System.out.println("Heating success.");
	}
}

這邊可以依據需求來創造很多種加熱方式

10. 實作微波爐介面

public class NormalMicrowave implements Microwave {
	MicrowaveContext context = null;
	Heating heating = null;
	Food food = null;
 
	public NormalMicrowave() {
		super();
		this.heating = new NormalHeating();
		this.context = new MicrowaveContext(new MicrowaveStepOne());
	}
 
	public NormalMicrowave(Heating heating) {
		super();
		this.heating = heating;
		this.context = new MicrowaveContext(new MicrowaveStepOne());
	}
	
	@Override
	public boolean open() {
		if (context.canOpen() && this.food != null) {
			context.pull();
			return true;
		} else if (context.canOpen() && this.food == null) {
			context.push();
			return true;
		}
 
		return false;
	}
 
	@Override
	public boolean putFood(Food food) {
		if (context.canPutFood()) {
			context.push();
			this.food = food;
			return true;
		}
 
		return false;
	}
 
	@Override
	public Food getFood() {
		if (context.canGetFood()) {
			context.pull();
			Food food = this.food;
			this.food = null;
			return food;
		}
 
		return null;
	}
 
	@Override
	public boolean close() {
		if (context.canClose() && this.food != null) {
			context.push();
			return true;
		} else if (context.canClose() && this.food == null) {
			context.pull();
			return true;
		}
 
		return false;
	}
 
	@Override
	public boolean startHeating() {
		try {
			if (context.canHeating()) {
				context.push();
				heating.start(this.food);
				context.push();
			}else{
				return false;
			}
		} catch (Exception e) {
			System.out.println(e.getMessage());
			return false;
		}
 
		return true;
	}
}

============================================

我認為最難設計的就是狀態的部分

對應流程的push跟pull並非都一樣

單看程式碼要熟悉整套的運作是有那麼點困難

這還是因為只有五個狀態...更多的話大概只能用執行的方式來確認狀態的轉換

物件導向的寫作方式真的很..繁瑣

花的時間也比直接寫來的多

不過知道怎麼去設計之後,能力提高的程度是非常大的

想要學好OOP要加強的能力就是對事情的抽象化,後面還有很長的路要走

我經營的論壇: 台論之星

塵世中一位載浮載沉之小小工程師

michael-chen@jiebu-lang.com