以下设计对您来说是否合适?这是一种设计模式吗?如果您认为需要重构,您会如何改进?
public class FruitFetcher {
public static void main(String[] args) {
FruitFetcher fetcher = new FruitFetcher();
Apple apple = (Apple) fetcher.fetch(new FetchAppleRequest());
}
public Fruit fetch(FetchFruitRequest request){
Fruit fruit = null;
if(request.getFruitName().equals(FetchAppleRequest.REQUEST_NAME)){
fruit = new Apple();
}else if (request.getFruitName().equals(FetchBananaRequest.REQUEST_NAME)){
fruit = new Banana();
}
return fruit;
}
}
abstract class FetchFruitRequest{
abstract public String getFruitName();
}
class FetchAppleRequest extends FetchFruitRequest{
static String REQUEST_NAME = "Fetch_Apple";
@Override
public String getFruitName() {
return REQUEST_NAME;
}
}
class FetchBananaRequest extends FetchFruitRequest{
static String REQUEST_NAME = "Fetch_Banana";
@Override
public String getFruitName() {
return REQUEST_NAME;
}
}
class Fruit {
}
class Apple extends Fruit{
}
class Banana extends Fruit{
}
在代码中,FruitFetcher
的客户需要将Fruit
转发为正确的类型,您认为这是正确的吗?
编辑:
为了回答The Elite Gentleman的问题,我修改了我的代码以表明Reqeust
需要一个简单字符串以外的类型。
getResponse()
中的PaymentServer
仍然看起来有点'难看'吗?我如何重新审视它?
public class PaymentServer {
public static void main(String[] args) {
PaymentServer server = new PaymentServer();
//set pin
SetPinResponse setPinResponse = (SetPinResponse) server.getResponse(new SetPinRequest("aPin"));
System.out.println(setPinResponse.isSuccess());
//make payment
MakePaymentResposne makePaymentResponse = (MakePaymentResposne) server.getResponse(new MakePaymentRequest(new Money("5.00)"),"aPin"));
System.out.println(makePaymentResponse.isSuccess());
}
public Response getResponse(Request request){
Response aResponse = null;
if(request.getRequestName().equals(SetPinRequest.REQUEST_NAME)){
aResponse = new SetPinResponse();
}else if (request.getRequestName().equals(MakePaymentRequest.REQUEST_NAME)){
aResponse = new MakePaymentResposne();
}
return aResponse;
}
}
abstract class Request{
abstract public String getRequestName();
}
class SetPinRequest extends Request{
static String REQUEST_NAME = "Set_Pin";
private String pin;
SetPinRequest(String pin){
this.pin = pin;
}
@Override
public String getRequestName() {
return REQUEST_NAME;
}
boolean setPin(){
//code to set pin
return true;
}
}
class MakePaymentRequest extends Request{
static String REQUEST_NAME = "Make_Payment";
private Money amount;
private String pin;
MakePayment(Money amount, String pin){
this.amount = amount;
this.pin = pin;
}
@Override
public String getRequestName() {
return REQUEST_NAME;
}
}
abstract class Response {
abstract protected boolean isSuccess();
}
class SetPinResponse extends Response{
@Override
protected boolean isSuccess() {
return true;
}
}
class MakePaymentResposne extends Response{
@Override
protected boolean isSuccess() {
return false;
}
}
谢谢,
萨拉
答案 0 :(得分:3)
您的设计非常接近工厂模式。 “fetcher”是一个水果工厂,你要求一种特殊类型的水果,并获得那种水果。
“请求”部分看起来有点复杂。考虑使用枚举:
public enum FruitType{
APPLE, BANANA
}
public FruitFetcher {
public static Fruit fetch(FruitType type) {
switch(type) {
case APPLE: return new Apple();
case BANANA: return new Banana();
}
}
return null;
}
编辑 - 它仍然非常复杂。理解它需要一段时间,你想要实现什么,这通常表明必须有一个更容易的设计。
首先 - 如果你的Request
和Response
类只提供抽象方法声明,那么你应该将代码重构为接口两种类型的代码。提高可读性的一步。
第二 - getResponse方法可以大大简化。您不需要那个(丑陋的)getName构造 - 只需检查请求对象的类型:
public Response getResponse(Request request){
Response aResponse = null;
if(request instanceof SetPinResponse) {
aResponse = new SetPinResponse((SetPinRequest) request);
} else if (request instanceof MakePaymentResposne) {
aResponse = new MakePaymentResposne((MakePaymentRequest) request);
}
return aResponse;
}
答案 1 :(得分:1)
除了设计模式之外,您正在寻找的是Generics。
至于设计模式,你所做的是Factory Method Pattern,其中FruitFetcher
是工厂,Fruit
(及其子类)是产品。
你的FruitFetcher.fetch
有点“含糊不清”(缺乏更好的词)。我建议传递type
来识别您要求的Fruit
。
type
可以是枚举,整数或字符串(它实际上取决于您希望如何创建FruitFetcher.fetch()
可识别的特定值类型。
示例:
public class FruitFetcher {
public Fruit fetch(String fruitName) {
if ("Apple".equals(fruitName)) {
return new Apple();
}
if ("Banana".equals(fruitName)) {
return new Banana();
}
return null;
}
}
这比发送new FetchAppleRequest()
或new FetchBananaRequest()
更有说服力。
答案 2 :(得分:-1)
提示:这是代码的“丑陋”部分......
if(request.getFruitName().equals(FetchAppleRequest.REQUEST_NAME)){
fruit = new Apple();
}else if (request.getFruitName().equals(FetchBananaRequest.REQUEST_NAME)){
fruit = new Banana();