首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >假采访场景:刽子手

假采访场景:刽子手
EN

Code Review用户
提问于 2021-09-15 16:59:18
回答 2查看 294关注 0票数 2

为了一次假面试,我决定给Hangman写信。我要问的第一个问题是,当在面试中检查某人的代码时,写一些简短的、能完成任务的东西,还是用依赖注入和小的OOP模块来写东西,会更重要吗?

附件是我想出的一个小例子,花了30分钟左右。如果您正在检查这段代码,您会认为这是可以接受的,还是希望在一小时内,有人能生产出更多的技能呢?

代码语言:javascript
复制
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Hangman
{
    public static class Program
    {
        private const string WordToGuess = "HANGMAN";
        private static readonly HashSet<char> LettersToGuess = new(WordToGuess.ToCharArray());
        private const int MaxLives = 5;

        private static readonly HashSet<char> _guessedLetters = new();

        private static void Main(string[] _)
        {
            while (!WonGame && LivesRemaining > 0)
            {
                var displayStringBuilder = new StringBuilder();
                displayStringBuilder
                    .AppendLine(WordDisplay)
                    .Append("Letters Guessed: ").AppendLine(GuessedLettersDisplay)
                    .Append("Lives Remaining: ").Append(LivesRemaining)
                    .AppendLine().AppendLine()
                    .Append("Enter a guess: ");

                Console.Clear();
                Console.Write(displayStringBuilder.ToString());

                var guess = Console.ReadLine();
                if (!ValidGuess(guess)) continue;

                _guessedLetters.Add(char.ToUpper(guess[0]));
            }

            var endingStringBuilder = new StringBuilder();
            endingStringBuilder
                .Append("The word was: ").AppendLine(WordToGuess)
                .AppendLine(WonGame ? "You Won!" : "You Lost!");

            Console.Clear();
            Console.WriteLine(endingStringBuilder.ToString());
        }

        private static int LivesRemaining => MaxLives - _guessedLetters.Except(LettersToGuess).Count();
        private static bool WonGame => !LettersToGuess.Except(_guessedLetters).Any();

        private static string WordDisplay => string.Join(' ', WordToGuess.ToCharArray().Select(x => _guessedLetters.Contains(x) ? x : '_'));
        private static string GuessedLettersDisplay => string.Join(',', _guessedLetters);

        private static bool ValidGuess(string guess)
        {
            if (guess.Length != 1) return false;
            return char.IsLetter(guess[0]);
        }
    }
}
EN

回答 2

Code Review用户

发布于 2021-09-16 10:11:41

以下是我的观察结果

ValidGuess

  • 我建议叫它ValidateGuessIsGuessValid
  • 我也建议使用表达体法,就像你和其他成员一样
代码语言:javascript
复制
private static bool IsGuessValid(string guess) => guess.Length == 1 ? char.IsLetter(guess[0]) : false;
  • 我也建议扭转这种情况。有了这种形式,回退逻辑就变得更加可见了。

LettersToGuess

代码语言:javascript
复制
private static readonly ImmutableArray<char> WordToGuess = "HANGMAN".ToImmutableArray();
private static readonly ImmutableHashSet<char> LettersToGuess = WordToGuess.ToImmutableHashSet();

WordToGuess

  • 我还建议将其存储为字符集合,而不是const
    • 例如,在WordDisplay中,您正在一次又一次地将string转换为char[]

  • endingStringBuilder中,您可以简单地将ImmutableArray<char>转换为string,如下所示:
代码语言:javascript
复制
.Append("The word was: ").AppendLine(new string(WordToGuess.AsSpan()))

displayStringBuilderendingStringBuilder

  • 我建议你不要重复StringBuilder
  • 如果您想强调它们是构建器,那么请尝试使用以下名称:
    • gameStatusInformationBuilder或者仅仅是statusInformationBuilder
    • gameSummaryInformationBuilder或者仅仅是summaryInformationBuilder

Main

代码语言:javascript
复制
static void Main() 
{ 
   ...
}

MaxLivesLivesRemaining

  • 这是次要的,但使用方便的命名有助于资格。
  • 例如:MaxLivesRemainingLives

if (!IsGuessValid(guess)) continue;

  • 我认为在这里提供一个信息丰富的错误消息,然后continue,可能会帮助玩家修复他/她以前的问题。
票数 2
EN

Code Review用户

发布于 2021-09-16 21:23:31

..。才能创造出更多的技能?

要求+设计+代码=艺术。事情就是这样。

设计

