サンプルコード

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

※他サイトを参照