Является ли нормой практика иметь член ClientBundle в содержащем ClientBundle?
В моем приложении у меня есть MyAppResources
, который будет в основном содержать пользовательские стили для приложения. Я думаю о том, что является хорошим способом применения пользовательских стилей к стандартным виджетам, таким как CellTable, наряду с пользовательскими стилями на макете и пользовательскими виджетами?
Мой вопрос: так как MyAppResources является одиночным (это не обязательно должно быть, как упоминалось в других постах), но CellTableResources
нет, и CellTableResources
является членом этого экземпляра, который также расширяет интерфейс ClientBundle
Будет ли прокси "CellTableResources" создаваться на каждом MyAppResources.INSTANCE.cellTableResources().foo()
?
Если так, могу ли я создать MyAppResources.CELLTABLE_RESOURCE_INSTANCE
обойти это? Или создание прокси будет незначительным, даже если есть многочисленные призывы к MyAppResources.INSTANCE.cellTableResources().#
?
Во-вторых, еще вопрос для обсуждения: что является наилучшей практикой в отношении использования нескольких ClientBundle
в этом случае? Должен ли я вместо этого использовать CellTableResources
отдельно (удалите его из MyAppResources
), с помощью GWT.create(CellTableResources.class);
в виджете, который нуждается в этом (или используя синглтон, как у меня для MyAppResources
)?
MyAppResources
:
public interface MyAppResources extends ClientBundle {
public static final MyAppResources INSTANCE = GWT.create(MyAppResources.class);
@Source("MyAppStyles.css")
public MyAppCssResource css();
public CellTableResources cellTableResources();
}
CellTableResources
:
public interface CellTableResources extends CellTable.Resources {
interface CellTableStyle extends CellTable.Style {
}
@Override
@Source({ CellTable.Style.DEFAULT_CSS, "CellTableStyles.css" })
CellTableStyle cellTableStyle();
@Source("green_light.png")
ImageResource getGreenLight();
//...
}
Спасибо за чтение.
1 ответ
Вопрос из нескольких частей, поэтому я попытаюсь ответить на этот вопрос в нескольких частях:
Какова стоимость GWT.create()
?
Большинство из GWT
класс - это "магия", то, что вы не можете написать для себя другими способами, так как они вызывают компилятор, чтобы заполнить для вас конкретные детали. Они часто отличаются при работе в режиме разработки и скомпилированы в JS.
В случае GWT.create
получается, что это скомпилировано в new
- он используется только для создания новых экземпляров. Так какова стоимость нового экземпляра по сравнению с синглтоном? Это полностью зависит от создаваемого объекта. Если в объекте нет полей, тогда стоимость по существу бесплатна - фактически, компилятор может на самом деле удалить вызов конструктора и переписать все последующие методы как static
тем не мение!
Это то, что происходит в большинстве случаев - GWT.create
следует считать очень дешевым, если только вы не делаете глупости, например, вызываете это в цикле, который запускается много раз.
Что происходит, когда я перечисляю ClientBundle
метод внутри другого ClientBundle
?
Ну, что происходит, когда вы перечисляете что-нибудь внутри ClientBundle
?
Все, что может быть указано в ClientBundle, должно быть отмечено @ResourceGeneratorType
, указывая, как создать этот тип. Например, вот ImageResource
:
/**
* Provides access to image resources at runtime.
*/
@DefaultExtensions(value = {".png", ".jpg", ".gif", ".bmp"})
@ResourceGeneratorType(ImageResourceGenerator.class)
public interface ImageResource extends ResourcePrototype {
//...
Призывает ImageResourceGenerator
создавать изображения по мере необходимости. Любой класс, описанный в этой аннотации, должен реализовывать com.google.gwt.resources.ext.ResourceGenerator
, который описывает, как подготовиться к работе, как создать необходимые поля, как их инициализировать и как завершить.
Так как же это выглядит для самого ClientBundle? Проверять, выписываться com.google.gwt.resources.rg.BundleResourceGenerator
- это очень простой класс, который просто вызывает GWT.create()
по типу данного метода. Таким образом, предсказуемо, это означает, что эти "дочерние" ClientBundles создаются с помощью GWT.create, более или менее так же, как вы могли бы сделать в противном случае.
Хорошо, что это значит в данном конкретном случае?
Оказывается, что экземпляры ClientBundles не имеют полей, из которых они отслеживают вновь созданные объекты, но вместо этого имеют статические элементы, которые они используют вместо этого - эффективно одиночные. Это означает, что после того, как вы вызвали метод один раз, экземпляр, который он возвращает, будет таким же, как при следующем вызове. Разумеется, два разных ClientBundle с одинаковым содержимым будут сохранять две разные копии объектов, но не имеет значения, сколько раз вы создаете ClientBundle - его внутренние компоненты всегда будут одинаковыми.
Что-нибудь еще?
Ага! Помните, что здесь вы имеете дело с интерфейсами, а не с классами, поэтому вы можете расширять несколько раз за раз!
public interface MyAppResources extends
ClientBundle,
CellTable.Resources,
CellTree.Resources {//etc
//...
Теперь, если два интерфейса описывают одни и те же методы, у вас могут возникнуть проблемы, но если нет, то это может обеспечить преимущество при генерировании изображений со ссылками. Каждый человек ClientBundle
будет рисовать на своем собственном пуле изображений при подготовке их к использованию - если у вас есть ClientBundle
в пределах ClientBundle
они не будут работать вместе, чтобы спрайт изображения на большие куски. Чтобы получить это, вам нужно сделать только один ClientBundle
тип. Это может не иметь значения в вашем конкретном случае, но я решил, что это также стоит упомянуть.