Design Pattern – Template Method

In this time, I will explain about one of design pattern that you can apply when developing a software. Yep, the pattern is called by Template Method. I also applied Template Method pattern when developing our project. In a simple explanation, Template Method is a pattern where there’s an abstract class that contains template(s) to execute its methods then its subclasses can override the method implementation as what’s needed.

More formally, the definition of Template Method pattern is provided in the original Gang of Four book on Design Patterns:

Defines the skeleton of an algorithm in a method, deferring some steps to subclasses. Template Method lets subclasses redefine certain steps of an algorithm without changing the algorithms structure.

Quoting from here, the background to use this pattern is,

Two different components have significant similarities, but demonstrate no reuse of common interface or implementation. If a change common to both components becomes necessary, duplicate effort must be expended.

By inspiring with the background and the definition of Template Method pattern, I also applied that pattern with some of modification. The reason I created a modification is because I applied the pattern on writing React code using ES6 which there’s no actually a real abstract class like the Java provides. Instead of writing an abstract class, I wrote a super class which contains the based properties and behavior that the component has, then by inherit from it, I can expand the implementation and override what’s different.

So, this pattern is used when I created a dropdown component. There are two kind of dropdown that our project has. The first one is the original dropdown with its default behavior like containing a list of text menu. In the other hand, the second one is the dropdown that has customized content for displaying user’s photo, user’s name, and logout button. Actually, those two components have same behavior, don’t they? Dropdown behavior is just like it is, it has dropdown button which when you click it, an object which typically a box will appeared below the button that you click. That object has a specific content regarding to dropdown title contained in dropdown button.

So, here’s the code for the parent class, the original dropdown,

import onClickOutside from 'react-onclickoutside';
import React from 'react';
import DropdownButton from './DropdownButton.jsx';
import DropdownItem from './DropdownItem.jsx';

export class Dropdown extends React.Component {
  constructor(props) {
    super(props);

    this.handleClick = this.handleClick.bind(this);

    this.state = {
      opened: false,
    };
  }

  handleClick() {
    this.setState(
      {
        opened: !this.state.opened,
      },
    );
  }

  handleClickOutside() {
    this.setState(
      {
        opened: false,
      },
    );
  }

  render() {
    const content = this.state.opened ? (
      <ul className="dropdown__menu">
        {this.props.menuItems.map(item =>
          <DropdownItem key={item.link} text={item.text} link={item.link} />,
        )}
      </ul>) : null;

    return (
      <div className="dropdown">
        <DropdownButton
          active={this.state.opened}
          title={this.props.title}
          onClick={this.handleClick}
        />
        {content}
      </div>
    );
  }

}

Dropdown.propTypes = {
  menuItems: React.PropTypes.arrayOf(React.PropTypes.object),
  title: React.PropTypes.string,
};

Dropdown.defaultProps = {
  menuItems: [],
  title: 'Dropdown',
};

export default onClickOutside(Dropdown);

Then by inherit the original dropdown, the user dropdown can have similar behavior like what the actual dropdown behaves but with customized content,

import onClickOutside from 'react-onclickoutside';
import React from 'react';
import { Dropdown } from './Dropdown.jsx';
import UserDropdownButton from './UserDropdownButton.jsx';

export class UserDropdown extends Dropdown {
render() {
const content = this.state.opened ? (
<div className="dropdown__content u__padding-top--4 u__padding-bottom--4">
<div className="row">
<div className="col col--8">
<img className="avatar__image" src={this.props.image} alt="user" />
</div>
</div>
<divc className="row">
<div className="col col--12 u__align--center">
<div className="u__margin-top--1 u__margin-bottom--2">
<strong>{this.props.name}</strong>
</div>
<a href="/logout" className="btn btn--small">Logout</a>
</div>
</divc>
</div>
) : null;

return (
<div className="dropdown">
<UserDropdownButton
active={this.state.opened}
image={this.props.image}
onClick={this.handleClick}
/>
{content}
</div>
);
}

}

UserDropdown.propTypes = {
name: React.PropTypes.string,
image: React.PropTypes.string,
};

UserDropdown.defaultProps = {
name: '',
image: '',
};

export default onClickOutside(UserDropdown);

As you can see the user dropdown code above, instead of extends from React.Component, the user dropdown extends class Dropdown. Here’s the screenshot that tells the only difference between original dropdown and the user dropdown,

Screenshot from 2017-05-17 12:29:50
Original Dropdown
Screenshot from 2017-05-17 12:29:01
User Dropdown

So, what if I didn’t use Template Method for creating the dropdown? Yep, there will be many duplicate codes and lines and also I have to spend duplicate effort to create the user dropdown which actually I ever spent it before. I would spend similar effort twice. Well, I think this is enough for explaining the Template Method, see you in the next post! 😀

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s