• 简单工厂模式概述

  1. 定义:定义一个工厂类,他可以根据参数的不同返回不同类的实例,被创建的实例通常都具有共同的父类
  2. 在简单工厂模式中用于被创建实例的方法通常为静态(static)方法,因此简单工厂模式又被成为静态工厂方法(Static Factory Method)
  3. 需要什么,只需要传入一个正确的参数,就可以获取所需要的对象,而无需知道其实现过程

  4. 例如,我开一家披萨店,当客户需要某种披萨并且我这家店里也能做的时候,我就会为其提供所需要的披萨(当然是要钱的哈哈),如果其所需的我这没有,则是另外的情况,后面会谈。这时候,我这家 披萨店就可以看做工厂(Factory),而生产出来的披萨被成为产品(Product),披萨的名称则被称为参数,工厂可以根据参数的不同返回不同的产品,这就是简单工厂模式
  • 简单工厂模式的结构与实现

  • 结构:
  1. Factory(工厂):核心部分,负责实现创建所有产品的内部逻辑,工厂类可以被外界直接调用,创建所需对象
  2. Product(抽象类产品):工厂类所创建的所有对象的父类,封装了产品对象的公共方法,所有的具体产品为其子类对象
  3. ConcreteProduct(具体产品):简单工厂模式的创建目标,所有被创建的对象都是某个具体类的实例。它要实现抽象产品中声明的抽象方法(有关抽象类)
  • 实现

     abstract class Product
    {
    public void MethName()
    {
    //公共方法的实现
    }
    public abstract void MethodDiff();
    //声明抽象业务方法
    }
    class ConcreteProductA : Product
    {
    public override void MethodDiff()
    {
    //业务方法的实现
    }
    } class Factory
    {
    public static Product GetProduct(string arg)
    {
    Product product = null;
    if(arg.Equals("A")
    {
    product = new ConcreteProductA();
    //init
    }
    else if(arg.Equals("B"))
    {
    product = new ConcreteProductB();
    //init
    }
    else
    {
    ....//其他情况
    }
    return product;
    }
    } class Program
    {
    static void Main(string[] args)
    {
    Product product;
    product = Factory.GetProduct("A");//工厂类创建对象
    Product.MethName();
    product.MethodDiff();
    }
    }
  • 简单工厂模式的简化

  1. 为了简化简单工厂模式,将抽象产品类和工厂类合并,将静态工厂方法移到抽象产品类中
  2. 客户端可以调用产品父类的静态工厂方法,根据不同的参数创建不同类型的产品子类对象。
  • 简单工厂模式的优缺点和适用环境  

  • 简单工厂模式的优点

    (1)工厂类包含必要的逻辑判断,可以决定在什么时候创建哪一个产品的实例。客户端可以免除直接创建产品对象的职责
    (2)客户端无需知道所创建具体产品的类名,只需知道参数即可
    (3)也可以引入配置文件,在不修改客户端代码的情况下更换和添加新的具体产品类。(这也是我在开始的披萨店里遇到没有的披萨的解决情况)

  • 简单工厂模式的缺点

    (1)工厂类集中了所有产品的创建逻辑,职责过重,一旦异常,整个系统将受影响
    (2)使用简单工厂模式会增加系统中类的个数(引入新的工厂类),增加系统的复杂度和理解难度
    (3)系统扩展困难,一旦增加新产品不得不修改工厂逻辑,在产品类型较多时,可能造成逻辑过于复杂
    (4)简单工厂模式使用了static工厂方法,造成工厂角色无法形成基于继承的等级结构。

  • 简单工厂模式的适用环境

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

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

  • 简单案例

  1. 题目:

    使用简单工厂模式设计一个可以创建不同几何图形(Shape),如Circle,Rectangle,Triangle等绘图工具类,每个几何图形均具有绘制Draw()和擦除Erase()两个方法
    要求在绘制不支持的几何图形时,抛出一个UnsuppShapeException异常,绘制类图并使用C#语言实现。

  2. UML:


  3.  using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    /*使用简单工厂模式设计一个可以创建不同几何图形(Shape),如Circle,Rectangle,Triangle等绘图工具类,每个几何图形均具有绘制Draw()和擦除Erase()两个方法
    * 要求在绘制不支持的几何图形时,抛出一个UnsuppShapeException异常,绘制类图并使用C#语言实现。
    */ namespace SimpleShapeFactory
    {
    public interface InShape//图形接口 抽象产品类
    {
    void Draw();
    void Erase();
    } public class Circle : InShape//圆形类,具体产品类
    {
    private static int count; //生成图形计数
    string radious;
    public Circle()//构造
    {
    Console.WriteLine("Create Circle");
    Console.WriteLine("Input the radious of Circle:");
    radious = Console.ReadLine();
    }
    public void Draw()//实现接口方法
    {
    int Radious = int.Parse(radious);
    Console.WriteLine("Display circle " + (++count) +" information:");
    Console.WriteLine("Circle "+ count+ " circumference:" + * Radious * 3.14159);
    Console.WriteLine("Circle "+ count+" area:" + 3.14159 * Radious * Radious);
    }
    public void Erase()//实现接口方法
    {
    while (true)
    {
    Console.WriteLine("Erase current shape(y/n)?");
    string choose;
    choose = Console.ReadLine();
    if (choose.Equals("y") || choose.Equals("Y"))
    {
    Console.WriteLine("Erase Circle "+count +" successfully!");
    count--;
    break;
    }
    else if (choose.Equals("n") || choose.Equals("N"))
    {
    Console.WriteLine("Circle "+ count+" successfully saved!");
    break;
    }
    else
    {
    Console.WriteLine("Input error, re-enter!");
    }
    }
    }
    } class Rectangle : InShape//矩形类,具体产品类
    {
    private static int count = ;//生成图形计数
    string length;
    string wideth;
    public Rectangle()//构造
    {
    Console.WriteLine("Create Rectangle");
    Console.WriteLine("Input the length and wideth of Rectangle:");
    length = Console.ReadLine();
    wideth = Console.ReadLine();
    }
    public void Draw()//实现接口方法
    {
    int Length = int.Parse(length);
    int Wideth = int.Parse(wideth);
    Console.WriteLine("Display rectangle " + (++count) + " information:");
    Console.WriteLine("Rectangle "+ count + "circumference:" + * Length * Wideth);
    Console.WriteLine("Rectangle "+ count + "area:" + Length * Wideth); }
    public void Erase()//实现接口方法
    {
    while (true)
    {
    Console.WriteLine("Erase current shape(y/n)?");
    string choose;
    choose = Console.ReadLine();
    if (choose.Equals("y") || choose.Equals("Y"))
    {
    Console.WriteLine("Erase rectangle "+count+ "successfully!");
    --count;
    break;
    }
    else if (choose.Equals("n") || choose.Equals("N"))
    {
    Console.WriteLine("Rectangle "+ count+" successfully saved!");
    break;
    }
    else
    {
    Console.WriteLine("Input error, re-enter!");
    }
    }
    }
    } class Triangle : InShape//三角形类,具体产品类
    {
    private static int count = ;//生成图形计数
    string lengtha;
    string lengthb;
    string lengthc;
    public Triangle()//构造
    {
    Console.WriteLine("Create Triangle");
    Console.WriteLine("Input the lengtha ,lengthb and lengthc of Triangle:");
    lengtha = Console.ReadLine();
    lengthb = Console.ReadLine();
    lengthc = Console.ReadLine(); }
    public void Draw()//实现接口方法
    {
    int Lengtha = int.Parse(lengtha);
    int Lengthb = int.Parse(lengthb);
    int Lengthc = int.Parse(lengthc);
    if ((Lengtha + Lengthb > Lengthc) && (Lengtha + Lengthc > Lengthb) && (Lengthb + Lengthc > Lengtha))
    {
    double S = (Lengtha + Lengthb + Lengthc) * 0.5;
    double area = Math.Sqrt(S * (S - Lengtha) * (S - Lengthb) * (S - Lengthc));
    Console.WriteLine("Display triangle "+ (++count)+" information:");
    Console.WriteLine("Triangle " + count +" circumference:" + (Lengtha + Lengthb + Lengthc));
    Console.WriteLine("Triangle "+ count +" area:" + area);
    Erase();
    }
    else
    {
    Console.WriteLine("Create triangle failed!");
    }
    }
    public void Erase()//实现接口方法
    {
    while (true)
    {
    Console.WriteLine("Erase shape(y/n)?");
    string choose;
    choose = Console.ReadLine();
    if (choose.Equals("y") || choose.Equals("Y"))
    {
    Console.WriteLine("Erase tirangle " +count +" successfully!");
    --count;
    break;
    }
    else if (choose.Equals("n") || choose.Equals("N"))
    {
    Console.WriteLine("Triangle "+ count +" successfully saved!");
    break;
    }
    else
    {
    Console.WriteLine("Input error, re-enter!");
    }
    }
    }
    } class ShapeFactory//图形工厂类,充当工厂类
    {
    public static InShape Getshape(string type)//静态工厂方法
    {
    InShape shape;
    shape = null;
    if (type.Equals("Circle"))
    {
    shape = new Circle();
    Console.WriteLine("Init set Circle");
    shape.Draw();
    shape.Erase();
    }
    else if(type.Equals("Rectangle"))
    {
    shape = new Rectangle();
    Console.WriteLine("Init set Rectangle");
    shape.Draw();
    shape.Erase();
    }
    else if (type.Equals("Triangle"))
    {
    shape = new Triangle();
    Console.WriteLine("Init set Triangle");
    shape.Draw(); }
    else//异常 这里我应该声明调用异常处理类的,那样会更好些
    {
    Console.WriteLine("UnsupportShapeException!");
    Console.WriteLine("Emotional reminders :Pay 1 million$ to Alipay:132****6151 can create every shape you want!!! ");
    }
    return shape;
    }
    } class Program//客户端测试类
    {
    static void Main(string[] args)
    {
    while (true)
    {
    InShape shape;
    Console.WriteLine("Please input the shape you want to create");
    string str = Console.ReadLine();
    shape = ShapeFactory.Getshape(str);//通过静态工厂方法创建产品
    Console.ReadLine();
    }
    }
    }
    }
  4. 运行结果:
  5. 自我感觉写的一般般,如有不对的地方,欢迎指正。

简单工厂模式(Simple Factory Pattern)的更多相关文章

  1. 【设计模式】简单工厂模式 Simple Factory Pattern

    简单工厂模式Simple Factory Pattern[Simple Factory Pattern]是设计模式里最简单的一个模式,又叫静态工厂模式[Static Factory Pattern], ...

  2. Golang设计模式—简单工厂模式(Simple Factory Pattern)

    Golang设计模式--简单工厂模式 背景 假设我们在做一款小型翻译软件,软件可以将德语.英语.日语都翻译成目标中文,并显示在前端. 思路 我们会有三个具体的语言翻译结构体,或许以后还有更多,但现在分 ...

  3. 大白话简单工厂模式 (Simple Factory Pattern)

    大白话简单工厂模式 (Simple Factory Pattern) 从买车经历说起 毕业两年,码农张小两口无法忍受挤公交,凌晨起床抢火车票的痛苦,遂计划买车.逛了多家4S店,最终定下日产某车型的轿车 ...

  4. Net设计模式实例之简单工厂模式(Simple Factory Pattern)

    一.简单工厂模式简介(Bref Introduction) 简单工厂模式(Simple Factory Pattern)的优点是,工厂类中包含了必要的逻辑判断,根据客户端的选择条件动态实例化相关的类, ...

  5. 设计模式之—简单工厂模式<Simple Factory Pattern >

    简单工厂模式结构图: 简单工厂模式以简单的加减乘除运算为例: 运算符类(Operation): namespace CalcTest.Simple_Factory_patterns { class O ...

  6. 设计模式之简单工厂模式(Simple Factory Pattern)

    一.简单工厂模式的由来 所有设计模式都是为解决某类问题而产生的,那么简单工厂模式是为解决什么问题呢?我们假设有以下业务场景: 在一个学生选课系统中,文科生用户选课时,我们要获得文科生的所有课程列表:理 ...

  7. 【UE4 设计模式】简单工厂模式 Simple Factory Pattern

    概述 描述 又称为静态工厂方法 一般使用静态方法,根据参数的不同创建不同类的实例 套路 创建抽象产品类 : 创建具体产品类,继承抽象产品类: 创建工厂类,通过静态方法根据传入不同参数从而创建不同具体产 ...

  8. 六个创建模式之简单工厂模式(Simple Factory Pattern)

    定义: 定义一个工厂类,它可以根据参数的不同生成对应的类的实例:被创建的类的实例通常有相同的父类.因为该工厂方法尝尝是静态的,所以又被称为静态工厂方法(Static Factory Method) 结 ...

  9. 【java设计模式】【创建模式Creational Pattern】简单工厂模式Simple Factory Pattern(静态工厂方法模式Static Factory Method Pattern)

    public class Test { public static void main(String[] args){ try{ Factory.factory("A").doSt ...

随机推荐

  1. Python_重写集合

    class Set(object): def __init__(self,data=None): if data == None: self.__data = [] else: if not hasa ...

  2. linux定时任务cron配置

    实现linux定时任务有:cron.anacron.at,使用最多的是cron任务 名词解释 cron--服务名:crond--linux下用来周期性的执行某种任务或等待处理某些事件的一个守护进程,与 ...

  3. PAT1013: Battle Over Cities

    1013. Battle Over Cities (25) 时间限制 400 ms 内存限制 65536 kB 代码长度限制 16000 B 判题程序 Standard 作者 CHEN, Yue It ...

  4. SSM-MyBatis-04:Mybatis中使用properties整合jdbc.properties

    ------------吾亦无他,唯手熟尔,谦卑若愚,好学若饥-------------properties整合jdbc.properties首先准备好jdbc.properties,里面的key值写 ...

  5. Linux的文本处理工具浅谈-awk sed grep

    Linux的文本处理工具浅谈 awk   老大 [功能说明] 用于文本处理的语言(取行,过滤),支持正则 NR代表行数,$n取某一列,$NF最后一列 NR==20,NR==30 从20行到30行 FS ...

  6. 过滤emoji表情符

    1.使用正则匹配 public  function remove_emoji($text){        return preg_replace('/([0-9|#][\x{20E3}])|[\x{ ...

  7. js算法初窥04(算法模式01-递归)

    终于来到了有点意思的地方--递归,在我最开始学习js的时候,基础课程的内容就包括递归,但是当时并不知道递归的真正意义和用处.我只是知道,哦...递归是自身调用自身,递归要记得有一个停止调用的条件.那时 ...

  8. GO语言.树莓派.环境安装和测试

    Go是Google开发的一种静态强类型.编译型.并发型,并具有垃圾回收功能的编程语言.为了方便搜索和识别,有时会将其称为Golang 记录一下如何在树莓派上安装语言环境 第一步: 下载安装包 http ...

  9. Java8-6-Predicate接口详解

    转自https://segmentfault.com/a/1190000012256677 Predicate函数式接口的主要作用就是提供一个test方法,接受一个参数返回一个布尔类型,Predica ...

  10. 在MFC中怎么获得Excel文档中已经使用了的行数和列数

    _Worksheet ws;Range range; range = ws.GetUsedRange();//获得Worksheet已使用的范围range = range.GetRows();   / ...