Design Patterns: An index of GoF and POSA Patterns

Knowing where to look for a design pattern or set of patterns that solve a particular problem can be time-consuming and frustrating. Here I compile all of the design patterns from the GoF book and the first two volumes of the POSA books to help you discover where to go for a deeper look.

 

Design Patterns: Elements of Reusable Object-Oriented Software

Pattern NameCategoryShort Description
Abstract FactoryCreationalProvide an interface for creating families of related or dependent objects without specifying their concrete classes.
BuilderCreationalSeparate the construction of a complex object from its representation so that the same construction process can create different representations.
Factory MethodCreationalDefine an interface for creating an object, but let subclasses decide which class to instantiate. Factory Method lets a class defer instantiation to subclasses.
PrototypeCreationalSpecify the kinds of objects to create using a prototypical instance, and create new objects by copying this prototype.
SingletonCreationalEnsure a class only has one instance, and provide a global point of access to it.
AdapterStructuralConvert the interface of a class into another interface clients expect. Adapter lets classes work together that couldn’t otherwise because of incompatible interfaces.
BridgeStructuralDecouple an abstraction from its implementation so that the two can vary independently.
CompositeStructuralCompose objects into tree structures to represent part-whole hierarchies. Composite lets clients treat individual objects and compositions of objects uniformly.
DecoratorStructuralAttach additional responsibilities to an object dynamically. Decorators provide a flexible alternative to subclassing for extending functionality.
FacadeStructuralProvide a unified interface to a set of interfaces in a subsystem. Facade defines a higher-level interface that makes the subsystem easier to use.
FlyweightStructuralUse sharing to support large numbers of fine-grained objects efficiently.
ProxyStructuralProvide a surrogate or placeholder for another object to control access to it.
Chain of ResponsibilityBehavioralAvoid coupling the sender of a request to its receiver by giving more than one object a chance to handle the request. Chain the receiving objects and pass the request along the chain until an object handles it.
CommandBehavioralEncapsulate a request as an object, thereby letting you parameterize clients with different requests, queue or log requests, and support undoable operations.
InterpreterBehavioralGiven a language, define a represention for its grammar along with an interpreter that uses the representation to interpret sentences in the language.
IteratorBehavioralProvide a way to access the elements of an aggregate object sequentially without exposing its underlying representation.
MediatorBehavioralDefine an object that encapsulates how a set of objects interact. Mediator promotes loose coupling by keeping objects from referring to each other explicitly, and it lets you vary their interaction independently.
MementoBehavioralWithout violating encapsulation, capture and externalize an object’s internal state so that the object can be restored to this state later.
ObserverBehavioralDefine a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically.
StateBehavioralAllow an object to alter its behavior when its internal state changes. The object will appear to change its class.
StrategyBehavioralDefine a family of algorithms, encapsulate each one, and make them interchangeable. Strategy lets the algorithm vary independently from clients that use it.
Template MethodBehavioralDefine the skeleton of an algorithm in an operation, deferring some steps to subclasses. Template Method lets subclasses redefine certain steps of an algorithm without changing the algorithm’s structure.
VisitorBehavioralRepresent an operation to be performed on the elements of an object structure. Visitor lets you define a new operation without changing the classes of the elements on which it operates.

Pattern-Oriented Software Architecture Volume 1

