2010-11-21 48 views
6

Tôi là sinh viên đại học (khoa học máy tính) và vừa mới bắt đầu một lớp lập trình C#. Đối với các bài tập của chúng tôi, tôi đã sử dụng một lớp được gọi là "Hiển thị", nơi tôi đặt bất kỳ đầu ra bàn điều khiển nào có thể được sử dụng nhiều lần trong suốt một dự án. Ví dụ, một yêu cầu để tiếp tục hoặc thoát khỏi chương trình. Thay vì gõ nó nhiều lần trong Main() Tôi chỉ gọi phương thức từ lớp Display.sử dụng đúng các lớp học?

Một học sinh khác trong một cấp độ cao hơn đã nói với tôi rằng tôi không nên làm điều này. Đó là thực hành mã hóa kém và tôi chỉ nên bao gồm tất cả các phương thức trong lớp chính (có chứa Main()) và chỉ sử dụng lớp khác khi thật cần thiết.

Tôi chỉ đang tìm một số đầu vào và tư vấn.

Tôi được yêu cầu bao gồm mã. Ban đầu tôi đã định, nhưng không muốn đăng bài này quá lâu. Tôi đã chọn một bài tập khá ngắn. Tôi muốn làm rõ rằng tôi chỉ học hỏi để mã không thanh lịch như nhiều người trong số các bạn có thể viết. Phê bình mang tính xây dựng được chào đón rất nhiều.

Cuối cùng tôi chỉ đang chơi với việc sử dụng các lớp học. Tôi biết rằng một số phương thức trong lớp Display có thể dễ dàng ở trong Main().

Đây là lớp học Chương trình có chứa Main()

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"); 
    } 
} 

Đây là lớp 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(); 
    }   
} 

Đây là yêu cầu lớp

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; 
    } 
} 

Đó là nó. Điều này sẽ được coi là một cách không hiệu quả để mã? Làm thế nào tôi có thể cải thiện nó?

Cảm ơn tất cả các đầu vào từ trước đến nay. Nó rất có giá trị đối với tôi.

+2

Bạn có thể chia sẻ mã không? Nó dễ dàng hơn để bình luận về mã khi bạn thực sự có thể nhìn thấy nó ... –

+3

Tôi sẽ không đặt câu trả lời này vì nó được đề cập dưới đây, nhưng tôi muốn nói rằng sinh viên khác này là một trong những lý do có quá nhiều mã xấu ngoài kia. Gửi cho anh ta liên kết này đến SO và vui chơi. :) –

+0

Tôi đã thêm mã từ một trong các bài tập của tôi, theo Fredrick Mörk. Mội thông tin đầu vào đều sẽ được xem xét kĩ. – subcan

Trả lời

14

Cấu trúc lớp học kỹ lưỡng và được thiết kế tốt là cực kỳ quan trọng trong việc tuân thủ nguyên tắc object-oriented design.

Đây chỉ là một vài lý do để xem xét vi phạm ma có liên quan thành các lớp riêng biệt:

  • Nó tạo ra một phân công lao động và cách ly các nhiệm vụ khác biệt. Điều này đôi khi được giải thích là Single Responsibility Principle, mà nói rằng mọi đối tượng (lớp) nên có một trách nhiệm duy nhất và tập trung vào việc hoàn thành một nhiệm vụ duy nhất. Encapsulation cũng nhanh chóng trở thành một nguyên tắc quan trọng ở đây, về cơ bản có nghĩa là dữ liệu được đi kèm với các phương thức chịu trách nhiệm vận hành trên dữ liệu đó. Điều này cũng giúp giảm thiểu các cơ hội cho các lỗi xâm nhập vào mã của bạn.

  • Nó có thể giúp quảng cáo code reuse. Việc lấy một lớp hiện có với mã mà bạn đã viết và tích hợp nó vào một ứng dụng khác sẽ dễ dàng hơn nhiều nếu mã đó nằm rải rác trong suốt ứng dụng. Tại sao viết lại cùng một mã hơn và hơn?

  • Cấu trúc lớp được thiết kế tốt có thể tạo cấu trúc phân cấp hợp lý giúp mã của bạn dễ hiểu và khái niệm hơn, đồng thời giúp ứng dụng của bạn dễ bảo trì trong thời gian dài. Đó là lý do tại sao chúng tôi tổ chức các tệp trên máy tính của chúng tôi vào các thư mục và mọi thứ khác trong cuộc sống của chúng tôi (hoặc ít nhất là chúng tôi cố gắng).

+0

Cảm ơn câu trả lời của bạn. Tôi đã xem trang wiki về thiết kế hướng đối tượng. Trong đó tác giả nói, "Người ta có thể nói rằng một lớp là một kế hoạch chi tiết hoặc nhà máy mô tả bản chất của một cái gì đó." Tôi đã thêm mã vào bài đăng gốc của mình. Bạn có nói rằng lớp Hiển thị của tôi không tuân thủ nguyên tắc này? Tôi đang cố gắng tránh quá nhiều lộn xộn trong Main(). Tôi có thể làm theo mã của tôi khá dễ dàng từ chương trình đến chương trình, nhưng liệu có ai khác gặp khó khăn sau khi đăng ký chương trình không? – subcan

