Q:

OOP: Application architecture issues

(Nothing serious in this question)
Ones a time I've read such an example of "bad application architecture":
There was a "rendering application" (browser, as far as I remember), so it was told, that having "render()" method in TagA, TagUL, TagDIV classes is really bad practice, because you'll have lots of "render-code" smeared all around. So (in this example), they adviced to have RenderA, RenderUL, RenderDIV classes that would implement rendering. And tag-objects would incapsulate those renderers.
I can't understand why that's a bad practice. In this case we'll have lot's of render code smeared around Render-* objects. And, finaly, why not to have Redner-singleton with lot's of overriden methods? That sounds, at least, cheaper.
What to read to understand it better?

A:

Will the rendering for all of these different objects be the same? If so, then it should only be implemented once, most likely in a base class. This would be a better solution than a Singleton, which serves a completely different purpose: mainly to implement a resource (notice its a resource, not a method) that should only exist once.
If each implementation of render() will be different (which is most likely the case) then there is nothing wrong with them being implemented in separate objects, this is called polymorphism. What should probably be done though, is to have a class hierarchy in which the render() method is defined in the base class (most likely as abstract) and implemented in the derived classes. This effectively formalizes the interface, meaning that any class that inherits from said base class will have the render() method available and will have to implement it.
If you have parts of the render code that are common, and parts that are specific to the derived classes, instead of having to duplicate the common parts in all the derived class implementations, you can use a Template Method pattern, whereby the base class method does the common parts, and orchestrates calling the derived class implementation(s). Here is a pseudo-code example in C++
class TagBase {
public:
    void render() {
        // do some common stuff here
        doRender();
        // do some more common stuff here
    }

    virtual void doRender() = 0;
    ....
};

class TagA : public TagBase {
public:
    virtual void doRender() {
        // do your specific stuff here
    }
};

Here are a few good books:

Design Patterns, Gang of Four
Head First Design Patterns
Head First Object Oriented Analysis and Design

