首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >数字向导独立(UI独立)实现

数字向导独立(UI独立)实现
EN

Code Review用户
提问于 2015-05-24 03:52:09
回答 1查看 195关注 0票数 5

我受到了数字向导游戏问题的启发,我决定写我自己的游戏版本。我的目标是遵循坚实的原则,使逻辑UI独立。不过,我对结果有点困惑。

我认为我的解决方案读起来比原始问题中的版本容易得多,但另一方面,在设计方面也要复杂得多。我谈过复杂的事情了吗?

接口:

代码语言:javascript
复制
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; }

    }
}

有用的摘要:

代码语言:javascript
复制
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;
        }
    }
}

各国:

代码语言:javascript
复制
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; } }
    }
}

“国家机器”:

代码语言:javascript
复制
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>();
        }       
    }
}

主要:

代码语言:javascript
复制
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);
            }
        }
    }
}
EN

回答 1

Code Review用户

回答已采纳

发布于 2015-06-01 13:33:09

你是在问自己关于事情复杂化的正确问题。的确,对于大多数小的挑战,解决方案往往是小的,毕竟没有多少人想要构建一个企业应用程序作为一个“有趣的挑战”。这些挑战中的许多都可以作为机会来尝试一个新的想法,或者作为一名开发人员,在处理生产代码时不会得到改进。接下来是密码。我看到的次要的事情是不一致的访问修饰符。您的Range --您将Min和Max标记为私有集,但是您将SetMin和Max设置为内部。不过,这门课是公开的。如果您正在进行使用范围的测试,则只能创建一次范围,而不能更改值。可能不是一个可怕的副产品,但也似乎很奇怪。到目前为止,当您只设置min和max时,为什么要在猜测中创建一个新的范围?

我认为您可能在SetupMax和SetupMin的代码中违反了L的代码。您有一个类具有与IState相同的方法,但没有实现IState。当然,它看起来并不是应该的,但是它有相同的方法,并且在这两种方法中都有一个直接的实现,而没有能力放入自定义的方法。

总的来说,我认为你做得很好。我建议编写一些测试,以确保您希望的逻辑按预期工作。诚然,坚实的原则不涉及编写测试,但它们确实使编写测试更容易。测试是一种快速的方法来验证您的代码是否按预期工作,并且它将帮助您问出您需要问的问题,以保持坚实的原则。

票数 2
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/91612

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档