zoukankan      html  css  js  c++  java
  • 设计模式学习(四):集中式工厂的实现—简单工厂模式

    一、简单工厂模式概述

    1.基本思想及流程:

       首先将需要创建的各种不同对象的相关代码封装到不同的类中,这些类成为具体产品类,而将它们公共的代码进行抽象和提取后封装在一个抽象产品类中,每一个具体产品类都是抽象产品类的子类;然后提供一个工厂类用于创建各种产品,在工厂类中提供一个创建产品的工厂方法,该方法可以根据所传入的参数不同创建不同的具体产品对象;客户端只需要调用工厂类的工厂方法并传入相应的参数即可得到一个产品对象。

    2.定义:

      简单工厂模式(Simple Factory Pattern):定义一个工厂类,它可以根据参数的不同返回不同类的实例,被创建的实例通常都具有共同的父类。因为在简单工厂模式中用于创建实例的方法是静态方法,因此简单工厂模式又被称为静态工厂方法模式,它属于类创建型模式。

    3.简单工厂模式的要点

      当你需要什么,只需要传入一个正确的参数,就可以获取你想要的对象,而无须知道具体的创建细节。

    二、类图及核心代码1.类图

    说明:

    ①Factory(工厂角色):即工厂类,它是工厂模式的核心,负责实现创建所有产品实例的内部逻辑;工厂类可以被外界直接调用,创建所需的产品对象;在工厂类中提供了静态的工厂方法FactoryMethod(),它返回的类型为抽象传品类型Product。

    ②Product(抽象产品角色):它是工厂类所创建的所有对象的父类,封装了各种产品对象的公有方法,它的引入将提高系统的灵活性,使得在工厂类中只需要定义一个通用的工厂方法,因此所有创建的具体产品对象都是其子类对象。

    ③ConcreteProduct(具体产品角色):它是简单工厂模式的创建目标,所有被创建的对象都充当这个角色的某个具体类的实例。每一个具体产品角色都继承了抽象产品角色,需要实现在抽象产品中声明的抽象方法。

    ④在简单工厂模式中,客户端通过工厂类来创建一个产品类的实例,而无须直接使用new关键字来创建对象。

    2.核心代码

     1     public abstract class Product
     2     {
     3         //所有产品类的公共业务方法
     4         public void SameMehtod()
     5         {
     6             Console.WriteLine("我是公共方法!");
     7         }
     8 
     9         //声明抽象业务方法
    10         public abstract void DiffMehtod();
    11     }
    1         //实现业务方法
    2         public override void DiffMehtod()
    3         {
    4             Console.WriteLine("我是产品A");
    5         }
    1         public override void DiffMehtod()
    2         {
    3             Console.WriteLine("我是产品B");
    4         }
     1     public class Factory
     2     {
     3         public static Product GetProduct(string arg)
     4         {
     5             Product product = null;
     6             if (arg == "A")
     7             {
     8                 product = new ConcreteProductA();
     9             }
    10             else if (arg == "B")
    11             {
    12                 product = new ConcreteProductA();
    13             }
    14             return product;
    15         }
    16     }

    客户端测试代码:

     1     class Program
     2     {
     3         static void Main(string[] args)
     4         {
     5             Product product;
     6             product = Factory.GetProduct("A");
     7             product.SameMehtod();
     8             product.DiffMehtod();
     9         }
    10     }

    三、方案的改进

      上述方案在创建具体Product对象时,每更换一个Product对象都需要修改客户端代码中静态工厂方法的参数,客户端代码将要重新编译,对于客户端而言,违反了开闭原则。

          下面将介绍一种在不修改客户端代码的前提下更换具体产品对象的实现方式。

          可以将静态工厂方法的参数存储在XML格式的配置文件中,如App.config,代码如下:

          

    1 <?xml version="1.0" encoding="utf-8" ?>
    2 <configuration>
    3   <appSettings>
    4     <add key="name" value="A"/>
    5   </appSettings>
    6 </configuration>

    客户端代码:

       class Program
        {
            static void Main(string[] args)
            {
                Product product;
                string type = ConfigurationManager.AppSettings["name"];
                product = Factory.GetProduct(type);
                product .DiffMethod();
                Console.ReadKey();
            }
        }

    不难发现,在上述代码中不包含任何与具体图表对象相关的信息,如果需要更换具体图表对象,只需要修改配置文件,无须修改任何源代码,符合开闭原则。

    四、简单工厂模式总结

    简单工厂模式提供了专门的工厂类用于创建对象,将对象的创建和对象的使用分离开,它作为一种最简单的工厂模式在软件开发中得到了较为广泛的应用。

    1.优点

    (1)实现了对象创建和使用的分离。

    (2)通过引入配置文件,可以再不修改任何客户端代码的情况下更换和增加新的具体类,在一定程度上提高了系统的灵活性。

    2.缺点

    (1)系统扩展困难,一旦添加新产品就不得不修改工厂逻辑,在产品类型较多时,有可能造成工厂逻辑过于复杂,不利于系统的扩展和维护。

    (2)增加了系统中类的数量,增加了系统的复杂度和难理解度。

    3.适应场景

    (1)工厂类负责创建的对象比较少,由于创建的对象较少,不会造成工厂方法中的业务逻辑太过复杂。

    (2)客户端只知道传入工厂类的参数,对于如何创建对象不关心。

  • 相关阅读:
    已知前序中序后序中的两种,如何求另一种
    sql(上)例题
    sql语句顺序/包含执行顺序和书写顺序
    VScode中文乱码问题
    好用的后台管理模板Bootstrap3
    手把手教你用Typora自动上传到picgo图床【教程与排坑】
    解决GitHub网页githubusercontent地址无法访问问题
    Java学习+面试指南(转)
    Linux C/C++ 方向学习经验【转】
    Scrapy学习笔记(一)
  • 原文地址:https://www.cnblogs.com/sunshineground/p/3586940.html
Copyright © 2011-2022 走看看