不执行汉曼游戏。只有一个硬编码的单词--通过设计--只有一种使用丢弃的东西,而不是游戏。

手动替换猜测词需要每次重写程序。“不,只需更改WordToGuess值”。我要对版本控制软件说这句话;您从来没有必要以交付和维护工作软件为生,是吗?任何更改,无论多么琐碎,都需要回顾、测试、集成、部署、客户需求等等。因此,从“刽子手”改为"EXEMPLOYEE“绝不能像”重写“代码那么重要。

依赖注入本身并不是设计目标。这是经过深思熟虑的模块化设计的结果,如果不是明确的面向对象的话。模块本身并不是一个设计目标。总体目标是程序功能的分离/独立。我们称这为单一责任原则..。

Hangman算法没有直接输出显示的功能。即使在Hangman游戏中,对于细微的功能责任也可能有不同的看法,但这不是这样的。提取控制台显示代码将产生大量有目的的"DI“和”小模块“。不要强行把热门词宾果BS写进代码中。可能会增加复杂性,却没有任何合理的好处。

我不明白为什么static类。Program是Hangman类,为什么要将它命名为Program并使其成为静态类?包装在Hangman命名空间中的坏类名仍然是错误的类名。阅读这个线程:为什么类程序被声明为静态的?。在所选的答案中引用:

Program的S职责是为应用程序提供一个入口点,所以它不应该再做任何事情

这是一个小程序,但有抽象概念和代码,封装细节等的空间。

如果我做了任何错误的假设或代码误读,我可以把它放在编码器上。结构、有意义的名称、抽象、封装、实心、成语、判断等使即使是“简单”的程序也不平凡。

编码

提取一种方法 -对主游戏循环来说太详细了

代码语言:javascript
复制
var displayStringBuilder = new StringBuilder();
            displayStringBuilder
                .AppendLine(WordDisplay)
                .Append("Letters Guessed: ").AppendLine(GuessedLettersDisplay)
                .Append("Lives Remaining: ").Append(LivesRemaining)
                .AppendLine().AppendLine()
                .Append("Enter a guess: ");

            Console.Clear();
            Console.Write(displayStringBuilder.ToString());

"CorrectGuess“是正确的。“有效”在用户交互中具有更广泛的含义。字母表中的字母是有效的输入,但只有猜字的字母是正确的.

代码语言:javascript
复制
 private static bool ValidGuess(string guess)

对无效输入的保护太弱了

代码语言:javascript
复制
private static bool ValidGuess(string guess)
    {
        if (guess.Length != 1) return false;
        return char.IsLetter(guess[0]);
    }

// suggestions:
private static bool ValidGuess(string guess)
    {
        if (string.IsNullOrWhitespace(guess)) return false;

        if (guess.Length != 1) return false;
        
        // IsLetter can throw NullArgumentException, but the
        // above guards for that.
        return char.IsLetter(guess[0]);
    }

ValidGuess只是这样做的,而不是寻找一个正确的WordToGuess字母。单一责任的极好例子。

所以线程:isNullOrWhitespace

我开始欣赏矮个子ifs时的单线和没有支撑。但是,无论多长时间,始终在控制块(而不仅仅是"if")上方和下面留空格。一个大爆炸的巴克可读性提示!

过度工程?我不明白HashSet的必要性。另外,string是一个char数组。换句话说,您可以直接forEach(letter in myString)

代码语言:javascript
复制
private static readonly HashSet<char> LettersToGuess = new(WordToGuess.ToCharArray());

游戏主回路应读为“高水平”,并准确地表达游戏条件。

代码语言:javascript
复制
while (!WonGame && LivesRemaining > 0)

表达“我还活着吗?”,而不是“生命是否还在零?”。我不在乎有多少人,如果有的话。代码越早从低水平的DNA比特中抽象出来,就越好。

代码语言:javascript
复制
while (!WonGame && StillAlive)

protected bool StillAlive { get {return LivesRemaining > 0; }}

!WonGame在这里的意思是我们猜错了这个词。

代码语言:javascript
复制
while ( WrongGuess && StillAlive )

protected bool WrongGuess { get { ... }}

现在我们明白了继续比赛的条件。而不需要读取底层代码。

Hangman宇宙中的总体“坚持”概念是什么?

代码语言:javascript
复制
while (NotHung) { ... }

protected bool NotHung { get { return WrongGuess && StillAlive; }}

我们可以争论一整天的财产的负面名称。这是我们要找的主意。

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

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

复制
相关文章

相似问题

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