サンプルコード
Chain Pattern
・前回処理の結果を活用
>jQueryサンプル
$("#id").find("div").find("p").find("input[name=age]");
Factory().setName("Andy").setAge(20).getName();
function Demo(){ }
Demo.prototype = {
setName:function(name){
this.name = name;
return this;
},
getName:function(){
return this.name;
},
setAge:function(age){
this.age = age;
return this;
}
};
function Factory(){
return new Demo();
}
>C#サンプル
var result = list.FindAll(p => p.Age > 30).FindAll(p => p.Name.Length < 10);
FindAllメソッドのソースコード
public List<T> FindAll(Predicate<T> match)
{
if (match == null)
{
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.match);
}
List<T> list = new List<T>();
for (int i = 0; i < this._size; i++)
{
if (match(this._items[i]))
{
list.Add(this._items[i]);
}
}
return list;
}
class Calculator
{
private double result;
public Calculator(double num)
{
this.result = num;
}
public Calculator Minus(double num)
{
this.result -= num;
return this;
}
...
public double Result()
{
return this.result;
}
}
//利用側
var result = new Calculator(10.2)
.Plus (3.3).Minus(6).Multiply(3).Divide(2.1).Minus(5).Result();
SPI(Service Provider Interface) Pattern
SPI = 基于接口的编程+策略模式+配置文件的动态加载机制
interface Service {
...
}
interface Provider {
Service newService();
}
final class Services {
private Services();
private static final Map<String, Provider> providers =
new ConcurrentHashMap<String, Provider>();
private static final String DEFAULT_PROVIDER_NAME = "default";
public static void registerDefaultProvider(Provider p) {
registerProvider(DEFAULT_PROVIDER_NAME, p);
}
public static void registerProvider(String name, Provider p) {
providers.put(name, p);
}
public static Service newInstance() {
return newInstance(DEFAULT_PROVIDER_NAME);
}
public static Service newInstance(String name) {
Provider p = providers.get(name);
if (p == null) {
throw new IllegalArgumentException(
"No provider registered with name: " + name);
}
return p.newService();
}
}
API (Application Programing Interface) call and use to achieve a goal
SPI (Service Provider Interface) extend and implement to achieve a goal
Plugin Pattern
プラグ管理
public interface IPlugin
{
void Initialize(IPluginManager pluginManager);
void DoSomething();
}
public interface IPluginManager
{
void AddMenuItem(string name, Action<string> clickHandler);
void RegisterComponent<T>(T component) where T : class;
T GetComponent<T>() where T : class;
}
public class PluginManager : IPluginManager
{
private IMessageManager messageManager;
private readonly IDictionary<Type, IComponent> components
= new Dictionary<Type, IComponent>();
private List<IPlugin> pluginList = new List<IPlugin>();
public PluginManager(){ }
public PluginManager(IMessageManager messageManager)
{
this.messageManager = messageManager;
}
public void Run(string[] files)
{
this.LoadPlugin(files);
if (this.pluginList.Count > 0)
{
this.pluginList.ForEach( plugin => plugin.DoSomething() );
}
IComponent component = this.GetComponent<IComponent>();
component.Initiate();
}
public void LoadPlugin(string[] files)
{
foreach (string fileName in files)
{
Assembly assembly = Assembly.LoadFile(fileName);
foreach (Type pluginType in assembly.GetTypes())
{
if (!pluginType.IsPublic
|| pluginType.IsAbstract
|| pluginType.IsInterface)
{
continue;
}
Type concreteType =
pluginType.GetInterface(typeof(IPlugin).FullName, true);
if (concreteType != null)
{
//IPlugin plugin =
(IPlugin)Activator.CreateInstance(pluginType);
IPlugin plugin = (IPlugin)Activator.CreateInstance
(pluginType, new object[] { messageManager });
plugin.Initialize(this);
this.pluginList.Add(plugin);
break;
}
}
}
}
public void AddMenuItem(string name, Action<string> clickHandler)
{
clickHandler(name);
}
public void RegisterComponent<T>(T component) where T : class
{
this.components.Add(typeof(T), (IComponent)component);
}
public T GetComponent<T>() where T : class
{
return (T)this.components[typeof(T)];
}
}
プラグイン(PluginA.dllを生成)
public class PluginA : IPlugin
{
private IMessageManager messageManager;
public PluginA(){ }
public PluginA(IMessageManager messageManager)
{
this.messageManager = messageManager;
}
public void Initialize(IPluginManager pluginManager)
{
pluginManager.RegisterComponent<IComponent>(new ConcreteComponent());
pluginManager.AddMenuItem("Click In PluginA",
name => Console.WriteLine(name));
}
public void DoSomething()
{
Console.WriteLine("DoSomething In PluginA");
if (messageManager != null)
{
messageManager.ShowMessage();
}
}
}
プラグと通信用
public interface IMessageManager
{
void ShowMessage();
}
public class ConcreteMessage : IMessageManager
{
private string message;
public ConcreteMessage(string message)
{
this.message = message;
}
public void ShowMessage()
{
Console.WriteLine(this.message);
}
}
機能拡張用
public interface IComponent
{
void Initiate();
}
public class ConcreteComponent : IComponent
{
public void Initiate()
{
Console.WriteLine("Component run");
}
}
利用側
string[] files = Directory.GetFiles(Directory.GetCurrentDirectory() + "\\" + "Plugins", "*.dll");
new PluginManager().Run(files);
Console.WriteLine("------------------------");
new PluginManager(new ConcreteMessage("Enter")).Run(files);
★API vs SPI
※他サイトを参照