Pattern NameCategoryShort Description
LayersArchitectural: From Mud to StructureHelps to structure applications that can be decomposed into groups of subtasks in which each group of subtasks is at a particularlevel of abstraction.
Pipes and FiltersArchitectural: From Mud to StructureProvides a structure for systems that process a stream of data. Each processing step is encapsulated in a filter component. Data is passed through pipes between adjacent filters. Recombining filters allows you to build families of related systems.
BlackboardArchitectural: From Mud to StructureUseful for problems for which no deterministic solution strategies are known. In Blackboard several specialized subsystems assemble their knowledge to build a possibly partial or approximate solution.
BrokerArchitectural: Distributed SystemsCan be used to structure distributed software systems with decoupled components that interact by remote service invocations. A broker component is responsible for coordinating communication, such as forwarding requests, as well as for transmitting results and exceptions.
Model-View-ControllerArchitectural: Interactive SystemsDivides an interactive application into three components. The model contains the core functionality and data. Views display information to the user. Controllers handle user input. Views and controllers together comprise the user interface. A change-propagation mechanism ensures consistency between the user interface and the model.
Presentation-Abstraction-ControlArchitectural: Interactive SystemsDefines a structure for interactive software systems in the form of a hierarchy of cooperating agents. Every agent is responsible for a specific aspect of the application's functionality and consists of three components: presentation, abstraction, and control. This subdivision separates the human-computer interaction aspects of the agent from its functional core and its communication with other agents.
MicrokernelArchitectural: Adaptable SystemsApplies to software systems that must be able to adapt to changing system requirements. It separates a minimal functional core from extended functionality and customer-specific parts. The microkernel also serves as a socket for plugging in these extensions and coordinating their collaboration.
ReflectionArchitectural: Adaptable SystemsProvides a mechanism for changing structure and behavior of software systems dynamically. It supports the modification of fundamental aspects, such as type structures and function call mechanisms. In this pattern, an application is split into two parts. A meta level provides information about selected system properties and makes the software self-aware. A base level includes the application logic. Its implementation builds on the meta level. Changes to information kept in the meta level affect subsequent base-level behavior.
Whole-PartDesign: Structural DecompositionHelps with the aggregation of components that together form a semantic unit. An aggregate component, the Whole, encapsulates its constituent components, the Parts, organizes their collaboration, and provides a common interface to its functionality. Direct access to the Parts is not possible.
Master-SlaveDesign: Organization of WorkSupports fault tolerance, parallel computation and computational accuracy. A master component distributes work to identical slave components and computes a final result from the results these slaves return.
ProxyDesign: Access ControlMakes the clients of a component communicate with a representative rather than to the component itself. Introducing such a placeholder can serve many purposes, including enhanced efficiency, easier access and protection from unauthorized access.
Command ProcessorDesign: ManagementSeparates the request for a service from its execution. A command processor component manages requests as separate objects, schedules their execution, and provides additional services such as the storing of request objects for later undo.
View HandlerDesign: ManagementHelps to manage all views that a software system provides. A view handler component allows clients to open, manipulate and dispose of views. It also coordinates dependencies between views and organizes their update.
Forwarder-ReceiverDesign: CommunicationProvides transparent inter-process communication for software systems with a peer-to-peer interaction model. It introduces forwarders and receivers to decouple peers from the underlying communication mechanisms.
Client-Dispatcher-ServerDesign: CommunicationIntroduces an intermediate layer between clients and servers, the dispatcher component. It provides location transparency by means of a name service, and hides the details of the establishment of the communication connection between clients and servers.
Publisher-SubscriberDesign: CommunicationHelps to keep the state of cooperating components synchronized. To achieve this it enables one-way propagation of changes: one publisher notifies any number of subscribers about changes to its state.
Counted PointerMemory Mangement: C++ IdiomMakes memory management of dynamically- allocated shared objects in C++ easier. It introduces a reference counter to a body class that is updated by handle objects. Clients access body class objects only through handles via the overloaded operator->().

Pattern-Oriented Software Architecture Volume 2

