You have your inheritance chain and you want to modify the base implementation on a per project base while still keeping the common code and types (and not being forced to severely modify the existing projects) The way to go is to decouple the common functionality from project specific customizations. Use the decorator pattern which even enables you to share customizations between projects You situation is for all existing projects: A a() B->a(), B->b() C->a(), C->b(), C->c() Your new project (lets say project 1) shall have: A1 a(), A1->a1(), B->a(), B->a1(), B->b() C->a(), C->a1(), C->b(), C->c() The decorator pattern requires you to create a decorator for each object you want to extend (A1, B1, C1). You want the custom methods of A1 also available in your decorating B1 and C1, so you need to chain them the same way as the original classes A1 decorates A B1 decorates B C1 decorates C A1 a1() B1->a1() C1->a1() You still want the functionality of A, B, C also in your decorating classes, so you need to create a link between each decorator and its decorating source class and delegate the appropriate methods: A1 hosts a reference of A B1 hosts a reference of B C1 hosts a reference of C A1->a() ----> $this->myA->a(); B1->a() ----> $this->myB->a(); B1->b() ----> $this->myB->b() All custom project 1 methods are executed directly: A1->a1() ----> $this->a1() In your new project 1 you use then: A1 instead of A B1 instead of B C1 instead of C Your A1, B1 and C1 dec0 be allowed to create their instances of A, B, C right in their constructor although you could pass the instances to enable multiple decorations.In that case you will need proper interfaces, lets say IA, IB, IC.
Then your A1 could have the method setA(IA theA) where theA might be an exact A or even an A1 or A2 or A3 ... But this is more advanced and you will find more information by googling the decorator pattern and you perhaps need a little bit of experience with interfaces and polymorphy Altogether: Leave your inheritance chain as it is Create a decorator chain for each custom project Link the decorators to their original class and delegate the common functionality Use the decorators instead of the original classes in your custom project. They are now identical to their originals plus have the additional methods you want to add.
You have your inheritance chain and you want to modify the base implementation on a per project base while still keeping the common code and types (and not being forced to severely modify the existing projects). The way to go is to decouple the common functionality from project specific customizations. Use the decorator pattern which even enables you to share customizations between projects.
You situation is for all existing projects: A a() B->a(), B->b() C->a(), C->b(), C->c() Your new project (lets say project 1) shall have: A1 a(), A1->a1(), B->a(), B->a1(), B->b() C->a(), C->a1(), C->b(), C->c() The decorator pattern requires you to create a decorator for each object you want to extend (A1, B1, C1). You want the custom methods of A1 also available in your decorating B1 and C1, so you need to chain them the same way as the original classes. A1 decorates A B1 decorates B C1 decorates C A1 a1() B1->a1() C1->a1() You still want the functionality of A, B, C also in your decorating classes, so you need to create a link between each decorator and its decorating source class and delegate the appropriate methods: A1 hosts a reference of A B1 hosts a reference of B C1 hosts a reference of C A1->a() ----> $this->myA->a(); B1->a() ----> $this->myB->a(); B1->b() ----> $this->myB->b(); All custom project 1 methods are executed directly: A1->a1() ----> $this->a1(); In your new project 1 you use then: A1 instead of A B1 instead of B C1 instead of C Your A1, B1 and C1 dec0 be allowed to create their instances of A, B, C right in their constructor although you could pass the instances to enable multiple decorations.In that case you will need proper interfaces, lets say IA, IB, IC.
Then your A1 could have the method setA(IA theA) where theA might be an exact A or even an A1 or A2 or A3 ... But this is more advanced and you will find more information by googling the decorator pattern and you perhaps need a little bit of experience with interfaces and polymorphy. Altogether: Leave your inheritance chain as it is Create a decorator chain for each custom project Link the decorators to their original class and delegate the common functionality. Use the decorators instead of the original classes in your custom project.
They are now identical to their originals plus have the additional methods you want to add.
Thanks Jens, while I've probably done things slightly differently, this is basically how I solved it... although I do find that the more I use object orientated programming, the more complicated solutions you seem to need to use (maybe that's just me though). – Craig Francis Aug 25 at 10:48.
It depends what you want to do with the help text. Perhaps, though you could do it like this: 1 - Create the help text object for the purposes you desire. 2 - Create an optional constructor parameter in your form_field_base class.
If set, it would be a private instance of the help text class. 3 - Inside your subclasses, check for the existence of the help text object. If it is set, perform the additional action.
Perhaps this is not suitable for what you're trying to do, though. Without being more sure, though, that's the best I could come up with!
Different ways, I'm sure there will be other random (one off) features appearing in the future which will also need this kind of editing. – Craig Francis Aug 18 at 10:06.
If you already have a nice base class for all form fields that does well without any help text, then leave it as it is. Instead, make a class that will represent a component of the form. This can be a higher level of abstraction: abstract class FormComponent { public __construct(FormField $field) { $this->_field = $field; } public html() { // Here you can choose any way to integrate the field's input HTML into // the component's HTML.
You can wrap it in a label, for example. Return $self->_get_html() . $self->_field->html_input(); } } UPDATE: You don't have to touch the form_field inheritance chain, you can leave it as it is.
If you do it this way, you will have to inject your instantiated field objects into the component class like this: $field = new form_field_email($arguments); // Whatever arguments it takes // Here the FormComponent_Email class inherits the FormComponent class $component = new FormComponent_Email($field); $component->set_hint('Some hint'); // Set your help text here $component->set_label('Enter your email'); // You can even add an error container if you wish if ($some_email_error) { $component->set_error('Your email has an error! '); } $component_html = $component->html(); Here inside the html method of the email component class you can add HTML wrapping to the field that will display the label, the hint container, the error container and everything else that you need.
This does sound very interesting... I'm just going to look at the documentation, but do you have more of an example on how this would work... if your saying that I could drop the "extends form_field_base" from the text/email/file/etc classes, so that they can somehow inherit from either that class, or another (custom) one which in turn inherits from form_field_base, then that would be great. – Craig Francis Aug 18 at 10:10 I have updated the answer, see the code snippet. See how you use your regular form object and pass it into the constructor of the new object.
– Igor Zinov'yev Aug 18 at 11:50 1 Just wanted to say thank you for the example, in the end I didn't use this method because adding an extra wrapper to every field (the project contains a few hundred fields), but it's a good solution which may help in other projects. – Craig Francis Aug 25 at 10:46 You're welcome, sure, use whatever fits your case the best. – Igor Zinov'yev Aug 26 at 17:18.
I cant really gove you an answer,but what I can give you is a way to a solution, that is you have to find the anglde that you relate to or peaks your interest. A good paper is one that people get drawn into because it reaches them ln some way.As for me WW11 to me, I think of the holocaust and the effect it had on the survivors, their families and those who stood by and did nothing until it was too late.