我遇到了一个很大的问题,我的代码太长而且字符全。我删除了很多,使用方法和使用一些适当的设计模式...但它仍然太“拥挤”。
我从用户那里得到一个字符串,如:
"How are you Josh?"
"Who is Josh's mother?"
我需要分析这个问题,以便查看它的内容和System.out.print()的答案。
所以一长串“if / else if”开始了,例如
if (question.startsWith("How") && question.endsWith("Josh?"))
{
//do a lot of things here.
System.out.print(actualHealth);
}
else if (question.startsWith("Who") && question.endsWith("mother?"))
{
//do a lot of things here.
System.out.print(getParents().getMother());
}
*
*
* //Lot of "else if" here to recognize the question meaning.
*
*
else
{
System.out.print("question not recognized");
}
我将此类AnswersFactory称为设计模式“工厂模式”,因为问题在另一个类中被“询问”。但我认为将它视为一种设计模式是错误的。
如何简化所有这些条件,即使它们似乎无法简化,或者至少使代码看起来更有条理?是否有良好的设计模式?
我的代码效果很好,但看起来并不漂亮。我希望你明白这种挫败感!
谢谢。
答案 0 :(得分:1)
不确定为什么要根据关键字检查问题,它有一些像HCBPshenanigans所提到的缺点 但要改变它更灵活,我会做这样的事情:
所有问题处理程序的界面
public interface IQuestionHandler
{
bool CanHandle(string question);
void Handle(string question);
}
每个方案的具体类。每个类都将告诉它是否可以处理问题,并包含处理问题的逻辑:
public class HealthQuestionHandler : IQuestionHandler
{
public bool CanHandle(string question)
{
return question.StartsWith("How") && question.EndsWith("Josh?");
}
public void Handle(string question)
{
//Replace by actual processing
string healthStatus = "I'm fine";
Console.WriteLine(healthStatus);
}
}
public class MotherQuestionHandler : IQuestionHandler
{
public bool CanHandle(string question)
{
return question.StartsWith("Who") && question.EndsWith("mother?");
}
public void Handle(string question)
{
//Replace by actual processing
string mother = "...";
Console.WriteLine(mother);
}
}
最后一个问题处理程序处理器来管理所有处理程序。它将在构造函数中注册所有可用的处理程序。当被调用进行处理时,它会遍历所有可用的处理程序,逐个询问哪个人可以处理问题
public class QuestionHandlerProcessor
{
private List<IQuestionHandler> _handlers;
public QuestionHandlerProcessor()
{
//Register available handlers
_handlers = new List<IQuestionHandler>
{
new HealthQuestionHandler(),
new MotherQuestionHandler()
};
}
public void Process(string question)
{
foreach(var handler in _handlers)
{
if(handler.CanHandle(question))
{
handler.Handle(question);
return;
}
}
Console.WriteLine("Question not recognized");
}
}
用法:
QuestionHandlerProcessor processor = new QuestionHandlerProcessor();
processor.Process("How are you Josh?");
processor.Process("Who is Josh's mother?");
虽然我的答案是在C#中,但转换为Java应该不难。
答案 1 :(得分:0)
为你的常数创建一个enum
&#34; WHO&#34;,&#34; HOW&#34;,....和WHERE&#34;然后在那之后尝试使用switch
你可以在同一个类中创建枚举
答案 2 :(得分:0)
您可以使用工厂模式和策略模式。由于Qestion是在另一个类中被问到的(让我们称之为QueryResolver),它应该是这样的:
class QueryProcessor
{
private IQueryResolver _ resolver;
//We will be injecting our dependencies in the constructor (Dependency Inversion)
public QueryProcessor(IQueryResolver resolver )
{
_resolver = resolver;
}
public string ProcessQuery()
{
_resolver.ResolveQuery();
}
现在,您的QueryResolver实现IQueryResolver接口
public interface IQueryResover
{
string ResolveQuery();
}
你将有多个IQueryResolver实现,每个实现负责一种特定的查询,例如:
//This particular implementation know how to resolve question including the "Who" key word.
class WhoQueryResolver : IQueryResolver
{
private string _question;
public WhoQueryResolver(string question)
{
_question = question;
}
public string ResolveQuery()
{
//do a lot of things here.
System.out.print(getParents().getMother());
}
类似地,
class HowQueryResolver : IQueryResolver
{
private string _question;
public HowQueryResolver(string question)
{
_question = question;
}
public string ResolveQuery()
{
//do a lot of things here.
System.out.print(GetActualHealth());
}
最终返回一个返回IQueryResolver具体实现的工厂
public class QueryResolverFactory
{
public static IQueryResolver GetQueryResolver()
{
if (question.startsWith("How") && question.endsWith("Josh?"))
{
return new HowQueryResolver(question);
}
else if (question.startsWith("Who") && question.endsWith("mother?"))
{
return new WhoQueryResolver(question);
}
}
}
答案 3 :(得分:0)
您可以使用Chain Of Responsibility模式。你需要捕捉异常
UnhandledQuestionException
public abstract class QuestionHandler {
protected QuestionHandler successor;
public void setSuccessor(QuestionHandler successor) {
this.successor = successor;
}
public abstract void handle(String question);
}
和实现者应该如此
public class HealthQuestionHandler extends QuestionHandler {
private bool canHandle(String question) {
return question.startsWith("How") && question.endsWith("Josh");
}
public void handle(String question) {
if( canHandle(question) ) {
String healthStatus = "I am fine";
System.out.println(healthStatus);
} else {
super.successor.handle(question);
}
}
}
public class MotherQuestionHandler extends QuestionHandler {
private bool canHandle(String question) {
return question.startsWith("Who") && question.endsWith("Mother");
}
public void handle(String question) {
if( canHandle(question) ) {
String mother = "..."; //name
System.out.println(mother);
} else {
super.successor.handle(question);
}
}
}
最终处理程序,当无法处理问题时:
public class UnhandledQuestionHandler extends QuestionHandler {
public void handle(String question) {
throw new UnhandledQuestionException("question not recognized");
}
}
你应该创建
UnhandledQuestionException
首先,它扩展了Exception类。
你也应该创建QuestionHandlerFactory。
public class QuestionHandlerFactory {
public static QuestionHandler create() {
//if you can have several variants of this handler combinations, this method shouldn't be static
QuestionHandler healthQuestionHandler = new HealthQuestionHandler();
QuestionHandler motherQuestionHandler = new MotherQuestionHandler();
QuestionHandler unhandledQuestionHandler = new UnhandledQuestionHandler()'
motherQuestionHandler.setSuccessor(unhandledQuestionHandler);
healthQuestionHandler.setSuccessor(motherQuestionHandler);
return healthQuestionHandler;
}
}
并且在此类的用户中将是:
QuestionHandler handler = QuestionHandlerFactory.create();
try {
handler.handle(question);
} catch( UnhandledQuestionException ex ) {
System.out.println(ex.getMessage());
}