Pattern NameCategoryShort Description
Wrapper FacadeService Access and ConfigurationEncapsulates the functions and data provided by existing non-object-oriented APIs within more concise, robust, portable, maintainable, and cohesive object-oriented class interfaces.
Component ConfiguratorService Access and ConfigurationAllows an application to link and unlink its component implementations at run-time without having to modify, recompile, or statically relink the application. Component Configurator further supports the reconfiguration of components into different application processes without having to shut down and re-start running processes.
InterceptorService Access and ConfigurationAllows services to be added transparently to a framework and triggered automatically when certain events occur.
Extension InterfaceService Access and ConfigurationAllows multiple interfaces to be exported by a component, to prevent bloating of interfaces and breaking of client code when developers extend or modify the functionality of the component.
ReactorEvent HandlingAllows event-driven applications to demultiplex and dispatch service requests that are delivered to an application from one or more clients.
ProactorEvent HandlingAllows event-driven applications to efficiently demultiplex and dispatch service requests triggered by the completion of asynchronous operations, to achieve the performance benefits of concurrency without incurring certain of its liabilities.
Asynchronous Completion TokenEvent HandlingAllows an application to demultiplex and process efficiently the responses of asynchronous operations it invokes on services.
Acceptor-ConnectorEvent HandlingDecouples the connection and initialization of cooperating peer services in a networked system from the processing performed by the peer services after they are connected and initialized.
Scoped LockingSynchronizationEnsures that a lock is acquired when control enters a scope and released automatically when control leaves the scope, regardless of the return path from the scope. C++ idiom.
Strategized LockingSynchronizationParameterizes synchronization mechanisms that protect a component's critical sections from concurrent access.
Thread-Safe InterfaceSynchronizationMinimizes locking overhead and ensures that intra-component method calls do not incur `self-deadlock' by trying to reacquire a lock that is held by the component already.
Double-Checked Locking OptimizationSynchronizationReduces contention and synchronization overhead whenever critical sections of code must acquire locks in a thread-safe manner just once during program execution.
Active ObjectConcurrencyDecouples method execution from method invocation to enhance concurrency and simplify synchronized access to objects that reside in their own threads of control.
Monitor ObjectConcurrencySynchronizes concurrent method execution to ensure that only one method at a time runs within an object. It also allows an object's methods to cooperatively schedule their execution sequences.
Half-Sync/Half-AsyncConcurrencyDecouples asynchronous and synchronous service processing in concurrent systems, to simplify programming without unduly reducing performance. The pattern introduces two intercommunicating layers, one for asynchronous and one for synchronous service processing.
Leader/FollowersConcurrencyProvides an efficient concurrency model where multiple threads take turns sharing a set of event sources in order to detect, demultiplex, dispatch, and process service requests that occur on the event sources.
Thread-Specific StorageConcurrencyAllows multiple threads to use one `logically global' access point to retrieve an object that is local to a thread, without incurring locking overhead on each object access.

Other Design Pattern Resources

JanusVR gstreamer 0.10 multimedia fix for Ubuntu 14.04

Unfortunately the upgrade to gstream 1.0 in Ubuntu 14.04 causes problems with some Qt apps and that means that the sound and videos won’t work with JanusVR.

For example, when entering rooms with multimedia content like the Virtual Reality Reviewer room I see the following error in my terminal:

defaultServiceProvider::requestService(): no service found for – “org.qt-project.qt.mediaplayer”

Luckily the fix is a PPA away:

sudo add-apt-repository ppa:mc3man/trusty-media
sudo apt-get update
sudo apt-get install gstreamer0.10-ffmpeg libqt5multimedia5

After the install, restart Janus hop into the VRR room and try clicking on a video to confirm it works. Now that the sound works you’re probably already sick of that wind sound, so just hit ‘m’ to mute Janus.

Sources:

http://digital-era.net/10-things-to-do-after-installing-ubuntu-14-04-trusty-tahr-to-get-a-near-perfect-desktop/
http://thebugfreeblog.blogspot.de/2014/05/ffmpeg-gstreamer-plugin-on-ubuntu-1404.html
http://qt-project.org/forums/viewthread/33877

Hanging out in Janus

Hanging out in Janus

Your first Virtual Reality Room with JanusVR and VRSites.com

If you haven’t checked out JanusVR yet then you need to stop reading and go do that now. You don’t need a rift to use it. Go!

Ok, now that you’re back you’re probably wondering how to create your own rooms in Janus. Luckily it’s pretty easy because the creator of JanusVR, James McCrae, has written a very clear and simple guide, so get started by giving it a quick read over here.  Here’s a template you can use to get started creating your own VR site:

<html>
<head>
<title>Hello VR World!</title>
</head>
<body>
<FireBoxRoom>
<Assets>
</Assets>
<Room use_local_asset=”room1″>
</Room>
</FireBoxRoom>
</body>
</html>

You can play with your room locally but getting it online is more fun. To get your site online go to VRSites.com and sign up. Now put your room’s code in one of the 10 rooms editors and save it. You can then find your room in Janus by going to the VRSites room (big portal on the right) and finding it based on the address on the top right side of the editor window, or just press tab in Janus and enter your room’s URL. The url is simply james.vrsites.com followed by the room number and then your user number. For example, my user number is 288 and so my Room 1 is found at http://james.vrsites.com/1/288.

