For a small system that can get a String and output an HTML, what design pattern would be suitable?
This is a small example:
public String makeStrong(String in) {
return "<strong>" + in + "</strong>";
}
Of course it needs to model some hierarchical structure so that it can fit <ul>
and <ol>
and their children. I'm thinking of Decorator but Composite pattern sounds good too. What should I consider?
Design patterns are common in programming, such as in object-oriented programming. In HTML / CSS , design patterns are those that work across browsers and devices. They manage complexity, mitigate code bloat, and improve productivity.
The Singleton Design Pattern That prevents multiple instances from being active at the same time which could cause weird bugs. Most of the time this gets implemented in the constructor. The goal of the singleton pattern is typically to regulate the global state of an application.
Design patterns provide a standard terminology and are specific to particular scenario. For example, a singleton design pattern signifies use of single object so all developers familiar with single design pattern will make use of single object and they can tell each other that program is following a singleton pattern.
On first glance I thought of a Builder pattern or better a fluent API. A bit more compact is the following:
import static a.b.c.HTML.*;
String html = p(
ol(
li(),
li(
_("Hello, "),
strong(_("World")),
_("!")
),
li()
)
).toString();
public class HTML {
protected final String tag;
private final HTML[] items;
public HTML(String tag, final HTML... items) {
this.tag = tag;
this.items = items;
}
public static HTML _(String text) {
return new HTML(text) {
@Override
public String toString() {
return tag;
}
@Override
protected void buildString(StringBuilder sb) {
sb.append(tag);
}
};
}
public static HTML li(final HTML... items) {
return new HTML("li", items);
}
public static HTML ol(final HTML... items) {
return new HTML("ol", items);
}
public static HTML p(final HTML... items) {
return new HTML("p", items);
}
public static HTML strong(final HTML... items) {
return new HTML("strong", items);
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
buildString(sb);
return sb.toString();
}
protected void buildString(StringBuilder sb) {
sb.append('<').append(tag);
if (items.length == 0) {
sb.append(" />");
} else {
sb.append('>');
for (HTML item : items) {
item.buildString(sb);
}
sb.append("</").append(tag).append('>');
}
}
}
Consider the builder pattern for building validated HTML fragments. I wrote something similar to validate HTML for use in Swing app components, e.g. tooltips. Here's a rough skeleton of something you could build on:
public final class HtmlBuilder()
{
private final StringBuilder sb = new StringBuilder();
private final Deque tagStack = new ArrayDeque();
public HtmlBuilder()
{
startTag("html");
}
// Consider using an enum of valid tags and extending to support attributes
public HtmlBuilder startTag( String tag )
{
// TODO preconditions
tagStack.push( tag );
sb.append('<').append(tag).append('>');
return this;
}
public HtmlBuilder endTag( String tag )
{
// TODO preconditions,
// e.g. check "!tagStack.isEmpty() && tagStack.peek().equals( tag )
tagStack.pop();
sb.append('<').append('/').append(tag).append('>');
return this;
}
public HtmlBuilder append( String text )
{
// TODO Preconditions, check for/escape special characters etc
sb.append( text );
return this;
}
@Override
public String toString()
{
endTag("html")
return sb.toString();
}
}
Simple use case:
String html = new HtmlBuilder()
.startTag( "strong" ).append( "text" ).endTag( "strong" )
.toString();
You could add as much validation as you like, e.g. defining "tr" as only being allowed inside a "table". I suspect there is something like this out there already.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With