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

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

Жанры

Философия 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) {

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

Барон играет по своим правилам

Ренгач Евгений
5. Закон сильного
Фантастика:
попаданцы
аниме
фэнтези
фантастика: прочее
5.00
рейтинг книги
Барон играет по своим правилам

Сердце Дракона. нейросеть в мире боевых искусств (главы 1-650)

Клеванский Кирилл Сергеевич
Фантастика:
фэнтези
героическая фантастика
боевая фантастика
7.51
рейтинг книги
Сердце Дракона. нейросеть в мире боевых искусств (главы 1-650)

Герцогиня в ссылке

Нова Юлия
2. Магия стихий
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Герцогиня в ссылке

Ну привет, заучка...

Зайцева Мария
Любовные романы:
эро литература
короткие любовные романы
8.30
рейтинг книги
Ну привет, заучка...

На Ларэде

Кронос Александр
3. Лэрн
Фантастика:
фэнтези
героическая фантастика
стимпанк
5.00
рейтинг книги
На Ларэде

Сердце Дракона. Том 12

Клеванский Кирилл Сергеевич
12. Сердце дракона
Фантастика:
фэнтези
героическая фантастика
боевая фантастика
7.29
рейтинг книги
Сердце Дракона. Том 12

Истинная поневоле, или Сирота в Академии Драконов

Найт Алекс
3. Академия Драконов, или Девушки с секретом
Любовные романы:
любовно-фантастические романы
6.37
рейтинг книги
Истинная поневоле, или Сирота в Академии Драконов

Кодекс Охотника. Книга VI

Винокуров Юрий
6. Кодекс Охотника
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Кодекс Охотника. Книга VI

Гардемарин Ее Величества. Инкарнация

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

Сама себе хозяйка

Красовская Марианна
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Сама себе хозяйка

Душелов. Том 3

Faded Emory
3. Внутренние демоны
Фантастика:
альтернативная история
аниме
фэнтези
ранобэ
хентай
5.00
рейтинг книги
Душелов. Том 3

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

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

Стеллар. Заклинатель

Прокофьев Роман Юрьевич
3. Стеллар
Фантастика:
боевая фантастика
8.40
рейтинг книги
Стеллар. Заклинатель

Возвышение Меркурия. Книга 5

Кронос Александр
5. Меркурий
Фантастика:
боевая фантастика
попаданцы
аниме
5.00
рейтинг книги
Возвышение Меркурия. Книга 5