常用12种设计模式---(其三)简单工厂(simple factory)

1.简单工厂设计模式

  • 1.1: 简单工厂属于创建模式的一种。简单工厂不是一种标准的设计模式,但是它十分常用但相对简单易懂,所以我们必须掌握。
  • 1.2: 前面两章讲了工厂方法和抽象工厂,其实按难度应该从简单工厂开始了解,但是在这里我是按三种模式中常用的等级进行依次学习。
  • 1.3: 常用指数:☆☆☆☆

2.接口回顾

  • 2.1 接口用来干什么?
    • 通常接口用来实现类的行为定义,也就是对实现类的行为进行约束。当然,接口约定了实现类的行为,但是在实现接口的所有约定后,如果还需要在类里进行其余行为的实现这是许可的。
  • 2.2 接口的思想?
    • 接口就是 “封装隔离”
    • 封装:对隔离体的行为的封装
    • 隔离:外部调用和内部实现。外部调用只能通过实现接口来进行调用,因为外部并不知道内部是如何实现的
  • 2.3 接口的好处?
    • 只要接口没有改变,那么内部实现的变化就不会影响到外部应用,这样会使系统更灵活,维护性更高
  • 2.4 接口和抽象类的选择?
    • 优先选择接口
    • 在既要定义子类行为时,并且要为子类提供公共的功能时选择抽象类。参考工厂方法模式。

3.问题

  • 现在有一个接口叫Api,然后一个类(ClassA)实现了这个Api接口,那么在客户端怎么使用这个接口呢?
  • 3.1 初步思维: 因为ClassA实现了Api,那么在Client(main)里面我们就直接用这个类去实例化这个接口,然后调用方法即可:Api api = new ClassA(); api.function();
    • 疑惑: 我们这样看到客户端通过这样的方式进行了接口的调用,但是很显然,客户知道了有Api这个接口同时也知道了有ClassA这个实现该接口的类,更何况,知道了ClassA了,那么我还有必要去实例化接口Api吗?直接调用ClassA就行了啊。接口核心思想就是封装隔离,现在倒好,所有信息都在客户端暴露出来。
  • 3.2 简单工厂:
    • 定义: 提供一个创建对象实例的功能,而不去关心具体怎么实现。被创建的实例的类型可以是接口、抽象类、具体类
    • 示例图: 在这里插入图片描述
    • 3.3 代码:
class Program
    {
        static void Main(string[] args)
        {
            //用简单工厂类去实例化接口Api,而不是去用实现类去实例化接口Api了
            //注意这里的参数,这样导致的缺陷就是会向客户暴露一部分内部的实现细节
            Api_Print api = new SimpleFactory().Api(1);
            api.Print();
            BImplementApi.ExtraPrint();
            Console.ReadLine();
        }
    }
    //声明一个具有输出内容的接口
    public interface Api_Print
    {
        //接口的输出功能
        void Print();
    }
    
    //声明一个实现接口的A类
    public class AImplementApi:Api_Print
    {
        //实现接口功能
        public void Print()
        {
            Console.WriteLine("通过A实现类来实现接口的Print()功能");
        }
        //实现类里额外需要的功能声明
        public void ExtraPrint()
        {
            Console.WriteLine("这是A实现类额外需要的功能,并不影响接口内部");
        }
    }
    //声明一个实现接口的B类
    public class BImplementApi : Api_Print
    {
        //实现接口功能
        public void Print()
        {
            Console.WriteLine("通过B实现类来实现接口的Print()功能");
        }
        //静态实现类里额外需要的功能声明
        public static void ExtraPrint()
        {
            Console.WriteLine("这是B实现类额外需要的功能,并不影响接口内部");
        }
    }

    public class SimpleFactory
    {
        //定义一个接口变量
        Api_Print api = null;
        //声明一个创建接口Api对象的方法
        public Api_Print Api(int Judge)
        {
            if (Judge == 0)
            {
                //将对象的实例化交给工厂类里面去实现,实现了隔离思想
                api = new AImplementApi();
            }
            else
            {
                api = new BImplementApi();
            }
            return api;
        }
    }
  • 3.4 结果:
    在这里插入图片描述
  • 3.5 代码连接: https://github.com/liusa1997/DesignModel
  • 3.6 可配置的简单工厂:
    • 问题:如果现在要加入一个新的实现类,那么工厂类就会相应改变,但是这样很繁琐。那么如何在加入实现类情况下,不去修改工厂类?
    • 方法:使用配置文件,当有了新的实现类后,只要在配置文件里面配置新的实现类就行了。在简单工厂里面可以使用反射,也可以使用 IoC/DI(控制反转/依赖注入) 来实现。
    • 配置:配置过程暂且不提,以后所需增加
  • 3.7 简单工厂的优缺点:
    • 优点:
      • 帮助封装:简单工厂很简单同时很方便的帮我们封装了组件,然后让外部能真正面向接口编程
      • 解耦:通过简单工厂,实现了客户端和具体实现类的解耦
    • 缺点:
      • 可能增加客户端的复杂度:如果通过客户端参数来选择具体的实现类,那么就会暴露一定的内部实现
      • 不方便扩展子工厂:通常情况下,不会为简单工厂创建子类
  • 3.8 简单工厂、工厂方法、抽象工厂:
    • 简单工厂是来 选择实现的,可以选择任意接口的实现。一个简单工厂可以有多个用于选择并创建对象的方法,多个方法创建的对象可以有关系也可以没有关系。
    • 工厂方法的本质也是选择实现,跟简单工厂不同的是,它把选择 具体实现的功能延迟到子类去实现。如果把实现放到父类,当然就跟简单工厂没什么区别了。
    • 抽象工厂是用来选择产品簇的实现的。一般抽象工厂里面有多个选择并创建对象的方法,但是这些 方法之间是有关联 的,这些被创建的对象通常构成一个产品簇所需要的部件对象
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值