第一部分:面向细节的编程方法(类)
首先,准备几个普通类(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文件:有类库编译生成
当需要动态增加类的时候,使用反射,屏蔽细节
待续中....