| |
| |
| The factory pattern is useful, but nevertheless not suitable for Wicket components. |
| |
| *Listing 15:* |
| |
| {code} |
| public class CmsFactory { |
| public Label getCmsLabel(String markupId, final String url) { |
| IModel<String> fragment = new AbstractReadOnlyModel<String>() { |
| @Override |
| public String getObject() { |
| return loadSomeContent(url); |
| } |
| }; |
| Label result = new Label(markupId, fragment); |
| result.setRenderBodyOnly(true); |
| result.setEscapeModelStrings(false); |
| return result; |
| } |
| |
| public String loadContent(String url) { |
| // load some content |
| } |
| } |
| |
| // create the component within the page: |
| public class MyPage extends WebPage { |
| @SpringBean |
| CmsFactory cmsFactory; |
| |
| public MyPage() { |
| add(cmsFactory.getCmsLabel("id", "http://url.to.load.from")); |
| } |
| } |
| {code} |
| |
| This approach for adding a label from the @CmsFactory@ to a page seems to be okay at first glance, but it comes with some disadvantages. There is no possibility to use inheritance anymore. Furthermore, there is no possibility to override @isVisible()@ and @isEnabled()@. The factory could also be a Spring service which instanciates the component. A better solution is to create a @CmsLabel@. |
| |
| *Listing 16:* |
| |
| {code} |
| public class CmsLabel extends Label { |
| @SpringBean |
| CmsResource cmsResource; |
| public CmsLabel(String id, IModel<String> urlModel) { |
| super(id, urlModel); |
| IModel<String> fragment = new AbstractReadOnlyModel<String>(){ |
| @Override |
| public String getObject() { |
| return cmsResource.loadSomeContent(urlModel.getObject()); |
| } |
| }; |
| setRenderBodyOnly(true); |
| setEscapeModelStrings(false); |
| } |
| } |
| |
| // create the component within a page |
| public class MyPage extends WebPage { |
| public MyPage() { |
| add(new CmsLabel("id", Model.of("http://url.to.load.from"))); |
| } |
| } |
| {code} |
| |
| The label in listing 16 is clearly encapsulated in a component without using a factory. Now you can easily create inline implementations and override @isVisible()@ or other stuff. Naturally, you might claim "I need a factory to initialize some values in the component, e.g. a Spring service.". For this you can create a implementation of @IComponentInstantiationListener@. This listener gets called on the super-constructor of every component. The most popular implementation of this interface is the @SpringComponentInjector@ which injects Spring beans in components when the fields are annotated with @\@SpringBean@. You can easliy write and add your own implementation of @IComponentInstantiationListener@. So there is no reason for using a factory anymore. More information about the instanciation listener is located in Wicket's JavaDoc. |