我受到了数字向导游戏问题的启发,我决定写我自己的游戏版本。我的目标是遵循坚实的原则,使逻辑UI独立。不过,我对结果有点困惑。
我认为我的解决方案读起来比原始问题中的版本容易得多,但另一方面,在设计方面也要复杂得多。我谈过复杂的事情了吗?
接口:
namespace NumberWizard.Api
{
public interface IMessenger
{
IEnumerable<string> BeforeStateEnterMessages();
IEnumerable<string> InStateMessages();
}
}
namespace NumberWizard.Api
{
public interface IState
{
void Increase();
void Decrease();
int Value { get; }
}
}有用的摘要:
using NumberWizard.Api;
using System;
namespace NumberWizard
{
public class SteppedValueChanger
{
private int _value = 0;
private readonly int _step;
public SteppedValueChanger(int step)
{
_step = step;
}
public void Increase()
{
_value += _step;
}
public void Decrease()
{
_value = Math.Max(0, _value - _step);
}
public int Value
{
get { return _value; }
}
}
}
namespace NumberWizard
{
public class Range
{
public int Min { get; private set; }
public int Max {get; private set;}
public Range() : this(0, 0)
{
}
public Range(int min, int max)
{
Min = min;
Max = max;
}
internal void SetMin(int min)
{
Min = min;
}
internal void SetMax(int max)
{
Max = max;
}
}
}各国:
using NumberWizard.Api;
using System.Collections.Generic;
namespace NumberWizard.State
{
class SetupMax : IState, IMessenger
{
private readonly SteppedValueChanger _valueModifier = new SteppedValueChanger(100);
public IEnumerable<string> BeforeStateEnterMessages()
{
return new[] { "Welcome to Number Wizard", "Set max number!" };
}
public IEnumerable<string> InStateMessages()
{
return new[] { string.Format("Max: {0}", Value) };
}
public void Increase()
{
_valueModifier.Increase();
Value = _valueModifier.Value;
}
public void Decrease()
{
_valueModifier.Decrease();
Value = _valueModifier.Value;
}
public int Value { get; private set; }
}
}
using NumberWizard.Api;
using System.Collections.Generic;
namespace NumberWizard.State
{
class SetupMin : IState, IMessenger
{
private readonly SteppedValueChanger _valueModifier = new SteppedValueChanger(1);
public IEnumerable<string> BeforeStateEnterMessages()
{
return new[] { "Set min number!" };
}
public IEnumerable<string> InStateMessages()
{
return new[] { string.Format("Min: {0}", Value) };
}
public void Increase()
{
_valueModifier.Increase();
Value = _valueModifier.Value;
}
public void Decrease()
{
_valueModifier.Decrease();
Value = _valueModifier.Value;
}
public int Value { get; private set; }
}
}
using NumberWizard.Api;
using System.Collections.Generic;
namespace NumberWizard.State
{
class Guess : IState, IMessenger
{
private Range _guessingRange;
private int _guess;
public Guess(Range range)
{
_guessingRange = range;
_guess = GuessNext();
}
public void Increase()
{
_guessingRange = new Range(_guess, _guessingRange.Max);
_guess = GuessNext();
}
public void Decrease()
{
_guessingRange = new Range(_guessingRange.Min, _guess);
_guess = GuessNext();
}
private int GuessNext()
{
return (_guessingRange.Max + _guessingRange.Min) / 2;
}
public IEnumerable<string> BeforeStateEnterMessages()
{
return new[]{
"Pick a number in your head, but don't tell me!",
string.Format("The highest number you can pick is {0}", _guessingRange.Max),
string.Format("The lowest number you can pick is {0}", _guessingRange.Min),
string.Format("Is the number higher or lower than {0}?", Value)
};
}
public IEnumerable<string> InStateMessages()
{
return new[] {
string.Format("Is the number higher or lower than {0}?", Value) };
}
public int Value { get { return _guess; } }
}
}“国家机器”:
using NumberWizard.Api;
using NumberWizard.State;
using System.Collections.Generic;
using System.Linq;
namespace NumberWizard
{
public class Game
{
private Range guessingRange = new Range();
private IState _gameState;
public IEnumerable<string> Decrease()
{
_gameState.Decrease();
return GetInStateMessages(_gameState);
}
public IEnumerable<string> Increase()
{
_gameState.Increase();
return GetInStateMessages(_gameState);
}
private IEnumerable<string> GetInStateMessages(IState gameState)
{
var messenger = gameState as IMessenger;
if (messenger == null) { return Enumerable.Empty<string>(); }
return messenger.InStateMessages();
}
private IEnumerable<string> GetBeforeStateEnterMessages(IState gameState)
{
var messenger = gameState as IMessenger;
if (messenger == null) { return Enumerable.Empty<string>(); }
return messenger.BeforeStateEnterMessages();
}
public IEnumerable<string> ChangeState()
{
if (_gameState == null)
{
_gameState = new SetupMax();
return GetBeforeStateEnterMessages(_gameState);
}
if (_gameState is SetupMax)
{
guessingRange.SetMax(_gameState.Value);
_gameState = new SetupMin();
return GetBeforeStateEnterMessages(_gameState);
}
if (_gameState is SetupMin)
{
guessingRange.SetMin(_gameState.Value);
_gameState = new Guess(guessingRange);
return GetBeforeStateEnterMessages(_gameState);
}
if (_gameState is Guess)
{
_gameState = null;
return new[] { "I guessed Correctly!", "Press 'c' to start over or 'q' to quit" };
}
return Enumerable.Empty<string>();
}
}
}主要:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace NumberWizard
{
class Program
{
static void Main(string[] args)
{
var game = new Game();
IEnumerable<string> messages = game.ChangeState();
PrintMessages(messages);
var key = Console.ReadKey(true);
while (true)
{
switch (key.KeyChar)
{
case 'u':
messages = game.Increase();
break;
case 'd':
messages = game.Decrease();
break;
case 'c':
messages = game.ChangeState();
break;
case 'q':
Environment.Exit(0);
break;
}
PrintMessages(messages);
key = Console.ReadKey(true);
}
}
private static void PrintMessages(IEnumerable<string> messages)
{
foreach (var m in messages)
{
Console.WriteLine(m);
}
}
}
}发布于 2015-06-01 13:33:09
你是在问自己关于事情复杂化的正确问题。的确,对于大多数小的挑战,解决方案往往是小的,毕竟没有多少人想要构建一个企业应用程序作为一个“有趣的挑战”。这些挑战中的许多都可以作为机会来尝试一个新的想法,或者作为一名开发人员,在处理生产代码时不会得到改进。接下来是密码。我看到的次要的事情是不一致的访问修饰符。您的Range --您将Min和Max标记为私有集,但是您将SetMin和Max设置为内部。不过,这门课是公开的。如果您正在进行使用范围的测试,则只能创建一次范围,而不能更改值。可能不是一个可怕的副产品,但也似乎很奇怪。到目前为止,当您只设置min和max时,为什么要在猜测中创建一个新的范围?
我认为您可能在SetupMax和SetupMin的代码中违反了L的代码。您有一个类具有与IState相同的方法,但没有实现IState。当然,它看起来并不是应该的,但是它有相同的方法,并且在这两种方法中都有一个直接的实现,而没有能力放入自定义的方法。
总的来说,我认为你做得很好。我建议编写一些测试,以确保您希望的逻辑按预期工作。诚然,坚实的原则不涉及编写测试,但它们确实使编写测试更容易。测试是一种快速的方法来验证您的代码是否按预期工作,并且它将帮助您问出您需要问的问题,以保持坚实的原则。
https://codereview.stackexchange.com/questions/91612
复制相似问题