示例(有个程序,既可以使用Windows风格外观,又可以使用Mac风格外观,而内部业务是一样的。):
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
namespace Szh.DI.DependencyLocate
{
public interface IButton
{
string ShowInfo();
}
public interface IWindow
{
string ShowInfo();
}
public interface ITextBox
{
string ShowInfo();
}
public interface IFactory
{
IWindow MakeWindow();
IButton MakeButton();
ITextBox MakeTextbox();
}
public class WinFactory:IFactory
{
public IWindow MakeWindow()
{
return new WinWindow();
}
public IButton MakeButton()
{
return new WinButton();
}
public ITextBox MakeTextbox()
{
return new WinTextbox();
}
}
public class MacFactory:IFactory
{
public IWindow MakeWindow()
{
return new MacWindow();
}
public IButton MakeButton()
{
return new MacButtton();
}
public ITextBox MakeTextbox()
{
return new MacTextbox();
}
}
internal static class FactoryContainer
{
public static IFactory factory { get; private set; }
static FactoryContainer()
{
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(".\\Config.xml");
//XmlNode xmlNode = xmlDoc.ChildNodes[1].ChildNodes[0].ChildNodes[0];
XmlNode xmlNode3 = xmlDoc.ChildNodes[0];
XmlNode xmlNode2 = xmlDoc.ChildNodes[1];
XmlNode xmlNode1 = xmlNode2.ChildNodes[0];
XmlNode xmlNode = xmlNode1.ChildNodes[0];
if ("Windows" == xmlNode.Value)
{
factory = new WinFactory();
}
else if ("Mac" == xmlNode.Value)
{
factory = new MacFactory();
}
else
{
throw new Exception("Factory Init Error");
}
}
}
public class WinButton:IButton
{
public string _description { get;set; }
public WinButton()
{
this._description ="Windows style button!";
}
public string ShowInfo()
{
return this._description;
}
}
public class MacButtton:IButton
{
public string _description{get;set;}
public MacButtton()
{
this._description = "Mac style button!";
}
public string ShowInfo()
{
return this._description;
}
}
public class WinWindow:IWindow
{
public string _description { get; set; }
public WinWindow()
{
this._description = "Win style window";
}
public string ShowInfo()
{
return this._description;
}
}
public class MacWindow:IWindow
{
public string _decription { get; set; }
public MacWindow()
{
this._decription = "Mac style window";
}
public string ShowInfo()
{
return this._decription;
}
}
public class WinTextbox:ITextBox
{
public string _decription { get; set; }
public WinTextbox()
{
this._decription = "Win style textbox";
}
public string ShowInfo()
{
return this._decription;
}
}
public class MacTextbox:ITextBox
{
public string _decription { get; set; }
public MacTextbox()
{
this._decription = "Mac style textbox";
}
public string ShowInfo()
{
return this._decription;
}
}
class Program
{
static void Main(string[] args)
{
IFactory factory = FactoryContainer.factory;
IWindow window = factory.MakeWindow();
Console.WriteLine("创建 " + window.ShowInfo());
IButton button = factory.MakeButton();
Console.WriteLine("创建 " + button.ShowInfo());
ITextBox textbox = factory.MakeTextbox();
Console.WriteLine("创建 " + textbox.ShowInfo());
Console.Read();
}
}
}
配置文件 Config.xml :
<?xml version="1.0" encoding="utf-8" ?>
<config>
<window>UbuntuWindow</window>
<button>MacButton</button>
<textBox>MacTextBox</textBox>
</config>
缺点:当新添加一种风格时,比如UbuntuWindow,UbuntuButton,UbuntuTextBox时,除了修改配置文件之外,还必须修改FactoryContainer 类,在其中增加处理分支。这破坏了OCP。使用反射机制可以完美的解决这个问题。见依赖注入篇。