正确使用课程?

sub*_*can 7 c# oop design-patterns class-design class

我是大学生(计算机科学),刚刚开始了C#编程课程.对于我们的作业,我一直在使用一个名为"Display"的类,我在其中放置了可以在整个项目中多次使用的控制台输出.例如,请求继续或退出程序.Main()我只是在Display课堂上调用方法,而不是多次输入.

更高级别的另一名学生告诉我,我不应该这样做.这是一个糟糕的编码实践,我应该只包括主类(包含Main())中的所有方法,并在绝对需要时只使用其他类.

我只是在寻找一些意见和建议.

我被要求包含代码.我本来打算,但不想让这篇文章太久.我选择了一个相当短的作业.我想澄清一下,我只是在学习,所以代码并不像你们许多人所能写的那么优雅.建设性的批评非常受欢迎.

最终我只是在玩类的使用.我知道Display类中的一些方法可以很容易地在Main()中.

这是包含Main()的Program类

namespace Chapter_6_10
{
class Program
{
    static void Main()
    {
        string triangle = "", result = " ";;
        char printingCharacter = ' ';
        int peakNumber = 0;
        Display.Instructions();
        Display.Continue();
        // perform a do... while loop to build triangle up to peak
        do
        {
            Console.Clear();
            Request.UserInput(out printingCharacter, out peakNumber);
            int  counter = 1, rowCounter = 0;
            do
            {
                do
                {
                    triangle += printingCharacter;
                    rowCounter++;
                }
                while (rowCounter < counter);
                counter++;
                rowCounter = 0;
                triangle += "\n";
            }
            while(counter != peakNumber);
            // perform a do... while loop to build triangle from peak to base
            do
            {
                do
                {
                    triangle += printingCharacter;
                    rowCounter++;
                }
                while (rowCounter < counter);
                counter--;
                rowCounter = 0;
                triangle += "\n";
            }
            while (counter != 0);
            Console.Clear();
            Console.WriteLine(triangle); // display triangle
            Display.DoAgain(out result); // see if user wants to do another or quit
            triangle = "";                
        }
        while (result != "q"); 
    }
}
Run Code Online (Sandbox Code Playgroud)

这是Display类

namespace Chapter_6_10
{
// This class displays various outputs required by program
class Display
{
    // This method display the instructions for the user
    public static void Instructions()
    {
        Console.WriteLine("\nThis program will ask you to enter a character to be used "
            + " to create triangle."
            + "\nThen you will be asked to enter a number that will represent the"
            + "\ntriangles peak."
            + "\nAfter your values have been received a triangle will be drawn.");
    }
    // This method displays the choice to continue
    public static void Continue()
    {
        Console.WriteLine("\n\nPress the enter key when you are ready to continue...");
        Console.ReadLine();
    }
    // This method displays an error message
    public static void Error(string ErrorType)
    {
        Console.WriteLine("\nYou have entered \"{0}\", which is a value that is not valid!"
            + "\nThis is not rocket science."
            + "\n\nTry agian...", ErrorType);
    }
    // This method will ask user to press enter to do again or 'q' to quit
    public static void DoAgain(out string Result)
    {
        string input = " ";
        Console.WriteLine("\nPress enter to run program again"
            + "\nor type the letter 'q' to close the application.");
        input = Console.ReadLine();
        // convert input to lowercase so that only one test needed
        Result = input.ToLower();
    }        
}
Run Code Online (Sandbox Code Playgroud)

这是Request类

namespace Chapter_6_10
{
// This class is used to get user input
class Request
{
    public static void UserInput(out char PrintingCharacter, out int PeakNumber)
    {
        string input = " ";
        char testCharacter = ' ';
        int testNumber = 0;

        // a do... while loop to get Printing Character from user
        // use TryParse() to test for correct input format
        do
        {
            Console.Write("\nPlease enter a character to be used to build triangle : ");
            input = Console.ReadLine();
            bool result = char.TryParse(input, out testCharacter);
            if (result)
            {

            }
            else
            {
                Console.Clear();
                Display.Error(input);
                input = " ";
            }
        }
        while (input == " ");
        // a do... while loop to get number from user
        // use TryParse() to test for correct input format
        do
        {
            Console.Write("\nPlease enter a number <between 1 and 10> for the peak of the triangle : ");
            input = Console.ReadLine();
            bool result = int.TryParse(input, out testNumber);
            if (result)
            {
                if ((testNumber > 0) && (testNumber < 11))
                {                        
                }
                else
                {
                    Console.Clear();
                    Display.Error(testNumber.ToString());
                    input = " ";
                }
            }
            else
            {
                Console.Clear();
                Display.Error(input);
                input = " ";
            }
        }
        while (input == " ");
        // assigned received values to 'outs' of method
        PrintingCharacter = testCharacter;
        PeakNumber = testNumber;
    }
}
Run Code Online (Sandbox Code Playgroud)

这就对了.这会被认为是一种无法实现的代码方式吗?我怎样才能改进它?

感谢到目前为止的所有输入.这对我来说非常有价值.

Cod*_*ray 15

完善和精心设计的类结构对于遵循面向对象的设计原则非常重要.

以下是考虑将相关代码分解为单独类的几个原因:

  • 它创造了劳动分工并隔离了差异化任务.这有时被解释为单一责任原则,它说每个对象(类)应该只有一个责任,并专注于完成单个任务.封装也很快成为一个重要的原则,基本上意味着数据与负责操作该数据的方法捆绑在一起.这也有助于减少错误进入代码的机会.

  • 它可以帮助促进代码重用.使用已编写的代码将现有类带入其他应用程序通常要容易得多,而不是将代码分散到整个应用程序中.为什么一遍又一遍地重写相同的代码?

  • 精心设计的类结构可以创建逻辑层次结构,使您的代码更易于理解和概念化,并使您的应用程序从长远来看更容易维护.这就是为什么我们将计算机上的文件组织到文件夹中,以及我们生活中的其他一切(或者至少我们尝试)的原因.


sta*_*ica 8

它的编码习惯很差,我应该只包括主类中的所有方法[...],并且只使用其他类时,绝对需要.

我绝对不同意.这种思路最终会导致该只落得做了几个吹机,厨房水槽类的一切.

如果我们谈论结构化编程,你的同事是对的,你可能只有子程序而没有类 - 组织功能的主要方法是将它分成子程序.但在这里我们谈论的面向对象编程,这也给了你瓜分功能,为不同类别的手段.毕竟,类是可以使用的,否则我们就不会调用这个OOP!

如果我是你,我更喜欢在你需要时定义新类的相当自由的方法.


PS:不言而喻,确实有最佳实践可以帮助您决定是否需要新课程以及如何设计.(参见例如Cody Gray的回答.)我只想在此指出,在OOP中主动避免课程肯定没有意义.


Arm*_*yan 6

永远不要听别人说谁"这是很好的做法"或"这是不好的做法,"如果他们不能向你解释为什么它是好还是坏.就像在其他所有领域一样,编程中有许多刻板印象,尽量避免它们.

为了您的具体的例子,这是一个有点模糊,因为我真的不知道你的类做什么,我不认为在一个单独的类分离IO功能是非常糟糕的做法.然而,这实际上取决于它的作用,是否是独立的等等.还取决于个人品味:)