You can also use SketchUp to create rooms, but try creating your own from the mark-up language first!

JanusVR Screenshot

JanusVR Screenshot

Eudyptula Challenge: Task 1

Task 1 of the challenge has you create a ‘Hello World!’ kernel module. As I mentioned in my first post about the challenge, I won’t give away any solutions but I will share some thoughts and some of the resources I used to complete the challenge.

At first I was a little intimidated by the scope of the first challenge but after rereading it and searching the web a bit I found some resources that make it much more clear how to complete the task. After that it didn’t seem so scary. Here are some resources you might find helpful:

How to Write Your Own Linux Kernel Module with a Simple Example

Minimal Linux setup for kernel development

Linux Kernel Newbies

HOWTO do Linux kernel development

Unreliable Guide To Hacking The Linux Kernel (doesn’t look like much in the browser so use curl or lynx if you want to feel more like a real kernel hacker)

Linux kernel and driver development course on free-electrons.org

Linux Kernel Development (3rd Edition)

Linux System Programming: Talking Directly to the Kernel and C Library

You don’t need all of these resources to finish the first challenge so don’t get intimidated! I just wanted to collect some resources here that will likely come in handy for the rest of the challenge.

Good luck!

TECHNOLUST: True Cyberpunk Kickstarter

This weekend on the Oculus Developer forums I stumbled upon this great Oculus Rift demo for a game called Technolust. There was a lot of positive feedback so I checked it out. Now, let me first say that I do not have the DK1 and am waiting for the DK2 so I couldn’t actually try the demo the way it was meant to be enjoyed. However, I was still able to get it up and running and walk around in the world a bit. I loved the ambience, the game premise, the easter eggs and all of the references and parallels to cyberpunk cultural icons such as Blade Runner and Ready Player One. I was also happy to see that they are treating Linux as a first class citizen and my nationalistic pride was raised when I saw the developer is in Toronto. I eagerly backed the project on Kickstarter. Check it out for yourself:

TECHNOLUST: True Cyberpunk on Kickstarter

TECHNOLUST: BEST. DEMO. EVER. thread on Oculus Developer Forums (must be logged in for the link to work)

Cyber-thriller ‘Technolust’ for Oculus Rift Launches Kickstarter, Unveils New Prototype (Developer Interview)

Technolust Oculus Rift Review

Unfortunately I couldn’t get the Linux demo working on Ubuntu 14.04 64bit because of a missing libGLU.so.1 32bit library. The Linux demo appears to have been published as a 32bit binary through Unity. I tried several hacks to try and get around this and searched online for a solution but was unable to get it running. I did get the Windows version working though so I got a chance to mess around with it. I think it’s going to be an awesome game and I can’t wait to see how it all comes together!

How to become a Linux kernel contributor: The Eudyptula Challenge

If you’ve ever wondered how development on the Linux kernel is done or wanted to contribute yourself, you can now go and checkout the Eudyptula Challenge. To start the challenge you need to send a plain text email to the address provided on the site and the script will send you your first challenge. The script seems a bit slow so be patient. I had to wait a few hours. Now that I’ve received the first challenge I am intrigue to see where all of this leads. I’ll post about my progress and share some resources as I find them. I will not post solutions or a guide however, since that would be against the spirit of the challenge.

Post in the comments and share your experience with the challenge!

Heartbleed OpenSSL Bug

A serious vulnerability in several OpenSSL versions was publicly disclosed on Monday. Most major Linux distros have already incorporated the patched verison of OpenSSL into their repositories so make sure you go and upgrade all of your machines right now if you haven’t already. In some cases that might not be enough and you should think about having all of your SSL certs reissued as well as having your users change their passwords. The discussion around the internet about this bug has been pretty interesting so if you haven’t already heard about the bug I can suggest you checkout the following links:

Now get out there, patch your s*** and change your passwords! Give LastPass a try if you haven’t already; they’ve implemented a feature in their Security Check tool that will automatically warn you if one of the sites for which you have a password stored is affected by Heartbleed. Besides that it’s a great tool for managing your passwords and a lot more.

 

