Чтение онлайн

на главную - закладки

Жанры

Философия Java3

Эккель Брюс

Шрифт:

new Class[]{ SomeMethods.class }. new MethodSelector(new Implementation))); proxy.boringlO; proxy.boring2; proxy.i nteresti ng("bonobo"); proxy.boring3;

}

} /* Output:

boringl

boring2

Посредник обнаружил интересный метод interesting bonobo boring3 *///:-

В данном случае мы просто проверяем имена методов, но с таким же успехом можно анализировать другие аспекты сигнатуры и даже значения аргументов.

Вряд ли вам придется каждый день пользоваться динамическими посредниками, но они хорошо подходят для решения многих разновидностей задач.

Объекты с неопределенным состоянием

Если использовать для обозначения неопределенного состояния (то есть отсутствия) объекта встроенное значение null, то при каждом использовании ссылки придется проверять, не равна ли она null. Это быстро утомляет, а код получается излишне громоздким. Проблема заключается в том, что null не имеет собственного поведения, кроме выдачи NullPointerException при попытке выполнения с ним какой-либо операции. Иногда бывает полезно ввести понятие объекта с неопределенным состояниемкоторый принимает сообщения, но возвращает значение, свидетельствующее об отсутствии «настоящего» объекта. Таким образом, вы можете считать, что все объекты действительны, и вам не придется тратить время на проверки null (и читать полученный код).

Было бы интересно представить себе язык программирования, автоматически создающий объекты с неопределенным состоянием, но на практике они применяются не так уж часто — иногда проверки null оказывается достаточно, иногда можно уверенно считать, что значение null вам не попадется, а иногда даже обработка аномальных ситуаций через NullPointerException является допустимой. Наибольшую пользу объекты с неопределенным состоянием приносят «вблизи от данных», представляя сущности в пространстве задачи. Простой пример: во многих системах имеется класс Person, а в коде возникают ситуации, когда объект не представляет конкретную личность (или, по крайней мере, информация о ней недоступна); при традиционном подходе вам следовало бы проверить ссылку null. Также можно воспользоваться объектом с неопределенным состоянием, но, даже несмотря на то, что такой объект будет отвечать на все сообщения, на которые отвечает «настоящий» объект, все равно потребуется способ проверки его на «определенность». Проще всего определить для этого специальный интерфейс:

//. net/mindview/uti1/Null java package net.mindview util; public interface Null {} ///•-

Это позволяет instanceof обнаруживать объекты с неопределенным состоянием и, что еще важнее, не требует включения метода isNull во все классы (в конце концов, это фактически будет другим способом выполнения RTTI — так почему бы сразу не воспользоваться встроенными средствами?):

// typeinfo/Person java

// Класс с неопределенным состоянием объекта

import net mindview util.*;

class Person {

public final String first; public final String last; public final String address; // И т д.

public Person(String first. String last, String address){ this.first = first;

1 Идея принадлежит Бобби Вульфу (Bobby Woolf) и Брюсу Андерсону (Bruce Anderson).

this.last = last; this.address = address;

}

public String toStringO {

return "Person: " + first + " " + last + " " + address;

}

public static class NullPerson extends Person implements Null {

private NullPerson^) { super("None". "None". "None"); } public String toStringO { return "NullPerson"; }

}

public static final Person NULL = new NullPersonO;

} ///:-

В общем случае объект с неопределенным состоянием является синглетным, поэтому он создается как экземпляр static final. Это возможно благодаря тому, что объект Person неизменяем — значения задаются в конструкторе, а затем читаются, но не могут изменяться (поскольку поля String по своей природе неизменяемы). Если вы захотите изменить NullPerson, его придется заменить новым объектом Person. Обратите внимание: для обнаружения обобщенной поддержки Null или более конкретного типа NullPerson можно использовать instanceof, но при синглетной архитектуре можно воспользоваться просто equals или даже == для сравнения с Person.NULL.

Представьте, что вы собираетесь открыть новое предприятие, но, пока вакансии еще не заполнены, в каждой должности Position можно временно хранить «заполнитель» — объект Person с неопределенным состоянием:

//• typeinfo/Position.java

class Position {

private String title; private Person person;

public Position(String jobTitle. Person employee) { title = jobTitle; person = employee; if(person == null)

person = Person.NULL;

}

public Position(String jobTitle) { title = jobTitle; person = Person.NULL;

}

public String getTitleO { return title; } public void setTitle(String newTitle) { title = newTitle;

}

public Person getPersonО { return person; } public void setPerson(Person newPerson) { person = newPerson. if(person == null)

person = Person.NULL;

}

public String toStringO {

return "Position: " + title + " " + person; продолжение &

}

} ///:-

