这样的设计有意义吗?
下面的设计你觉得好看吗?它是一种设计模式吗?如果您认为它需要重构,您将如何改进它?
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
向上转换为正确的类型,您认为这是正确的吗?
编辑: 为了回答精英绅士的问题,我修改了代码以表明 Reqeust
需要除简单字符串之外的类型。
PaymentServer
中的 get getResponse()
看起来仍然有点“丑陋”吗?我该如何重新编辑它?
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;
}
}
谢谢,
莎拉
Does the below design look good to you? Is it a design pattern? How would you improve it if you think it needs refactoring?
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{
}
In the code, clients of FruitFetcher
need to upcast Fruit
to a right type, do you think that is correct?
Edit:
To answer The Elite Gentleman's question, I modified my code to show that the Reqeust
needs a type other than a simple String.
Does get getResponse()
in PaymentServer
still look kind of 'ugly'? How do I re-fector it?
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;
}
}
Thanks,
Sarah
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您的设计非常接近工厂模式。 “取货者”是一个水果工厂,你要求一种特殊类型的水果并得到那种水果。
“请求”部分看起来有点复杂。考虑使用枚举:
编辑 - 它仍然相当复杂。需要一段时间才能理解您想要实现的目标,这通常表明必须有更简单的设计。
首先 - 如果您的
Request
和Response
类只提供抽象方法声明,那么您应该重构您的代码,将两种类型的代码都编码为接口。提高可读性的一步。其次 - getResponse 方法可以大大简化。您不需要那个(丑陋的) getName 构造 - 只需检查请求对象的类型:
Your design is pretty close to a factory pattern. The "fetcher" is a fruit factory, you ask for a fruit of a special type and get that fruit.
The "request" part looks a bit complicated. Consider using enums:
Edit - It's still pretty complicated. It takes a while to understand, what you want to achieve and this is usually an indicator that there must be an easier design.
First - if your
Request
andResponse
classes offer nothing but abstract method declarations, then you should refactor your code an code both types as interfaces. One step towards improved readability.Second - the getResponse methd can be greatly simplified. You don't need that (ugly) getName construct - just check the type of the request object:
除了设计模式之外,您还要寻找 泛型。
至于设计模式,您所做的称为 工厂方法模式,其中
FruitFetcher
是工厂,而Fruit
(及其子类)是产品。您的
FruitFetcher.fetch
有点“模棱两可”(因为缺乏更好的词)。我建议传递一个type
来标识您请求的Fruit
。type
可以是枚举、整数或字符串(这实际上取决于您希望如何创建可由FruitFetcher.fetch()
识别的特定值类型。示例:
这比发送
new FetchAppleRequest()
或new FetchBananaRequest()
更有说服力。Besides the design pattern, what you're looking for is Generics.
As for design pattern, What you're doing is called the Factory Method Pattern, where
FruitFetcher
is the Factory andFruit
(and its subclasses) are Products.Your
FruitFetcher.fetch
is a bit "ambiguous" (for the lack of better word). I would suggest passing atype
that would identify theFruit
that you are requesting.the
type
can be an enum, integer, or string (it really depends on how you want to create a specific value type that can be recognised byFruitFetcher.fetch()
.Example:
This is more eloquent than sending
new FetchAppleRequest()
ornew FetchBananaRequest()
.提示:这是代码中“丑陋”的部分......
Hint: this is the "ugly" part of the code...