Setup an SFTP server on Ubuntu

This guide will show you how to setup your Ubuntu computer as an SFTP server. This could be on real hardware or on a virtualized server like a Digital Ocean droplet or an OpenShift gear. We used 13.10 to test this tutorial but it should work fine for 14.04 as well.

Required Software

Install the following packages to get started:

sudo apt-get install openssh-server

Instructions

When making any big config changes it’s always a good idea to backup the file you are changing first. In this case we will modify /etc/ssh/sshd_config so we want to back it up and then open up the original in *insert favourite text editor here (we’ll use nano for this tutorial)*:

sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak
sudo nano /etc/ssh/sshd_config

When you’ve got sshd_config open you need to find and edit the following lines as shown:


#Subsystem sftp /usr/lib/openssh/sftp-server
Subsystem sftp internal-sftp

UsePAM yes

Match Group sftp-user
ChrootDirectory %h
AllowTCPForwarding no
X11Forwarding no
ForceCommand internal-sftp

You can further restrict access with directives like AllowUsers and/or AllowGroups but we won’t go into detail about that right now.

When we make changes to sshd_config we have to restart the ssh service:

sudo service ssh restart

Next we have to create the sftp-user group, create the /srv/sftp folder, and set the permissions and ownership of the folder:

sudo groupadd sftp-user
sudo mkdir /srv
sudo mkdir /srv/sftp
sudo chown root:sftp-user /srv/sftp
sudo chmod 755 /srv/sftp

Almost there now. Next we need to create a user who will be able to sftp in to our server, add them to the sftp-user group and give them a password. This user, who we will call cleared-for-sftp, will not have a shell and we will set their home directory to /srv/sftp, which they will be placed into when they log in because of the  ChrootDirectory %h directive from our sshd_config file above.

sudo useradd cleared-for-sftp -d /srv/sftp -s /bin/false -g sftp-user
sudo passwd cleared-for-sftp

Enter a password for the cleared-for-sftp user and you’re all set. Give your login a try with Filezilla or from the commmand line with:

sftp cleared-for-sftp@[your-server]

where [your-server] is the IP address or domain name of your server.

Last words

When you check your login you should also double check that the user is restricted to the directory he logs into and that the user is not able to log in via ssh and get a shell session. This user should not be able to access your system files. This is a pretty basic setup and you can further customize it by creating more users and restricting them to their own folders using the Match User directive in sshd_config. If you get the infamous ‘Broken Pipe’ error make sure that all directories leading up to the sftp-user’s ChrootDirectory are owned by root and only have write privileges for the owner (ie all parent folders have privileges no higher than 755).

Good luck!

Download Links: Sending files through a Rails 4 app

Creating download links to send files through a Rails app is fairly straightforward thanks to the built-in send_file method.

For this tutorial we’ll use Rail 4.0.4. Let’s say that you have generated a resource called Document with an attribute called document_path which is a string that contains the absolute path to this document, for example /var/www/myapp/downloadables/mydocument.pdf.

If you just need to add download functionality to one resource in your app there are just three steps to complete:

  1. Create a route for your new ‘download’ action
  2. Define the ‘download’ method in your controller
  3. Add a link to your download action in a view

Start by creating a route for the download action on that resource. For this example the download action is specific to a member of the Document resource rather than the collection of all Documents, which means we will refer to this member using its id. Add a route to routes.rb that looks like this:


resources :documents do
    get 'download', on: :member
end

This will define a route for use that maps a url like /documents/1/download to the download action we are about to define in our DocumentsController. That method is pretty simple, it’s just:


class DocumentsController < ApplicationController
before_action :set_document

  #All of your other actions (show, create, delete etc) go here  

  #Download
  def download
    send_file(@document.document_path)
  end

  private
      # Use callbacks to share common setup or constraints between actions.
      def set_document
        @document = Document.find(params[:id])
      end
end

With that change we can already point our browser at myapp/documents/1/download to get our pdf, but that’s not very intuitive or user friendly. Let’s add a link to one of our views to download this document. Let’s add it to the documents/show.html.erb view for this example. The code we want to add is:


<%= link_to "Download this Document!", download_document_path %>

