zoukankan      html  css  js  c++  java
  • 设计模式之工厂方法

    工厂方法(Factory Method)模式简介

    工厂方法(Factory Method)模式的意义是定义一个创建产品对象的工厂接口,将实际创建工作推迟到子类当中。核心工厂类不再负责产品的创建,这样核心类成为一个抽象工厂角色,仅负责具体工厂子类必须实现的接口,这样进一步抽象化的好处是使得工厂方法模式可以使系统在不修改具体工厂角色的情况下引进新的产品。
    工厂方法模式是简单工厂模式的衍生,解决了许多简单工厂模式的问题。首先完全实现‘开-闭 原则’,实现了可扩展。其次更复杂的层次结构,可以应用于产品结构复杂的场合。
    工厂方法模式是对简单工厂模式进行了抽象。有一个抽象的Factory类(可以是抽象类和接口),这个类将不再负责具体的产品生产,而是只制定一些规范,具体的生产工作由其子类去完成。在这个模式中,工厂类和产品类往往可以依次对应。即一个抽象工厂对应一个抽象产品,一个具体工厂对应一个具体产品,这个具体的工厂就负责生产对应的产品。
    工厂方法模式(Factory Method pattern)是最典型的模板方法模式(Templete Method pattern)应用。
    工厂方法模式结构图:
    工厂方法模式结构图:

    工厂方法模式的对简单工厂模式进行了抽象。  有一个抽象的Factory类(可以是抽象类和接口),这个类将不再负责具体的产品生产,而是只制定一些规范,具体的生产工作由其子类去完成。  在这个模式中,工厂类和产品类往往可以依次对应。  即一个抽象工厂对应一个抽象产品,一个具体工厂对应一个具体产品,这个具体的工厂就负责生产对应的产品。

    抽象工厂(Creator)角色:是工厂方法模式的核心,与应用程序无关。任何在模式中创建的对象的工厂类必须实现这个接口。

    具体工厂(Concrete Creator)角色:这是实现抽象工厂接口的具体工厂类,包含与应用程序密切相关的逻辑,并且受到应用程序调用以创建产品对象。

    抽象产品(Product)角色:工厂方法模式所创建的对象的超类型,也就是产品对象的共同父类或共同拥有的接口。在上图中,这个角色是Light。

    具体产品(Concrete Product)角色:这个角色实现了抽象产品角色所定义的接口。某具体产品有专门的具体工厂创建,它们之间往往一一对应。 

    工厂方法模式的应用

    工厂方法经常用在以下两种情况中:
    第一种情况是对于某个产品,调用者清楚地知道应该使用哪个具体工厂服务,实例化该具体工厂,生产出具体的产品来。
    第二种情况,只是需要一种产品,而不想知道也不需要知道究竟是哪个工厂为它生产的,即最终选用哪个具体工厂的决定权在生产者一方,它们根据当前系统的情况来实例化一个具体的工厂返回给使用者,而这个决策过程对于使用者来说是透明的。
     
    工厂方法和工厂模式区别:
    工厂方法模式:
    一个抽象产品类,可以派生出多个具体产品类。  
    一个抽象工厂类,可以派生出多个具体工厂类。  
    每个具体工厂类只能创建一个具体产品类的实例。

    抽象工厂模式:
    多个抽象产品类,每个抽象产品类可以派生出多个具体产品类。  
    一个抽象工厂类,可以派生出多个具体工厂类。  
    每个具体工厂类可以创建多个具体产品类的实例。  
       
    区别:
    工厂方法模式只有一个抽象产品类,而抽象工厂模式有多个。  
    工厂方法模式的具体工厂类只能创建一个具体产品类的实例,而抽象工厂模式可以创建多个。
     
    View Code
    View Code 
    
    using System;
    using System.Collections.Generic;
    using System.Text;
    
    namespace 工厂方法_雷锋工厂
    {
        class Program
        {
            static void Main(string[] args)
            {
                //基本方式:薛磊风代表大学生学习雷锋
                LeiFeng xueleifeng = new Undergraduate();
    
                xueleifeng.BuyRice();
                xueleifeng.Sweep();
                xueleifeng.Wash();
    
                LeiFeng student1 = new Undergraduate();
                student1.BuyRice();
                LeiFeng student2 = new Undergraduate();
                student2.Sweep();
                LeiFeng student3 = new Undergraduate();
                student3.Wash();
    
                //简单工厂模式
                LeiFeng studentA = SimpleFactory.CreateLeiFeng("学雷锋的大学生");
                studentA.BuyRice();
                LeiFeng studentB = SimpleFactory.CreateLeiFeng("学雷锋的大学生");
                studentB.Sweep();
                LeiFeng studentC = SimpleFactory.CreateLeiFeng("学雷锋的大学生");
                studentC.Wash();
    
                //工厂方法模式
                IFactory factory = new UndergraduateFactory();
                LeiFeng student = factory.CreateLeiFeng();
    
                student.BuyRice();
                student.Sweep();
                student.Wash();
    
                Console.Read();
            }
        }
    
        //雷锋
        class LeiFeng
        {
            public void Sweep()
            {
                Console.WriteLine("扫地");
            }
    
            public void Wash()
            {
                Console.WriteLine("洗衣");
            }
    
            public void BuyRice()
            {
                Console.WriteLine("买米");
            }
        }
    
        //学雷锋的大学生
        class Undergraduate : LeiFeng
        { }
    
        //社区志愿者
        class Volunteer : LeiFeng
        { }
    
        //简单雷锋工厂
        class SimpleFactory
        {
            public static LeiFeng CreateLeiFeng(string type)
            {
                LeiFeng result = null;
                switch (type)
                {
                    case "学雷锋的大学生":
                        result = new Undergraduate();
                        break;
                    case "社区志愿者":
                        result = new Volunteer();
                        break;
    
                }
                return result;
            }
        }
    
        //雷锋工厂
        interface IFactory
        {
            LeiFeng CreateLeiFeng();
        }
    
        //学雷锋的大学生工厂
        class UndergraduateFactory : IFactory
        {
            public LeiFeng CreateLeiFeng()
            {
                return new Undergraduate();
            }
        }
    
        //社区志愿者工厂
        class VolunteerFactory : IFactory
        {
            public LeiFeng CreateLeiFeng()
            {
                return new Volunteer();
            }
        }
    }
  • 相关阅读:
    C、C++笔记
    日向blog开发记录
    項目生成順序錯誤導致的鏈接ERROR
    vs单元测试demo
    让CtrlList的某一行自定义颜色
    MFC软件的一点没用的调试经验……
    VS单步调试DLL形式的COM组件的过程
    socket udp编程的一些积累的记录
    git push报错大文件,删除后重新commit依然报错
    CC++串口通信编程的一点技术记录
  • 原文地址:https://www.cnblogs.com/binyao/p/3059485.html
Copyright © 2011-2022 走看看