首页 > 其他分享 >工厂模式

工厂模式

时间:2024-02-27 09:01:42浏览次数:21  
标签:咖啡 模式 public CreateCoffee Brew 工厂 class

简单工厂

简介

简单工厂通过一个单独的工厂类来创建不同类型的对象,根据客户端的需求决定创建哪种产品类的实例。

简单工厂模式封装了对象的创建过程,使得客户端不需要知道具体的对象创建细节,只需与工厂类交互即可获得所需的对象。

简单工厂模式是工厂模式家族中最简单实用的模式之一,可理解为工厂模式的一种特殊实现。

简单工厂模式不属于23种GOF设计模式之一。

示例

假设你是一个咖啡店的顾客,你到咖啡店里想要点一杯咖啡。在咖啡店里,有一个咖啡师负责制作各种类型的咖啡,比如美式咖啡、拿铁、卡布奇诺等等。

当你告诉咖啡师你想要什么样的咖啡时,比如说你要一杯拿铁,咖啡师就会根据你的要求准备一杯拿铁咖啡给你,而你不需要知道拿铁咖啡是如何制作的,也不需要知道咖啡师的具体操作步骤,只需要告诉咖啡师你的需求,咖啡师就会为你制作出符合你要求的咖啡。

在这个例子中,咖啡师可以被视为一个简单工厂,他负责根据顾客的需求制作不同类型的咖啡。顾客不需要知道咖啡是如何制作的,也不需要知道咖啡师的具体操作步骤,只需要告诉咖啡师自己想要什么样的咖啡,咖啡师就会为顾客提供相应的咖啡。

using System;

// 定义咖啡类
public abstract class Coffee
{
    public abstract void Brew();
}

// 定义不同类型的咖啡类
public class Americano : Coffee
{
    public override void Brew()
    {
        Console.WriteLine("制作美式咖啡");
    }
}

public class Latte : Coffee
{
    public override void Brew()
    {
        Console.WriteLine("制作拿铁咖啡");
    }
}

public class Cappuccino : Coffee
{
    public override void Brew()
    {
        Console.WriteLine("制作卡布奇诺咖啡");
    }
}

// 定义咖啡工厂类
public class CoffeeFactory
{
    // 根据咖啡类型创建对应的咖啡对象
    public static Coffee CreateCoffee(string type)
    {
        switch (type.ToLower())
        {
            case "americano":
                return new Americano();
            case "latte":
                return new Latte();
            case "cappuccino":
                return new Cappuccino();
            default:
                throw new ArgumentException("不支持的咖啡类型");
        }
    }
}

class Program
{
    static void Main(string[] args)
    {
        // 客户点一杯拿铁
        Coffee latte = CoffeeFactory.CreateCoffee("latte");
        latte.Brew();

        // 客户点一杯美式
        Coffee americano = CoffeeFactory.CreateCoffee("americano");
        americano.Brew();

        // 客户点一杯卡布奇诺
        Coffee cappuccino = CoffeeFactory.CreateCoffee("cappuccino");
        cappuccino.Brew();
    }
}

缺点

  1. 违反开闭原则(OCP):当需要添加新的产品类型时,通常需要修改工厂类的代码,这违反了开闭原则,即系统应该对扩展开放,对修改关闭的原则。

  2. 责任过重:简单工厂模式的工厂类负责创建多种产品类型的对象,导致工厂类的责任过重,随着产品类型的增多,工厂类的代码可能会变得庞大、复杂,不利于维护和扩展。

  3. 耦合度高:客户端代码与具体产品类型紧密耦合,因为客户端需要知道可用的产品类型,并且直接依赖于工厂类来创建对象,导致了耦合度的增加。

工厂模式

在工厂方法模式中,每个具体产品都有对应的工厂类,工厂类负责创建特定类型的产品对象。这样一来,当需要添加新的产品类型时,只需创建对应的新产品类和工厂类即可,无需修改原有的工厂类,符合开闭原则。

以咖啡为例,工厂方法模式中可能会有多个工厂类,比如美式咖啡工厂、拿铁咖啡工厂、卡布奇诺咖啡工厂等,每个工厂类负责创建对应类型的咖啡对象。这样,当需要添加新类型的咖啡时,只需创建新的具体产品类和对应的工厂类,不会影响已有的代码结构,实现了系统的可扩展性和维护性。

using System;

// 定义咖啡接口
public interface ICoffee
{
    void Brew();
}

// 具体的咖啡类
public class Americano : ICoffee
{
    public void Brew()
    {
        Console.WriteLine("制作美式咖啡");
    }
}

public class Latte : ICoffee
{
    public void Brew()
    {
        Console.WriteLine("制作拿铁咖啡");
    }
}

public class Cappuccino : ICoffee
{
    public void Brew()
    {
        Console.WriteLine("制作卡布奇诺咖啡");
    }
}

// 定义咖啡工厂接口
public interface ICoffeeFactory
{
    ICoffee CreateCoffee();
}

// 具体的咖啡工厂类
public class AmericanoFactory : ICoffeeFactory
{
    public ICoffee CreateCoffee()
    {
        return new Americano();
    }
}

public class LatteFactory : ICoffeeFactory
{
    public ICoffee CreateCoffee()
    {
        return new Latte();
    }
}

public class CappuccinoFactory : ICoffeeFactory
{
    public ICoffee CreateCoffee()
    {
        return new Cappuccino();
    }
}

