简单工厂模式(Simple Factory Pattern)

该文章的最新版本已迁移至个人博客【比特飞】,单击链接 https://www.byteflying.com/archives/387 访问。

简单工厂模式属于创建型模式,又叫做静态工厂方法(Static Factory Method)模式,但不属于23种GoF设计模式之一。学习简单工厂模式是学习其它工厂模式的前提条件。

简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例。简单工厂模式是工厂模式家族中最简单实用的模式,可以理解为是不同工厂模式的一个特殊实现。

角色:

1、工厂(Creator)

简单工厂模式的核心,它负责实现创建所有实例的内部逻辑。工厂类的创建产品类的方法可以被外界直接调用,创建所需的产品对象;

2、抽象产品(Product)

简单工厂模式所创建的所有对象的抽象基类,它负责描述所有实例所共有的公共接口;

3、具体产品(Concrete Product)

这是简单工厂模式的创建目标,所有创建的对象都是充当这个角色的某个具体类的实例。

示例:

命名空间SimpleFactory中包含抽象水果基类Fruit、三个具体水果类、水果工厂类FruitFactory、未知水果异常类UnknowFruitException。本案例将向大家展示如何使用简单工厂模式来生产不同种类的水果。

namespace SimpleFactory
public abstract class Fruit {

    protected Color Color { get; set; } = Color.Orange;

    protected abstract string BornInfo();

    protected const string LINE_BREAK =
"------------------------------------------------------------"; public void WhatsFruit() {
Console.WriteLine("Printing!");
OnPrint();
Console.WriteLine("Printed!");
OnPrinted();
} protected virtual void OnPrint() {
Console.WriteLine($"I'm a(n) {this.ToString().Replace(nameof(SimpleFactory) + ".", "")} " +
$"with {Color.ToString()} and I born in {BornInfo()}!");
} protected virtual void OnPrinted() {
Console.WriteLine(LINE_BREAK);
} }

抽象水果基类Fruit 包含颜色Color属性、出生信息BornInfo抽象方法、这是什么水果WhatsFruit方法、打印水果OnPrint和打印完OnPrinted方法。

C#开发笔记之01-为什么开源框架会大量的使用protected virtual?

public class Apple : Fruit {

    public Apple() {
Color = Color.Red;
} protected override string BornInfo() => "summer"; protected override void OnPrint() {
Console.WriteLine($"I'm an apple with {Color.ToString()},not an IPhone!");
} }
public class Orange : Fruit {

    protected override string BornInfo() => "autumn";

    protected override void OnPrinted() {
Console.WriteLine("override OnPrinted()!");
Console.WriteLine(LINE_BREAK);
} }
public class Pear : Fruit {

    public Pear() {
Color = Color.Yellow;
} protected override string BornInfo() => "China"; }

具体水果类,苹果Apple类、橘子Orange类和梨子Pear类,各自实现或重写不同的构造函数、抽象方法、虚拟方法和属性。

public enum FruitType {
Unknow = -1,
Apple,
Orange,
Pear
}
public static class FruitFactory {

    public static Fruit CreateFruit(FruitType type) {
Fruit fruit = null;
switch (type) {
case FruitType.Apple:
fruit = new Apple();
break;
case FruitType.Orange:
fruit = new Orange();
break;
case FruitType.Pear:
fruit = new Pear();
break;
default:
throw new UnknowFruitException();
} return fruit;
} }

水果工厂类FruitFactory,该类是简单工厂的核心类,包含CreateFruit方法,传递FruitType参数以便确定产出何种水果。方法返回抽象水果基类,以便调用方使用基类变量接受返回值。

public class UnknowFruitException : Exception {

    public UnknowFruitException()
: base("Not Supported Fruit!") { } public UnknowFruitException(string message, Exception innerException)
: base(message, innerException) { } }

使用未知水果异常类UnknowFruitException,进行简单的异常处理。

