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要加強的能力就是對事情的抽象化,後面還有很長的路要走
我經營的論壇: 台論之星
塵世中一位載浮載沉之小小工程師