Превращать Position в объект с неопределенным состоянием не обязательно, потому что существование Person.NULL подразумевает неопределенность Position (возможно, позднее выяснится, что явная поддержка неопределенного состояния для Position нужна, и вы добавите ее, но в соответствии с одним из канонов экстремального программирования в начальный проект следует включить «простейшее решение, которое будет работать», и включать новые функции лишь по мере возникновения реальной необходимости).

Теперь класс Staff может проверять объекты с неопределенным состоянием при заполнении вакансий:

//: typeinfo/Staff.java

import java util.*;

public class Staff extends ArrayList<Position> {

public void addCString title, Person person) { add(new PositionCtitle, person)),

}

public void add(String.. titles) { for(String title : titles)

add(new PositionCtitle));

}

public StaffCString. titles) { add(titles); }

public boolean positionAvailable(String title) { for(Position position : this)

if(position.getTitleO.equals(title) &&

position.getPersonO == Person.NULL) return true;

return false,

}

public void fillPosition(String title, Person hire) { for(Position position ; this)

if(position.getTitleO.equals(title) &&

position.getPersonO == Person.NULL) { position.setPerson(hire); return;

}

throw new RuntimeException(

"Position " + title + " not available");

}

public static void main(String[] args) {

Поделиться:
Популярные книги

Играть... в тебя

Зайцева Мария
3. Звериные повадки Симоновых
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Играть... в тебя

Старший лейтенант, парень боевой!

Зот Бакалавр
8. Героями не становятся, ими умирают
Фантастика:
боевая фантастика
5.00
рейтинг книги
Старший лейтенант, парень боевой!

На границе империй. Том 7. Часть 3

INDIGO
9. Фортуна дама переменчивая
Фантастика:
космическая фантастика
попаданцы
5.40
рейтинг книги
На границе империй. Том 7. Часть 3

Древесный маг Орловского княжества 6

Павлов Игорь Васильевич
6. Орловское княжество
Фантастика:
аниме
фэнтези
попаданцы
5.00
рейтинг книги
Древесный маг Орловского княжества 6

Неудержимый. Книга XXVI

Боярский Андрей
26. Неудержимый
Фантастика:
фэнтези
попаданцы
5.00
рейтинг книги
Неудержимый. Книга XXVI

Мечников. Из доктора в маги

Алмазов Игорь
1. Жизнь Лекаря с нуля
Фантастика:
альтернативная история
аниме
фэнтези
фантастика: прочее
попаданцы
5.00
рейтинг книги
Мечников. Из доктора в маги

Древесный маг Орловского княжества

Павлов Игорь Васильевич
1. Орловское княжество
Фантастика:
аниме
фэнтези
фантастика: прочее
попаданцы
5.00
рейтинг книги
Древесный маг Орловского княжества

Печать пожирателя 2

Соломенный Илья
2. Пожиратель
Фантастика:
городское фэнтези
попаданцы
аниме
сказочная фантастика
5.00
рейтинг книги
Печать пожирателя 2

Ну, здравствуй, перестройка!

Иванов Дмитрий
4. Девяностые
Фантастика:
попаданцы
альтернативная история
6.83
рейтинг книги
Ну, здравствуй, перестройка!

Беглец

Бубела Олег Николаевич
1. Совсем не герой
Фантастика:
фэнтези
попаданцы
8.94
рейтинг книги
Беглец

Ботаник

Щепетнов Евгений Владимирович
1. Ботаник
Фантастика:
фэнтези
боевая фантастика
4.56
рейтинг книги
Ботаник

Газлайтер. Том 31

Володин Григорий Григорьевич
31. История Телепата
Фантастика:
боевая фантастика
попаданцы
альтернативная история
фэнтези
5.00
рейтинг книги
Газлайтер. Том 31

Моя простая курортная жизнь

Блум М.
1. Моя простая курортная жизнь
Проза:
современная проза
5.00
рейтинг книги
Моя простая курортная жизнь

Я все еще князь. Книга XXI

Дрейк Сириус
21. Дорогой барон!
Фантастика:
юмористическое фэнтези
попаданцы
аниме
5.00
рейтинг книги
Я все еще князь. Книга XXI