class Program
{
    static void Main(string[] args)
    {
        // 创建美式咖啡
        ICoffeeFactory americanoFactory = new AmericanoFactory();
        ICoffee americano = americanoFactory.CreateCoffee();
        americano.Brew();

        // 创建拿铁咖啡
        ICoffeeFactory latteFactory = new LatteFactory();
        ICoffee latte = latteFactory.CreateCoffee();
        latte.Brew();

        // 创建卡布奇诺咖啡
        ICoffeeFactory cappuccinoFactory = new CappuccinoFactory();
        ICoffee cappuccino = cappuccinoFactory.CreateCoffee();
        cappuccino.Brew();
    }
}

优点:

  1. 符合开闭原则(OCP):工厂方法模式允许系统在不修改现有代码的情况下引入新的产品类型,通过添加新的具体工厂类和产品类来扩展系统,因此符合开闭原则。
  2. 降低了客户端与具体产品类之间的耦合:客户端只依赖于抽象的工厂接口和产品接口,不需要直接与具体的产品类耦合,从而降低了耦合度,提高了系统的灵活性和可维护性。
  3. 具体产品的创建延迟到具体工厂类:工厂方法模式将具体产品的创建推迟到具体工厂类中,每个具体工厂类负责创建特定类型的产品对象,使得系统的结构更加清晰,易于理解和扩展。

缺点:

  1. 类的数量增加:工厂方法模式引入了多个工厂类和产品类,导致了类的数量增加,增加了系统的复杂度。
  2. 可能会导致类的层次结构复杂化:如果产品类的种类过多,可能会导致工厂类的层次结构变得复杂,不利于系统的管理和维护。
  3. 每个具体产品都需要一个具体工厂类:每种具体产品都需要对应的具体工厂类,当产品种类较多时,可能会导致工厂类的数量增加,不利于系统的管理和维护。

标签:咖啡,模式,public,CreateCoffee,Brew,工厂,class
From: https://www.cnblogs.com/mchao/p/18034698

相关文章

  • 可编辑模式下安装 python 包
    可编辑模式下安装python包一般情况下,我们使用的是pipinstallpkg来完成包的安装,默认的安装的目标目录在site-packages下,这种情况非常适合我们引用某些成熟包.如果我们想要给github某个项目贡献PR,或者仅仅要魔改一下某个项目,可以使用editable模式来安装.edit......
  • centos7安装hadoop(集群模式)
    目录节点规划安装前准备准备jdk和hadoop的安装文件分别修改三台主机名字建立hadoop账号添加账号并且指定密码添加hadoop账号到sudo组,vi/etc/soduers切换到hadoop账号配置三台主机的证书登录解压jdk和hadoop配置环境变量复制jdk和配置文件到别的节点使环境变量生效编辑文件修改修......
  • 单例模式
    简介单例模式是一种常见的设计模式,用于确保类只有一个实例,并提供一个全局访问点。以下是一个简单的单例模式的示例双重检查锁定经典的双重检查锁定是一种常见的在多线程环境下延迟初始化对象的方式。下面是一个使用双重检查锁定的单例模式的示例代码:usingSystem;publicse......
  • 面向对象,到底是个什么鬼? (设计模式)
    什么才算是面向对象编程语言面向对象是支持类对性得语法机制,并有现成得语法机制,能方便得实现面向对象得封装,继承多态,抽象。 一般来讲,面型对象编程,是通过面向对像得编程语言来进行得,但是不用面型对象编程语言,我们照样可以进行面向对象编程,反过来讲,即使我们使用面向像得语言写出......
  • 那些维度评价代码的好坏?设计模式
    1.可维护性对于项目来说,维护代码的耗时,远远大于大于代码的编码。代码维护性非常关键主观评价标准:bug容易修复,添加功能比较简单。2.可读性代码的可读性,关乎代码的可维护性。 代码是否符合代码的命名规范。 命名是否规范,注释是否全面,函数是否长短合适,模块划分是否清......
  • 享元模式
    享元模式(flyweightpattern)定义: 摈弃了在每个对象中保存所有数据的方式,通过共享多个对象所共有的相同状态,从而让我们能在优先的内存容量中载入更多的对象。 从这个定义可以发现,享元模式要解决的核心问题就是节约内存空间,使用的办法是找出相似对象之间的共有特征,然后复用这些特......
  • 在K8S中,kube-proxy的工作模式是什么?
    kube-proxy在Kubernetes集群中负责实现Service的网络代理和负载均衡功能,支持三种不同的工作模式:Userspace模式(已过时):在早期的Kubernetes版本中(1.2之前),kube-proxy默认使用Userspace模式。在此模式下,kube-proxy作为一个用户空间进程运行,为每个Service创建一个......
  • 优化通道颜色控制问题 - 使用状态模式
    在软件开发中,经常会遇到需要控制通道颜色的场景。如何优化通道颜色控制逻辑,提高代码的可维护性和扩展性呢?本篇博客将介绍如何使用状态模式来优化通道颜色控制逻辑。问题描述假设我们有一个需求:根据不同的通道状态来控制通道显示的颜色。通道状态包括正常状态、加热状态等。我们......
  • 类变量和类方法、代码块、单例设计模式、final关键字、抽象类、接口、内部类
    类变量和类方法类变量-提出问题说:有一群小孩在玩堆雪人,不时有新的小孩加入,请问如何知道现在共有多少人在玩?,编写程序解决。传统的方法来解决思路在main方法中定义一个变量count当一个小孩加入游戏后count++,最后个count就记录有多少小孩玩游戏小孩是一个类,有名字属......
  • 01 单例模式
    usingUnityEngine;publicclassSingleton:MonoBehaviour{////饿汉式单例////privatestaticSingleton_instance=new();//privatestaticSingleton_instance;//publicstaticSingletonInstance=>_instance;//privatevoidAwake()=&g......