Easy! But don’t get confused about download_document_path vs. @document.document_pathdownload_document_path is a convenience string that Rails generated for us when we declared the download route in Step 1.  @document.document_path is the string attribute stored in our database which describes the document’s location on disk. When we click on “Download this Document!” link Rails routes this URL to the download_document_path which calls the ‘download’ action in the DocumentsController. The ‘download’ method in turn calls send_file which then uses the @document.document_path string to locate the file you want to send on disk. The app then read this file and sends it to the user.

Performance Considerations

The way it is right now we are sending the file directly to the user with no streaming and blocking one of our application’s threads in the process.  This is a performance issue worthy of it’s own article but for now I’m just going to point you to some other resources where you can learn more about this topic:

send_file documentation

File Downloads Done Right

Adding more downloadable resources using Concerns

Now let’s say that in addition to allowing your users to download Documents, you also have Photos that your want your users to download. While you could easily just follow the above steps for the Photos resource, that wouldn’t be very DRY. Instead, consider moving your ‘download’ method to a ‘Downloadable’ module and then including that module into the controller for each resource that should be downloadable. In Rails parlance this module would be a called a ‘Concern’.

To get started let’s create a file called ‘downloadable.rb’ in our app/controllers/concerns folder. This will be a module that extends ActiveSupport::Concern and we want to copy our ‘download’ method code from the DocumentsController and paste it into this new module and rename it ‘send’ so that we do not confuse and override it with the ‘download’ method in the controller. We also want to pass the filepath as a parameter since we no longer can assume we know anything about the instance variable. We then include this module into the DocumentsController concern and the PhotosController and make the ‘download’ method call send. In the end our code will look like this:

#app/controllers/concerns/downloadable.rb
module Downloadable extend ActiveSupport::Concern

  def send_to_user(args={})
    send_file args[:filepath]
  end

end
#app/controllers/documents_controller.rb
class DocumentsController < ApplicationController
include Downloadable
before_action :set_document

  #All of your other actions (show, create, delete etc) go here  

  #Download
  def download
    send_to_user filepath: @document.document_full_path
  end

  private
      # Use callbacks to share common setup or constraints between actions.
      def set_document
        @document = Document.find(params[:id])
      end
end
#app/controllers/photos_controller.rb
class PhotosController < ApplicationController
include Downloadable
before_action :set_photo

  #All of your other actions (show, create, delete etc) go here  

  #Download
  def download
    send_to_user filepath: @photo.photo_full_path
  end

  private
      # Use callbacks to share common setup or constraints between actions.
      def set_photo
        @photo = Photo.find(params[:id])
      end
end

Now we’ve got to define our routes for Photo#download. Fortunately Rails also lets us use concerns in routes.rb to avoid duplicating code everytime we want to make something downloadable. We can route a concern as follows:

#routes.rb
MyApp::Application.routes.draw do

  concern :downloadable do
    get 'download', on: :member
  end

  resources :documents, concerns: :downloadable

  resources :photos, concerns: :downloadable

  root 'welcome#index'
end

Lastly, you want to create a link on your Photo’s show.html.erb page to grab this photo:


<%= link_to "Download this Photo!", download_photo_path %>

Final Thoughts

You probably noticed that our ‘send’ method is so short that it would actually be less code to just copy the ‘download’ method into PhotosController. Yes that’s true, but I wouldn’t do it. Duplicating code like that can be a maintenance nightmare. Our use of send_file is very basic and more than a little naive. We didn’t even check if the file exists and is readable before we tried to send it! Once we add validation and testing code the ‘send’ method will get a lot longer and we’ll start to see why we didn’t want to just copy and paste. If you’re curious how you might implement the file checking I’ve included a possibility for an expanded version of Downloadable in the addendum below.

If you have any comments or impovements to this code, please feel free to comment!

Addendum

Here’s an expanded version of the Downloadable module which adds some flash notifications and redirects the to page that made the last request in case the file is not readable:


module Downloadable extend ActiveSupport::Concern

  def send_to_user(args={})
  	file = args[:filepath]
  	if File.exists?(file) and File.readable?(file)
      send_file file
    else
      redirect_to :back, notice: 'Unfortunately the requested file is not readable or cannot be located.'
    end
  end

end