Abstract
This article focuses on intent and applicability of a new design pattern named "Commander" or "Dictator" Pattern. "Commander" Pattern can be defined a behavioral representative for a group of objects belonging to same class.
Analogy
Consider an army division, in an army a captain is appointed for each division who commands/controls the people in his division. A Captain is not different from his men, There is nothing which a captain can do and his men cannot do or vice-versa. A Captain has all characteristics of his men and vice versa. The only difference is a Captain is appointed as a "behavioral" representative for his men. There is difference between a representative and a "behavioral" representative. A person acting as a representative whose behavior or any action may/may not spread among all members of his group but a behavioral representative action must spread among all members of his groups. His members will execute any order given to a captain regardless of its underlying consequences and it is each member duty to obey to his captain order and he cannot show any sort of non-compliance. The intent of this pattern is to group unique instance and encapsulate 'groups' behavior into one and representing it as a one whole object.
Problem
As we know each application is built around thousands of objects, these objects are periodically created/destroyed dynamically, depending upon their usage. Each object represents a unique instance of some class; there could be a multiple/single instance of same class. Considering this scenario a need may arise to instruct different instances of same class to perform some activity, a transparent solution is required to address this requirement allowing the system to get operate at a group instance level instead of an unique instance level, This will give an absolute total control to the system, at any point of time system could switch to group level using the unique instance level as each unique instance knows its commander.
Structure
Following participants form the structure of Commander Pattern.
There are several ways of implementing this pattern, but lets go with a simpler approach.
1.Define the instructions/command each Fellow adheres/Commander commands.
using System; namespace commanderpattern { public interface instructions { void Dispose(); Instructions Getcommander(); void Jointeam(Instructions fellow); void Updatedata(string Data); } }Here are 2 methods Dispose, which each class needs to be implement, is used to clean-up unmanaged resources and Updatedata method is called to synchronize the data each object instance hold.
2.Define a Fellow, which implements same interface/characteristics.
using System; namespace commanderpattern { public class Fellow : instructions { private string _commandMsg; private static Instructions _commander; public Fellow() { if ( _commander == null ) { _commander = new Commander(); } Jointeam(this); } #region IContract Members public void Dispose() { Console.WriteLine?("Object Cleanup"); } public void Updatedata(string commandMsg) { _commandMsg = commandMsg; Console.WriteLine?("Data Updated"); } public void Jointeam(Instructions fellow) { _commander.Jointeam(fellow); } public Instructions Getcommander() { return _commander; } #endregion } }3.Define a Commander, which implements same interface/characteristics.
using System; namespace commanderpattern { public class Commander : Instructions { private ArrayList _FellowList; public Commander() { _FellowList = new ArrayList(); } #region IContract Members public void Dispose() { foreach(Instructions _fellow in _FellowList) { _fellow.Dispose(); } } public void Updatedata(string Data) { foreach(Instructions _fellow in _FellowList) { _fellow.Updatedata(Data); } } public void Jointeam(Instructions fellow) { _FellowList.Add(fellow); } public Instructions GetCommander?() { throw new ApplicationException?("Already operating at a Commander Level"); } #endregion } }4.Define a client, which uses the fellow services.
using System; namespace commanderpattern { class Class1 { [STAThread] static void Main(string[] args) { Instructions fellow1 = new Fellow(); Instructions fellow2 = new Fellow(); Instructions fellow3 = new Fellow(); Instructions commander = fellow2.Getcommander(); commander.Dispose(); commander.Updatedata("Synchronize Data"); } } }Consequences
There are several benefits of using the Commander/Dictator Pattern.
using System; namespace commanderpattern { [Commander] class Class1 { public void Test() } }Caveats
This seems to me the CompositePattern. What is the difference?-- Rafael U. C. Afonso