java - Java中从Caterpillar到Butterfly的模型
问题描述
我最近在一次采访中被问到这个问题:
随时间改变行为的动物模型。
你能模拟一只蝴蝶吗?
- 蝴蝶会飞 * 蝴蝶不会发出声音
你能优化你的模型来解释从毛毛虫到蝴蝶的变态吗?
- 毛毛虫不会飞
- 毛毛虫可以走路(爬行)
我创建了一个具有顶级接口 ( Insect
) 的层次结构,该接口有 2 个扩展它的接口 ( GroundInsect
& FlyingInsect
)。然后我有Caterpillar
实施GroundInsect
和ButterFly
实施FlyingInsect
。但是,我无法想出变形部分的解决方案。下面是我的代码:
昆虫界面:
public interface Insect { }
飞虫接口:
public interface FlyingInsect extends Insect {
public boolean fly();
}
地虫界面:
public interface GroundInsect extends Insect {
// Walk/Crawl
public boolean walk();
}
毛毛虫类:
public class Caterpillar implements GroundInsect {
@Override
public boolean walk()
{
System.out.println("Caterpillar Walk method");
return true;
}
}
蝴蝶班:
public class Butterfly implements FlyingInsect {
@Override
public boolean fly() {
System.out.println("ButterFly Flying method");
return false;
}
}
解决方案
让我们保持示例简单并坚持您的初始方法。
首先,我将介绍一个描述各种昆虫的通用界面:
interface Insect {
boolean fly();
boolean walk();
boolean sound();
}
方法fly
,walk
表示sound
昆虫与其邻域之间可能的交互(取决于这些交互的性质,这些方法可能会有所不同并且涉及更多:返回复杂的响应、接受回调等)。
你的第一个蝴蝶只是接口的一些具体实现:
class Butterfly implements Insect {
boolean fly() { return true; }
boolean walk() { return true; }
boolean sound() { return false; }
}
现在让我们添加转换的能力。同样,通常有多种方法可以做到这一点,所以让我们坚持蝴蝶的例子。
假设我们想要一只毛毛虫,并且它的相关蝴蝶是一个单一的实体(我们不希望毛毛虫在蝴蝶已经在那里时仍然四处游荡)。
在这种情况下,我会将毛毛虫和蝴蝶都表示为一个类,并将其当前状态隐藏在其中。“毛毛虫状态”和“蝴蝶状态”都将包含不同的操作实现,这些操作在转换后应该改变。封闭实例会将其方法委托给当前状态。
class Butterfly implements Insect {
private Insect state = new CaterpillarState();
boolean fly() { return state.fly(); }
boolean walk() { return state.walk(); }
boolean sound() { return state.sound(); }
void transform() { state = new ButterflyState(); }
private class ButterflyState implements Insect {
boolean fly() { return true; }
boolean walk() { return true; }
boolean sound() { return false; }
}
private class CaterpillarState implements Insect {
boolean fly() { return false; }
boolean walk() { return true; }
boolean sound() { return true; }
}
}
该transform
方法代表了变态的触发器。
这里ButterflyState
并CaterpillarState
实现与Insect
外部类相同的接口。在一般情况下,我可能会为内部状态定义不同的接口。
推荐阅读
- frontend - 如何加快前端monorepo项目的搭建?
- linux - 如何自动安排要求用户输入的作业?
- c# - 有条件地忽略对象 JavascriptSerializer 中的属性字段
- node.js - Node js docker镜像的缩减
- angular - 将 Angular 通用应用程序部署到 Firebase 托管中的非根路径
- reactjs - REACTJSX - 在获取 api 时无法设置默认值来选择选项,未定义
- javascript - 顺序执行数组中的承诺 socket.io
- java - 如何在 JAVA 中打印三重三角形图案?
- laravel - 如何在 Laravel 8.0 中设置 API 路由?
- three.js - 如何获取片段着色器生成的图像(或纹理)