Книги онлайн и без регистрации » Разная литература » Интернет-журнал "Домашняя лаборатория", 2007 №9 - Журнал «Домашняя лаборатория»

Интернет-журнал "Домашняя лаборатория", 2007 №9 - Журнал «Домашняя лаборатория»

Шрифт:

-
+

Интервал:

-
+

Закладка:

Сделать
1 ... 321 322 323 324 325 326 327 328 329 ... 415
Перейти на страницу:
без аргументов, вычисляющую значение этого поля всякий раз, когда это значение понадобится. Решение дилеммы — это вечный для программистов выбор между памятью и временем. Если предпочесть поле, то это приводит к дополнительным расходам памяти. Они могут быть значительными, когда создается большое число объектов — ведь свое поле должен иметь каждый объект. Если предпочесть функцию, то это потребует временных затрат на вычисление значения, и затраты могут быть значительными в сравнении с выбором текущего значения поля.

Если бы синтаксис описания метода допускал отсутствие скобок у функции (метода), в случае, когда список аргументов отсутствует, то клиент класса мог бы и не знать, обращается ли он к полю или к методу. Такой синтаксис принят, например, в языке Eiffel. Преимущество этого подхода в том, что изменение реализации никак не сказывается на клиентах класса. В языке C# это не так. Когда мы хотим получить длину строки, то пишем s.Length, точно зная, что Length — это поле, а не метод класса string. Если бы по каким-либо причинам разработчики класса String решили изменить реализацию и заменить поле Length соответствующей функцией, то ее вызов имел бы вид s.Length().

Пример: две версии класса Account

Проиллюстрируем рассмотренные выше вопросы на примере проектирования классов Account и Account 1, описывающих такую абстракцию данных, как банковский счет. Определим на этих данных две основные операции — занесение денег на счет и снятие денег. В первом варианте — классе Account — будем активно использовать поля класса. Помимо двух основных полей credit и debit, хранящих приход и расход счета, введем поле balance, которое задает текущее состояние счета, и два поля, связанных с последней выполняемой операцией. Поле sum будет хранить сумму денег текущей операции, а поле result — результат выполнения операции. Полей у класса много, и как следствие, у методов класса аргументов будет немного. Вот описание нашего класса:

/// <summary>

/// Класс Account определяет банковский счет. Простейший

/// вариант с возможностью трех операций: положить деньги

/// на счет, снять со счета, узнать баланс. Вариант с полями

/// </summary>

public class Account

{

    //закрытые поля класса

    int debit=0, credit=0, balance =0;

    int sum =0, result=0;

    /// <summary>

    /// Зачисление на счет с проверкой

    /// </summary>

    /// <param name="sum">зачисляемая сумма</param>

    public void putMoney(int sum)

    {

        this.sum = sum;

        if (sum >0)

    {

              credit += sum; balance = credit — debit; result =1;

     }

     else result = -1;

     Mes ();

   }//putMoney

   /// <summary>

   /// Снятие со счета с проверкой

   /// </summary>

   /// <param name="sum"> снимаемая сумма</param>

   public void getMoney(int sum)

   {

         this.sum = sum;

         if(sum <= balance)

         {

            debit += sum; balance = credit — debit; result =2;

         }

         else result = -2;

         Mes ();

    }//getMoney

    /// <summary>

    /// Уведомление о выполнении операции

    /// </summary> void Mes()

    {

        switch (result)

        {

             case 1:

                Console.WriteLine("Операция зачисления денег прошла успешно!");

                Console.WriteLine("Сумма={0},

                      Ваш текущий баланс={1}",sum, balance);

                break;

             case 2:

                 Console.WriteLine("Операция снятия денег прошла успешно!");

                 Console.WriteLine("Сумма={0},

                       Ваш текущий баланс={1}", sum,balance);

                 break;

             case -1:

                  Console.WriteLine("Операция зачисления денег не выполнена!");

                  Console.WriteLine("Сумма должна быть больше нуля!");

                  Console.WriteLine("Сумма={0},

                       Ваш текущий баланс={1}", sum,balance);

                   break;

             case -2:

                  Console.WriteLine("Операция снятия денег не выполнена!");

                  Console.WriteLine("Сумма должна быть не больше баланса!");

                  Console.WriteLine("Сумма={0},

                      Ваш текущий баланс={1}", sum,balance);

                  break;

             default:

                  Console.WriteLine("Неизвестная операция!");

                  break;

         }

    }

}//Account

Как можно видеть, только у методов getMoney и putMoney имеется один входной аргумент. Это тот аргумент, который нужен по сути дела, поскольку только клиент может решить, какую сумму он хочет снять или положить на счет. Других аргументов у методов класса нет — вся информация передается через поля класса. Уменьшение числа аргументов приводит к повышению эффективности работы с методами, так как исчезают затраты на передачу фактических аргументов. Но за все надо платить. В данном случае, усложняются сами операции работы со вкладом, поскольку нужно в момент выполнения операции обновлять значения многих полей класса. Закрытый метод Mes вызывается после выполнения каждой операции, сообщая о том, как прошла операция, и информируя клиента о текущем состоянии его баланса.

А теперь спроектируем аналогичный класс Account1, отличающийся только тем, что у него будет меньше полей. Вместо поля balance в классе появится соответствующая функция с этим же именем, вместо полей sum и result появятся аргументы у методов, обеспечивающие необходимую передачу информации. Вот как выглядит этот класс:

/// <summary>

/// Класс Account1 определяет банковский счет.

/// Вариант с аргументами и функциями

/// </summary>

public class Account1

{

    //закрытые поля класса

    int debit=0, credit=0;

    /// <summary>

    /// Зачисление на счет с проверкой

    /// </summary>

    /// <param name="sum">зачисляемая сумма</param>

    public void putMoney(int sum)

    {

        int res =1;

        if (sum >0)credit += sum;

        else res = -1;

        Mes(res,sum);

     }//putMoney

     /// <summary>

     /// Снятие со счета с проверкой

     /// </summary>

     /// <param name="sum"> снимаемая сумма</param>

     public void getMoney(int sum)

     {

          int res=2;

          if(sum <= balance())debit += sum;

          else res = -2;

          balance();

          Mes(res, sum);

     }//getMoney

/// <summary>

/// вычисление баланса

/// </summary>

/// <returns>тeкyщий бaлaнc</returns>

     int balance()

     {

          return(credit — debit);

     }

     /// <summary>

     /// Уведомление о выполнении операции

     /// </summary>

     void Mes(int result, int sum)

     {

          switch (result)

     {

              case 1:

                  Console.WriteLine("Операция зачисления денег прошла успешно!");

                  Console.WriteLine("Сумма={0},

1 ... 321 322 323 324 325 326 327 328 329 ... 415
Перейти на страницу:

Комментарии
Минимальная длина комментария - 20 знаков. В коментария нецензурная лексика и оскорбления ЗАПРЕЩЕНЫ! Уважайте себя и других!
Комментариев еще нет. Хотите быть первым?