前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >2.简单工厂方法模式

2.简单工厂方法模式

作者头像
wfaceboss
发布2019-04-08 11:28:55
3550
发布2019-04-08 11:28:55
举报
文章被收录于专栏:wfacebosswfaceboss

第一部分:面向细节的编程方法(类)

首先,准备几个普通类(Man类和Woman类) (1)Man类

代码语言:javascript
复制
public class Man 
    {

        public void ShowS()
        {
            Console.WriteLine("I am a man");

            Console.ReadKey();

        }

    }

(2)Woman类

代码语言:javascript
复制
 public class Woman
    {
        public void ShowS()
        {

            Console.WriteLine("I am a man");

            Console.ReadKey();

        }
    }

然后,在主调用类中调用普通类

代码语言:javascript
复制
 static void Main(string[] args)
        {
           
            Man man = new Man();
            man.ShowS();
           


        }

总结:该种方法是常用的面向细节的编程方法,具体操作的类可见,但是,当普通中的类名发生改变时,所有调用该类的类都需要进行修改,否则错误。

   那有没有什么方法可以屏蔽这种事情的发生呢(即被调用类的类名发生变化时,主调类稳定运行,不收影响)

可以采用面向抽象的编程方法,抽象:接口,抽象类

因此,将上面普通类的方法提取出来,定义一个接口让普通区继承并实现其中的方法

则:

首先,准备一个接口(所用的类所共同具有的方法抽象)

代码语言:javascript
复制
  public interface IShow
    {
        void ShowS();
    }

然后,准备普通类(针对不同的类)继承接口

(1)Man类

代码语言:javascript
复制
  public class Man : IShow
    {

        public void ShowS()
        {
            Console.WriteLine("I am a Man");

            Console.ReadKey();

        }

    }

(2)Woman类

代码语言:javascript
复制
 public class Woman : IShow
    {
        public void ShowS()
        {

            Console.WriteLine("I am a Woman");

            Console.ReadKey();

        }
    }
代码语言:javascript
复制
  static void Main(string[] args)
        {
            //屏蔽左边的具体类                
            IShow woman = new Woman();
            woman.ShowS();
           
        }

针对这种做法,仍然有一个问题,那就是等号“=”的右边,依旧是具体的类,在普通的类名发生更改是仍然会出错。

那有什么办法可有将等号右边显示创建对象的方式屏蔽呢??

故此使用工厂方法模式l:通过一个工厂,创建所需的对象

实现方式为:

首先,准备一个工厂类

该工厂类为:

代码语言:javascript
复制
  public class SimpleFactory
    {
        //通过方法创建对象
        public static IShow CreateInstance()
        {
            return new Woman();
        }
     
    }

第二,该处的普通类与上述一样、

第三,主调类改为:

代码语言:javascript
复制
static void Main(string[] args)
        {
            IShow woman = SimpleFactory.CreateInstance();//右边通过方法创建对象
            woman.ShowS();
         
        }

该种只实现了一个对象的创建(没有参数)

针对多个对象,我们又该怎么做呢(带参数)

第一,普通类和上述一样,不发生变化

第二,工厂类变为:

代码语言:javascript
复制
 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

        }
    }

第三,主调类中:

代码语言:javascript
复制
  static void Main(string[] args)
        {

            IShow woman = SimpleFactory.CreateInstance(SimpleFactory.Human.Woman);//根据传递的参数创建需要的对象
            woman.ShowS();
        }

 简单工厂的好处:高耦合 矛盾转移到工厂当中

简单工厂的弊端:修改普通类则工厂也需要修改  严重违背面向对象的单一原则(一个类只做一件事)

以上所需要的类型是在工厂中方法调用时指定的

第二部分:工厂方法进阶

第一种方式:使用配置文件+简单工厂   将参赛设置在配置文件中    所需的类型是在配置文件中定义

首先,配置文件

代码语言:javascript
复制
<configuration>
  <appSettings>
    <add key="Woman" value="Woman"/>
  </appSettings>
</configuration>

其次,简单工厂类中

代码语言:javascript
复制
  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

最后,主调类中

代码语言:javascript
复制
   static void Main(string[] args)
        {

            IShow woman = SimpleFactory.CreateInstanceConfig();//方法无参数
            woman.ShowS();

        }

第二种方式:简单工厂+配置文件+反射    反射:动态加载dll文件       dll文件:有类库编译生成

当需要动态增加类的时候,使用反射,屏蔽细节

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2017-03-17 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档