我有一个表示水果的枚举类:
public enum Fruit{
//实例个数不会太多
APPLE,ORANGE,MANGO;
}
现在我需要三个接口(只是举例,可能更多)用来获取水果的信息,现有两种设计:
第一种:
提供一个类FruitInfo,提供三个方法,每一个根据传入的水果类型来进行不同的处理: public class FruitInfo{
public String getShape(Fruit fruit){
//下边的代码则是根据不同的fruit返回不同的形状
}
public String getColor(Fruit fruit){
//下边的代码则是根据不同的fruit返回不同的颜色
}
public String getPrice(Fruit fruit){
//下边的代码则是根据不同的fruit返回不同的价格
}
第二种:
提供一个接口FruitInfo,它有三个方法分别是getShape(),getColor(),getPrice()
然后它有三个实现类分别为AppleInfo,OrangeInfo,MangoInfo分别实现了各自获取信息的方法。
然后提供一个工厂类FruitFactory,它会根据传入的Fruit来产生不同的对象,客户端只要得到对象调用对应的方法就行了:
public FruitInfo getFruit(Fruit fruit){
//下边是根据不同的fruit产生不同的FruitInfo对象的代码
}----------------------分割线-------------------------
好了,上述场景我已说清楚了,现在请各位帮我分析哪种方案比较好,好在哪。我认为第二种好,因为用到了工厂模式...
但我又说不上来具体好在哪,因为如果以后增加了一种新的水果类,两种方案增加的代码量都差不多,而且访问接口的客户端改动的也不都多,只是传新的Fruit对象罢了。
唯一能想到的就是"类的单一职责原则",第一种方案类的职责太多。但是如果Fruit基本上只有那几个固定的对象,我想差别也不大。
请各位帮忙分析一下,多谢啦。
public enum Fruit{
//实例个数不会太多
APPLE,ORANGE,MANGO;
}
现在我需要三个接口(只是举例,可能更多)用来获取水果的信息,现有两种设计:
第一种:
提供一个类FruitInfo,提供三个方法,每一个根据传入的水果类型来进行不同的处理: public class FruitInfo{
public String getShape(Fruit fruit){
//下边的代码则是根据不同的fruit返回不同的形状
}
public String getColor(Fruit fruit){
//下边的代码则是根据不同的fruit返回不同的颜色
}
public String getPrice(Fruit fruit){
//下边的代码则是根据不同的fruit返回不同的价格
}
第二种:
提供一个接口FruitInfo,它有三个方法分别是getShape(),getColor(),getPrice()
然后它有三个实现类分别为AppleInfo,OrangeInfo,MangoInfo分别实现了各自获取信息的方法。
然后提供一个工厂类FruitFactory,它会根据传入的Fruit来产生不同的对象,客户端只要得到对象调用对应的方法就行了:
public FruitInfo getFruit(Fruit fruit){
//下边是根据不同的fruit产生不同的FruitInfo对象的代码
}----------------------分割线-------------------------
好了,上述场景我已说清楚了,现在请各位帮我分析哪种方案比较好,好在哪。我认为第二种好,因为用到了工厂模式...
但我又说不上来具体好在哪,因为如果以后增加了一种新的水果类,两种方案增加的代码量都差不多,而且访问接口的客户端改动的也不都多,只是传新的Fruit对象罢了。
唯一能想到的就是"类的单一职责原则",第一种方案类的职责太多。但是如果Fruit基本上只有那几个固定的对象,我想差别也不大。
请各位帮忙分析一下,多谢啦。
扩展的时候直接给出新的子类就OK了。
我的第二种方案其实就是magong所说的做法,AppleInfo,OrangeInfo,MangoInfo其实就是三种水果,它们记忆了自己的状态。
只不过我还做了一个工厂类用于产生所需的对象,这样客户端不需要参与创建对象,一定程度上解耦了。
而在这样的情况下,枚举类的好处就是总是传递合法值,客户端的调用也清晰了一点。
我说的有没有道理呢?
所以一个水果Fruit接口,提供你说的方法,然后水果子类实现该接口就好了
至于工厂,就看你想怎么做了,按照一般的框架模式来分析的话,是用反射的方式比较好,所以就看你是如何管理这些类,如果是配置文件,需要传入一个配置文件的水果分类的id,如果是用名字,就直接反射
如
interface Fruit { //这里用接口还是抽象类,根据具体需求决定
public String getShape();
public String getColor();
public String getPrice();
}class Apple implements Fruit {}class Orange implements Fruit {}class Mango implements Fruit {}class FruitFactory {
public static Fruit getFruit(String id) {
String className = Config.getFruit(id); //Config是相当于一个配置文件类
return (Fruit)Class.forName(className).newInstance();
//如果传入的id就是水果类名,直接Class.forName(id).newInstance();
}
}
话不能这么说啊,楼主,设计模式要看到它真的有用的时候你采用的。
工厂模式什么时候用的?
就是在你的初始化工作很麻烦的时候用的,比如说你的初始化要查询数据库,要查配置文件的时候,为了简化代码量,把相同代码写在工厂的create()方法里,这才是工厂模式意义所在啊,楼主不要人云亦云啊(可能措辞有点冲,冒犯楼主的地方,请见谅)
public class FruitInfo{
//get,set
private Fruit fruit; public String getShape(){
//下边的代码则是根据不同的fruit返回不同的形状
}
public String getColor(){
//下边的代码则是根据不同的fruit返回不同的颜色
}
public String getPrice(){
//下边的代码则是根据不同的fruit返回不同的价格
}
}
public FruitInfo getFruit(Fruit fruit){
//下边是根据不同的fruit产生不同的FruitInfo对象的代码
}
首先表示我认识楼主所说的两种方式并不冲突。
如果是我的话就会修改成上面的。
在某一个类会提供一个getFruit返回FruitInfo对象。具体的操作则可以调用具体的方法。
但是一个FruitInfo对象对应一个Fruit对象。
getShape,getColor,getPrice三个方法都是FruitInfo的职责。
这里把它分成三个细粒度的方法会非常好,便宜组装和扩展。