6

Đừng bao giờ nghe ai đó nói: "Đây là thực hành tốt" hoặc "Đây là thói quen xấu" nếu họ không thể giải thích cho bạn tại sao nó là tốt hay xấu. Cũng giống như trong mọi lĩnh vực khác, có nhiều khuôn mẫu trong lập trình, cố gắng tránh chúng. Ví dụ cụ thể của bạn, có một chút mơ hồ, bởi vì tôi không thực sự biết những gì lớp của bạn làm, tôi không nghĩ rằng tách chức năng IO trong một lớp riêng biệt là một ý tưởng khủng khiếp tồi tệ. Tuy nhiên điều đó thực sự phụ thuộc vào những gì nó thực hiện, cho dù đó là độc lập hay không, v.v. Ngoài ra phụ thuộc vào sở thích cá nhân :)

+1

Anh chàng chỉ trích mã của tôi nói với tôi rằng bằng cách sử dụng các lớp theo cách tôi có nghĩa là chương trình cần sử dụng nhiều vị trí bộ nhớ hơn để lưu trữ lớp và làm chậm chương trình trên quy mô lớn hơn. Tôi nói với anh ấy rằng tôi chỉ đang chơi với việc sử dụng các lớp học. Anh ấy bảo tôi không làm vậy và bằng cách sử dụng lại mã, tôi sẽ không học cách viết mã tốt hơn. Với điều này tôi đã nói với anh ấy rằng tôi liên tục thay đổi những lớp này khi tôi học thêm 'thủ đoạn'. Anh ấy vẫn khăng khăng rằng tôi đang sử dụng lớp học không chính xác. Tôi không biết. Tôi đã đọc về các lớp học trên MSDN và vẫn chưa quyết định. – subcan

+0

@subcan, những ngày này, bạn thường không cần phải lo lắng liệu các đối tượng của bạn sẽ mất một hoặc hai byte bổ sung NẾU có nghĩa là mã của bạn dễ hiểu hơn, dễ bảo trì hơn, dễ mở rộng hơn, v.v. khi bạn thiết kế các thuật toán và cấu trúc dữ liệu, * không * khi bạn thiết kế mô hình đối tượng của chương trình. Chúng tôi không nói ngôn ngữ lắp ráp ở đây, nhưng là một ngôn ngữ OOP mức độ hợp lý cao (C#). Xin lỗi vì đã quá bất thường, nhưng anh chàng chỉ trích mã của bạn chắc chắn không có vẻ như một người dạy kèm tốt để làm OOP. – stakx

+0

Tôi biết đây là một bài cũ hơn, nhưng Amen "nếu họ không thể giải thích cho bạn ** tại sao ** nó là tốt hay xấu" bởi vì * mọi * thực hành tốt đều có lý do dễ hiểu, dễ hiểu. – Crisfole

8

Đó là thực hành mã hóa kém và tôi chỉ nên bao gồm tất cả các phương pháp trong lớp chính [...] và chỉ sử dụng lớp khác khi thật cần thiết.

Tôi hoàn toàn không đồng ý. Dòng suy nghĩ này cuối cùng sẽ dẫn đến một số lớp học chìm, bồn rửa nhà bếp mà chỉ kết thúc làm mọi thứ.

đồng nghiệp của bạn sẽ đúng nếu chúng ta đã nói về lập trình có cấu trúc, nơi bạn chỉ có thể có chương trình con nhưng không có lớp — phương tiện chủ yếu của tổ chức chức năng sẽ được chia ra thành các chương trình con. Nhưng ở đây chúng tôi đang nói lập trình hướng đối tượng, cũng cung cấp cho bạn phương tiện phân chia chức năng thành các lớp khác nhau. Các lớp học sẽ được sử dụng, sau khi tất cả, nếu không chúng tôi sẽ không gọi OOP này!

Nếu tôi là bạn, tôi thích một cách tiếp cận khá tự do trong việc xác định các lớp học mới khi bạn cần chúng.


P.S .: Nó đi mà không nói rằng có thực sự thực hành tốt nhất giúp bạn quyết định xem bạn cần một lớp học mới cho một cái gì đó, và làm thế nào bạn nên thiết kế nó. (Xem ví dụ câu trả lời của Cody Gray.) Tôi chỉ muốn chỉ ra ở đây rằng nó chắc chắn không có ý nghĩa trong OOP để chủ động tránh các lớp học.

0

Nói chung, nếu bạn đang nhập cùng một điều nhiều lần, điều gì đó không ổn, tôi nghĩ vậy. Việc đóng gói các thói quen Hiển thị như vậy thực sự là biểu mẫu tốt. Nó cho phép bạn dễ dàng thay đổi đầu ra ở nhiều trường hợp, đặc biệt là đối với những thứ như thông báo lỗi.

Anh ấy có thể đến từ nhiều nền phong cách C hơn, trong khi C# thì giống java hơn bất kỳ thứ gì. Việc sử dụng tự do các lớp học được cho phép, thậm chí được khuyến khích.

+3

Ngay cả các lập trình viên C cũng không biết ném tất cả mọi thứ vào một nơi. –

Các vấn đề liên quan