思维导图
为了贯彻依赖倒置原则,在上端(调用者)去掉对细节的依赖,但是又需要获得实例,将获得实例的方法封装为一个工厂类中,工厂负责生产对象。
问题:虽然上端移除了对细节的依赖,但是上端还得传递参数(枚举)才能获取到相应的对象。只是转移了矛盾,并没有消除矛盾。
简单工厂
用工厂方法创建实现类,传递枚举参数来得到不同的实现类
public class SimpleFactory {
public static IRace CreateRace(RaceType raceType) {
IRace race = null;
switch (raceType) {
case RaceType.Human:
race = new Human();
break;
case RaceType.Undead:
race = new Undead();
break;
case RaceType.NE:
race=new NE();
break;
case RaceType.ORC:
race = new ORC();
break;
default:
break;
}
return race;
}
}
枚举
public enum RaceType {
Human,
Undead,
NE,
ORC
}
上端调用
IRace undead = SimpleFactory.CreateRace(SimpleFactory.RaceType.Undead);
可配置:简单工厂+配置文件
程序的可配置-不用修改编译,直接修改配置文件,即可支持不同行为
配置文件
<add key=""IRaceConfig" value="Human"/>
在工厂方法中
1、读取配置文件的配置.
假如某个值经常变换,不同环境下 会写入到配置文件--如数据库连接
private static string IRaceConfig =
System.Configuration.ConfigurationManager.AppSettings["IRaceCofig"];
2、根据配置文件的值作为参数,调用创建对象的方法
public static IRace CreateRaceConfig() {
RaceType raceType = (RaceType)Enum.Parse(typeof(RaceType), IRaceConfig);
return CreateRace(raceType);
}
上端调用
IRace undead = SimpleFactory.CreateRaceConfig();
可配置:简单工厂+配置文件+反射
即不依赖细节,又要获取实例,可以通过反射
配置文件
<add key=""IRaceConfigReflection" value="ServiceExtend.Six,ServiceExtend"/>
1、读取配置文件
配置文件中某个key的value放了两项(完整的命名空间),value用逗号分隔
private static string IRaceConfigReflection =
System.Configuration.ConfigurationManager.AppSettings["IRaceConfigReflection"];
2、读取配置文件中的类型,并创建一个实例对象
public static IRace CreateRaceConfigReflection() {
Assembly assembly = Assembly.Load(IRaceConfigReflection.Split(',')[1]);
Type type = assembly.GetType(IRaceConfigReflection.Split(',')[0]);
return (IRace)Activator.CreateInstance(type);
}
上端调用
IRace undead = SimpleFactory.CreateRaceConfigReflection();
可配置+可扩展
IOC容器就是在此基础上进一步扩展封装。添加新功能,还不用修改原有代码
1、添加一个类库,在里面添加新的实现类
namespace ServiceExtend {
public class Six:IRace {
//..
}
}
2、编译此类库(右键--重新生成),拷贝编译后的dll、pdb文件(bin--debug--net6.0)到之前的目录下
3、修改配置文件