public static void Main(string[] args) {
try {
var fruit = FruitFactory.CreateFruit(FruitType.Pear);
fruit.WhatsFruit(); fruit = FruitFactory.CreateFruit(FruitType.Apple);
fruit.WhatsFruit(); fruit = FruitFactory.CreateFruit(FruitType.Orange);
fruit.WhatsFruit(); fruit = FruitFactory.CreateFruit(FruitType.Unknow);
fruit.WhatsFruit();
}
catch (UnknowFruitException ex) {
Console.WriteLine(nameof(UnknowFruitException) + ":" + ex.Message);
}
catch (Exception ex) {
Console.WriteLine(nameof(Exception) + ":" + ex.Message);
} Console.ReadKey();
}

调用方用变量fruit接受水果工厂不同的产出,由WhatsFruit方法在控制台打印出水果信息,用catch分别处理不同类型的异常。以下是这个案例的输出结果:

Printing!
I'm a(n) Pear with Color [Yellow] and I born in China!
Printed!
-----------------------------------------------------------
Printing!
I'm an apple with Color [Red],not an IPhone!
Printed!
-----------------------------------------------------------
Printing!
I'm a(n) Orange with Color [Orange] and I born in autumn!
Printed!
override OnPrinted()!
-----------------------------------------------------------
UnknowFruitException:Not Supported Fruit!

优点:

该文章的最新版本已迁移至个人博客【比特飞】,单击链接 https://www.byteflying.com/archives/387 访问。

1、工厂类是整个模式最核心的部分,包含了对象的创建逻辑。调用者无需关心对象创建的细节,只要给出参数,就可以得到相应的对象;

2、他们之间相互独立,各司其职,有利于整个软件体系架构。

缺点:

1、由于工厂类集中了所有实例的创建逻辑,违反了高内聚责任分配原则;

2、将全部创建逻辑集中到了一个工厂类中,如果需要添加新的类,则就需要改变工厂类了,明显违反开闭原则。工厂方法模式中这个问题有一定程度的缓解。

使用场景:

1、工厂类负责创建的对象比较少;

2、客户只知道传入工厂类的参数,对于创建对象的细节不关心或无法知道;

3、由于简单工厂很容易违反高内聚责任分配原则,所以在实际开发中很少用到。

