Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
лабораторные / Лаб.раб.5С#.doc
Скачиваний:
95
Добавлен:
21.03.2015
Размер:
210.43 Кб
Скачать

Почему у методов мало аргументов?

Все дело в том, что методы класса- это не простопроцедуры; этопроцедуры, обслуживающие данные. Все поля доступны любому методу по определению. Нужно четко понимать, что в момент выполнения программной системы работа идет не склассом, а с объектами - экземплярамикласса. Из полей соответствующего объекта - цели вызова - извлекается информация, нужная методу в момент вызова, а работа метода чаще всего сводится к обновлению значений полей этого объекта. Поэтому очевидно, что методу не нужно черезвходные аргументыпередавать информацию, содержащуюся в полях. Если в результате работы метода обновляется значение некоторого поля, то, опять-таки, не нужен никакойвыходной аргумент.

Поля класса или функции без аргументов?

Поля хранят информацию о состоянии объектов класса. Состояние объекта динамически изменяется в ходе вычислений - обновляются значения полей. Часто возникающая дилемма при проектированиикласса: что лучше - создать ли поле, хранящее информацию, или создатьфункциюбез аргументов, вычисляющую значение этого поля всякий раз, когда это значение понадобится. Решение дилеммы - это вечный для программистов выбор между памятью и временем. Если предпочесть поле, то это приводит к дополнительным расходам памяти. Они могут быть значительными, когда создается большое число объектов - ведь свое поле должен иметь каждый объект. Если предпочестьфункцию, то это потребует временных затрат на вычисление значения, и затраты могут быть значительными в сравнении с выбором текущего значения поля.

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

Помимо двух основных полей creditиdebit, хранящих приход и расход счета, введем полеbalance, которое задает текущее состояние счета, и два поля, связанных с последней выполняемой операцией. Полеsumбудет хранить сумму денег текущей операции, а полеresult- результат выполнения операции.

Описание нашего класса:

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

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

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

public class Account {

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

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

int sum =0, result=0;

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

public void putMoney(int sum) {

this.sum = sum;

if (sum >0) {

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

}

else result = -1;

Mes();

}

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

public void getMoney(int sum) {

this.sum = sum;

if(sum <= balance) {

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

}

else result = -2;

Mes();

}

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

void Mes() {

switch (result) {

case 1:

Console.WriteLine("Операция зачисления денег

прошла успешно!");

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

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

break;

case 2:

Console.WriteLine("Операция снятия денег

прошла успешно!");

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

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

break;

case -1:

Console.WriteLine("Операция зачисления денег

не выполнена!");

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

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

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

break;

case -2:

Console.WriteLine("Операция снятия денег

не выполнена!");

Console.WriteLine("Сумма должна быть

не больше баланса!");

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

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

break;

default:

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

break;

}

}

}

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

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

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

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

public class Account1{

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

int debit=0, credit=0;

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

public void putMoney(int sum) {

int res =1;

if (sum >0)credit += sum;

else res = -1;

Mes(res,sum);

}

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

public void getMoney(int sum) {

int res=2;

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

else res = -2;

balance();

Mes(res, sum);

}

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

/// <returns>текущий баланс</returns>

int balance() {

return(credit - debit);

}

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

void Mes(int result, int sum) {

switch (result) {

case 1:

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

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

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

break;

case 2:

Console.WriteLine("Операция снятия денег

прошла успешно!");

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

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

break;

case -1:

Console.WriteLine("Операция зачисления денег

не выполнена!");

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

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

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

break;

case -2:

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

Console.WriteLine("Сумма должна быть

не больше баланса!");

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

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

break;

default:

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

break;

}

}

}

Сравнивая этот класссклассомAccount, можно видеть, что число полей сократилось с пяти до двух, упростились основные методыgetMoneyиputMoney. Но, в качестве платы, уклассапоявился дополнительный методbalance(), многократно вызываемый, и у методаMesтеперь появились два аргумента. Какойкласслучше? Однозначно сказать нельзя, все зависит от контекста, от приоритетов, заданных при создании конкретной системы.

ПоцедураклассаTesting, тестирующую работу склассамиAccountиAccount1:

public void TestAccounts() {

Account myAccount = new Account();

myAccount.putMoney(6000);

myAccount.getMoney(2500);

myAccount.putMoney(1000);

myAccount.getMoney(4000);

myAccount.getMoney(1000);

//Аналогичная работа с классом Account1

Console.WriteLine("Новый класс и новый счет!");

Account1 myAccount1 = new Account1();

myAccount1.putMoney(6000);

myAccount1.getMoney(2500);

myAccount1.putMoney(1000);

myAccount1.getMoney(4000);

myAccount1.getMoney(1000);

}

Соседние файлы в папке лабораторные