设计模式学习(四): 1.简单工厂 (附C#实现)
时间:2022-04-29
本文章向大家介绍设计模式学习(四): 1.简单工厂 (附C#实现),主要内容包括New、需求、建立一个简单的披萨工厂、简单工厂 Simple Factory、基本概念、基础应用、原理机制和需要注意的事项等,并结合实例形式分析了其使用技巧,希望通过本文能帮助到大家理解应用这部分内容。
New
这是一个典型的情况, 我们需要在运行时来实例化一些具体的类. 在需要修改或者扩展的时候我们就需要改这段代码. 一个程序中可能会多次出现类似的代码, 这使得维护和更新非常困难而且容易出错.
通过面向接口的编程, 我们可以把自己从各种变化中隔离出来, 因为如果代码是面向接口的话, 那么通过多态机制, 任何实现了该接口的新类都可以直接被使用.
所以别忘了设计原则: 对修改关闭.
需求
假设你是个披萨店老板, 有以下代码:
这是订购披萨的过程.
而你可能需要多种披萨:
这里就是根据参数来创建不同类型的披萨实例. 然后再进行下一步操作.
但是这样的事情可能会发生: 添加新类型披萨, 淘汰某些类型的披萨.
对代码修修改改. 所以这不是对修改关闭. 上面那部分代码需要修修改改, 下面那部分代码是固定不变的. 那最好的办法就是封装它.
封装对象的创建
需要把变化的部分封装起来, 也就是把创建披萨那部分代码移动到另外一个对象里, 而这个对象将专注于创建披萨.
针对这种对象, 它有一个名字, 叫工厂(Factory). 工厂会处理对象创建的细节.
建立一个简单的披萨工厂
这个类只有一个任务: 为客户创建披萨.
为什么不适用静态(static)方法?
可以使用static方法, 这样的话你就不需要创建一个对象然后再调用方法了. 但是这么做也有一个缺点, 那就是不可以对它继承了, 也无法改变create方法的行为了.
使用SimpleFactory之后:
简单工厂 Simple Factory
简单工厂实际上并不是设计模式, 可以更多的认为是一种编程范式. 但是使用的却是非常广泛.
理清一下目前的情况:
C#实现:
namespace C04FactoryPattern.Bases
{
public interface IPizza
{
string Type { get; }
void Prepare();
void Bake();
void Cut();
void Box();
}
}
namespace C04FactoryPattern.Bases
{
public interface IPizzaStore
{
Pizza OrderPizza(string type);
}
}
namespace C04FactoryPattern.Bases
{
public abstract class Pizza: IPizza
{
public abstract string Type { get;}
public void Prepare()
{
Console.WriteLine($"{Type} is Preparing...");
}
public void Bake()
{
Console.WriteLine($"{Type} is Baking...");
}
public void Cut()
{
Console.WriteLine($"{Type} is Cutting...");
}
public void Box()
{
Console.WriteLine($"{Type} is Boxing...");
}
}
}
namespace C04FactoryPattern.Models
{
public class CheesePizza : Pizza
{
public override string Type => nameof(CheesePizza);
}
public class ClamPizza : Pizza
{
public override string Type => nameof(ClamPizza);
}
public class PepperoniPizza : Pizza
{
public override string Type => nameof(PepperoniPizza);
}
public class VeggiePizza : Pizza
{
public override string Type => nameof(VeggiePizza);
}
}
namespace C04FactoryPattern.SimpleFactory
{
public class SimplePizzaFactory
{
public Pizza CreatePizza(string type)
{
Pizza pizza = null;
switch (type)
{
case nameof(CheesePizza):
pizza = new CheesePizza();
break;
case nameof(ClamPizza):
pizza = new ClamPizza();
break;
case nameof(PepperoniPizza):
pizza = new PepperoniPizza();
break;
case nameof(VeggiePizza):
pizza = new VeggiePizza();
break;
}
return pizza;
}
}
}
namespace C04FactoryPattern.SimpleFactory
{
public class PizzaStore: IPizzaStore
{
private readonly SimplePizzaFactory _factory;
public PizzaStore(SimplePizzaFactory factory)
{
_factory = factory;
}
public Pizza OrderPizza(string type)
{
var pizza = _factory.CreatePizza(type);
if (pizza != null)
{
pizza.Prepare();
pizza.Bake();
pizza.Cut();
pizza.Box();
Console.WriteLine($"{type} Done!!!");
}
else
{
Console.WriteLine("We don't have this kind of pizza!!");
}
return pizza;
}
}
}
测试:
namespace C04FactoryPattern
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Simple Factory:");
PizzaStore pizzaStore = new PizzaStore(new SimplePizzaFactory());
pizzaStore.OrderPizza(nameof(CheesePizza));
pizzaStore.OrderPizza(nameof(PepperoniPizza));
Console.ReadLine();
}
}
}
- Apache nutch1.5 & Apache solr3.6
- mysql数据迁移hbase问题
- hbase问题总结
- mysql DUPLICATE KEY UPDATE 问题
- mysql复制学习二 安装及首次复制配置
- 关于操作权限
- hadoop loadBalance源码分析
- writeup | 应该不是 XSS
- Hbase 源码分析之 Get 流程及rpc原理
- MOCTF WEB 题解
- HBase行锁与MVCC分析
- HBase行锁探索
- Spring Cloud构建微服务架构:分布式服务跟踪(抽样收集)【Dalston版】
- HBase client访问ZooKeeper获取root-region-server DeadLock问题(zookeeper.ClientCnxn Unable to get data of zn
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法