C#设计模式之0-简单工厂模式的更多相关文章

  1. java设计模式-----1、简单工厂模式

    简单工厂模式是属于创建型模式,又叫做静态工厂方法(Static Factory Method)模式,但不属于23种GOF设计模式之一.简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例,简单来说 ...

  2. C#设计模式系列:简单工厂模式(Simple Factory)

    1. 简单工厂模式简介 1.1 定义 简单工厂模式定义一个Factory类,可以根据参数的不同返回不同类的实例,被创建的实例通常有共同的父类. 简单工厂模式只需要一个Factory类. 简单工厂模式又 ...

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

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

  4. 大话设计模式C++版——简单工厂模式

    简单工厂模式应该是所有设计模式中最简单,也最基础的一种模式,以下是一个简单的采用工厂模式写一个加减法的计算器. 1.抽象接口类——依赖倒转原则(高层和底层都要依赖于抽象,针对接口编程) class I ...

  5. 设计模式笔记:简单工厂模式(Simple Factory)

    1. 简单工厂模式简介 1.1 定义 简单工厂模式:定义一个Factory类,可以根据参数的不同返回不同类的实例,被创建的实例通常有共同的父类. 简单工厂模式:只需要一个Factory类. 简单工厂模 ...

  6. 深入浅出《设计模式》之简单工厂模式(C++)

    前言 模式介绍 简单工厂模式其实并不属于GoF23(23种设计模式),更类似工厂模式的一种变型.其定义是可以根据参数的不同返回不同类的实例.简单工厂模式专门定义一个类来负责创建其他类的实例,被创建的实 ...

  7. Java设计模式2:简单工厂模式

    简单工厂模式 简单工厂模式是类的创建模式,又叫做静态工厂方法模式.简单工厂模式由一个工厂对象决定生产出哪一种产品类的实例. 为什么要使用简单工厂模式 原因很简单:解耦. A对象如果要调用B对象,最简单 ...

  8. IOS设计模式浅析之简单工厂模式(SimpleFactory)

    概述 首先说明一下,简单工厂模式不属于23种GOF设计模式之一.它也称作静态工厂方法模式,是工厂方法模式的特殊实现.这里对简单工厂模式进行介绍,是为本系列后面的工厂方法和抽象工厂模式做一个引子. 定义 ...

  9. C#设计模式之二简单工厂模式(过渡模式)

    一.引言 之所以写这个系列,是了为了自己更好的理解设计模式,也为新手提供一些帮助,我都是用最简单的.最生活化的实例来说明.在上一篇文章中讲解了单例模式,今天就给大家讲一个比较简单的模式--简单工厂模式 ...

  10. Java设计模式学习记录-简单工厂模式、工厂方法模式

    前言 之前介绍了设计模式的原则和分类等概述.今天开启设计模式的学习,首先要介绍的就是工厂模式,在介绍工厂模式前会先介绍一下简单工厂模式,这样由浅入深来介绍. 简单工厂模式 做法:创建一个工厂(方法或类 ...

随机推荐

  1. git和github连接权限(这是一个简便方法,不是很安全,建议大家还是用ssh解决)

    在使用,git从github上clone下来代码后. 我们再工作区进行编辑,然后提交. 最后我们想要将我们的改变推送到github上. 但是往往这个时候,我们可能会面临这样的问题. 我们没有权限将代码 ...

  2. 【Nginx】面试官问我Nginx能不能配置WebSocket?我给他现场演示了一番!!

    写在前面 当今互联网领域,不管是APP还是H5,不管是微信端还是小程序,只要是一款像样点的产品,为了增加用户的交互感和用户粘度,多多少少都会涉及到聊天功能.而对于Web端与H5来说,实现聊天最简单的就 ...

  3. iview实战 : 全屏去头去尾的弹窗

    <template> <Button @click="modal3 = true" >No title bar</Button> <Mod ...

  4. BT面板安装教程

    面板特点 一键配置服务器环境(LAMP/LNMP) 一键安全重启 一键创建管理网站.ftp.数据库 一键配置(定期备份.数据导入.伪静态.301.SSL.子目录.反向代理.切换PHP版本) 一键安装常 ...

  5. 题解 洛谷 P6349 【[PA2011]Kangaroos】

    先考虑对题目进行转化,我们称两个区间有交集为这两个区间能匹配,每个询问就是在序列中最长能连续匹配的长度. 对序列中的一个区间\([l,r]\)和询问的一个区间\([L,R]\),若满足\(L \leq ...

  6. Delphi获取文件名、不带扩展名文件名、文件所在路径、上级文件夹路径的方法

    1.获取不带扩展名的文件名方法,利用ChangeFileExt函数修改传入参数的扩展为空,并不会对文件本身产生变更. ChangeFileExt(ExtractFileName('D:\KK\Test ...

  7. java基础(二)--main方法讲解

    main()函数是如下的固定格式,除了args可以修改名字,其余均不可以修改 public class TestBase02MainMath { public static void main(Str ...

  8. Git文件合并

    两个分支:主分支master,分支pre 1.将pre分支文件合并到master分支: 切换到master分支下操作: 合并文件夹[如果是文件则为a.text b.text]: git checkou ...

  9. reverse 字符串翻转

    头文件 algorithm string s="hello"; reverse(s.begin(),s.end()); char c[]="hello"; re ...

  10. Docker引言,由来,思想

    引言 我本地运行没问题啊? 环境不一致? 哪个哥们又写死循环了?,怎么这么卡? 在多用户操作系统下,会相互影响 淘宝在双11的时候,用户量暴增 运维成果过高的问题 学习一门技术,学习安装成本高 关于安 ...