第一部分:面向细节的编程方法(类)
首先,准备几个普通类(Man类和Woman类) (1)Man类
public class Man
{
public void ShowS()
{
Console.WriteLine("I am a man");
Console.ReadKey();
}
}
(2)Woman类
public class Woman
{
public void ShowS()
{
Console.WriteLine("I am a man");
Console.ReadKey();
}
}
然后,在主调用类中调用普通类
static void Main(string[] args)
{
Man man = new Man();
man.ShowS();
}
总结:该种方法是常用的面向细节的编程方法,具体操作的类可见,但是,当普通中的类名发生改变时,所有调用该类的类都需要进行修改,否则错误。
那有没有什么方法可以屏蔽这种事情的发生呢(即被调用类的类名发生变化时,主调类稳定运行,不收影响)
可以采用面向抽象的编程方法,抽象:接口,抽象类
因此,将上面普通类的方法提取出来,定义一个接口让普通区继承并实现其中的方法
则:
首先,准备一个接口(所用的类所共同具有的方法抽象)
public interface IShow
{
void ShowS();
}
然后,准备普通类(针对不同的类)继承接口
(1)Man类
public class Man : IShow
{
public void ShowS()
{
Console.WriteLine("I am a Man");
Console.ReadKey();
}
}
(2)Woman类
public class Woman : IShow
{
public void ShowS()
{
Console.WriteLine("I am a Woman");
Console.ReadKey();
}
}
static void Main(string[] args)
{
//屏蔽左边的具体类
IShow woman = new Woman();
woman.ShowS();
}
针对这种做法,仍然有一个问题,那就是等号“=”的右边,依旧是具体的类,在普通的类名发生更改是仍然会出错。
那有什么办法可有将等号右边显示创建对象的方式屏蔽呢??
故此使用工厂方法模式l:通过一个工厂,创建所需的对象
实现方式为:
首先,准备一个工厂类
该工厂类为:
public class SimpleFactory
{
//通过方法创建对象
public static IShow CreateInstance()
{
return new Woman();
}
}
第二,该处的普通类与上述一样、
第三,主调类改为:
static void Main(string[] args)
{
IShow woman = SimpleFactory.CreateInstance();//右边通过方法创建对象
woman.ShowS();
}
该种只实现了一个对象的创建(没有参数)
针对多个对象,我们又该怎么做呢(带参数)
第一,普通类和上述一样,不发生变化
第二,工厂类变为:
public class SimpleFactory
{
//根据参数创建具体的对象
public static IShow CreateInstance(Human huMan)
{
switch (huMan)
{
case Human.Woman: return new Woman();
case Human.Man: return new Man();
default:
throw new Exception("Wrong");
}
}
//定义一个枚举储存类型
public enum Human
{
Man,
Woman
}
}
第三,主调类中:
static void Main(string[] args)
{
IShow woman = SimpleFactory.CreateInstance(SimpleFactory.Human.Woman);//根据传递的参数创建需要的对象
woman.ShowS();
}
简单工厂的好处:高耦合 矛盾转移到工厂当中
简单工厂的弊端:修改普通类则工厂也需要修改 严重违背面向对象的单一原则(一个类只做一件事)
以上所需要的类型是在工厂中方法调用时指定的
第二部分:工厂方法进阶
第一种方式:使用配置文件+简单工厂 将参赛设置在配置文件中 所需的类型是在配置文件中定义
首先,配置文件
<configuration>
<appSettings>
<add key="Woman" value="Woman"/>
</appSettings>
</configuration>
其次,简单工厂类中
public class SimpleFactory
{
private static string Config = ConfigurationManager.AppSettings["Woman"];
public static IShow CreateInstanceConfig()
{
switch ((Human)Enum.Parse(typeof(Human), Config))
{
case Human.Woman:
return new Woman();
case Human.Man:
return new Man();
default:
throw new Exception("Wrong");
}
}
//定义一个枚举储存类型
public enum Human
{
Man,
Woman
}
}
此处注意配置文件的使用,命名空间的导入。using system.Configration
最后,主调类中
static void Main(string[] args)
{
IShow woman = SimpleFactory.CreateInstanceConfig();//方法无参数
woman.ShowS();
}
第二种方式:简单工厂+配置文件+反射 反射:动态加载dll文件 dll文件:有类库编译生成
当需要动态增加类的时候,使用反射,屏蔽细节