Design Pattern – Publish-Subscribe

On my last post, I’ve talked one of design patterns, which is Template Method. Now I want to talk about other design pattern which is Publish-Subscribe. I used this pattern to make a communication between React components which are not directly related.

As quoting from here,

The pattern works using a middleman; an agent that bridges publishers and subscribers. Publishers are the objects that fire events when they are done doing some processing and subscribers are objects who wish to be notified when the publisher is done – i.e. they are interested in the work of publishers.

Well the main advantage of using this pattern is loose coupling. We don’t need to find ways to link between component, we can publish the message or event from one component then the message or event will be subscribed by other component(s). But unfortunately the publishers don’t know about status of subscribers and vice versa. You may not be sure whether everything’s alright or not.

There are two React component that I created and they implemented this pattern. The first is ProjectList component and the second is EditButton component. The ProjectList needs an edit button so user can edit list of project that they want to be displayed on home page. Before I implemented this pattern, I inserted an edit button object inside ProjectList component. It made the ProjectList component bloated and not cohesive enough. The ProjectList component would have other thing to be focused. Therefore, I took out the edit button object, separated it to be another component.

Then after separating the edit button object as own EditButton component, those two components need to communicate between each others. The EditButton component needs to tell the ProjectList if any click event happens. Yep, Publish-Subscribe pattern solves this problem. By implement that pattern, now those two component can communicate.

I implemented this pattern using the help from PubSubJS, you can install it by doing,

npm install pubsub-js

Here’s the sample of publisher part which is EditButton component,

import React from 'react';
import PubSub from 'pubsub-js';

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

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

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

handleClick() {
this.setState({
editMode: !this.state.editMode,
});
PubSub.publish('EDIT PROJECT LIST'); // publish event
}

...
}

Yep, after creating publisher, I need to create subscriber which is ProjectList component,

import React from 'react';
import PubSub from 'pubsub-js';
import Select from 'react-select';
import Alert from './Alert.jsx';
import Loader from './Loader.jsx';
import ProjectCard from './ProjectCard.jsx';

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

    ...

    this.state = {
      projects: this.props.projects,
      editMode: false,
      watchedProjects: this.props.watchedProjects,
      projectPHID: '',
      sendingRequest: false,
      hasError: false,
      error: {},
    };
  }

  componentWillMount() {
// subscribe event and do subscriber() function
    this.token = PubSub.subscribe('EDIT PROJECT LIST', this.subscriber.bind(this));
  }

  componentWillUnmount() {
    PubSub.unsubscribe(this.token);
  }
// function need to be executed if any event subscribed happens
  subscriber() {
    this.setState({
      editMode: !this.state.editMode,
    });
  }
  ...
}

It looks not really hard, isn’t it? Well, I think it’s enough for this post, bye! 😀

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