设计模式——简单工厂 SimpleFactory

场景:解除上端对细节的依赖,把细节包一层,在另一层中处理

抽象类

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DesignMode.Interface
{
    public abstract class BasePhone
    {
        public abstract void Call();
        public abstract void Text();
    }
}

苹果手机

using DesignMode.Interface;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace SimpleFactory
{
    public class iPhone : BasePhone
    {
        public override void Call()
        {
            Console.WriteLine("use {0} call", this.GetType().Name);
        }

        public override void Text()
        {
            Console.WriteLine("use {0} text", this.GetType().Name);
        }
    }
}

华为手机

using DesignMode.Interface;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace SimpleFactory
{
    public class Honor : BasePhone
    {
        public override void Call()
        {
            Console.WriteLine("use {0} call", this.GetType().Name);
        }

        public override void Text()
        {
            Console.WriteLine("use {0} text", this.GetType().Name);
        }
    }
}

三星手机

using DesignMode.Interface;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace SimpleFactory
{
    public class Galaxy : BasePhone
    {
        public override void Call()
        {
            Console.WriteLine("use {0} call", this.GetType().Name);
        }

        public override void Text()
        {
            Console.WriteLine("use {0} text", this.GetType().Name);
        }
    }
}

工厂类

using Interface;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Model
{
    /// <summary>
    /// 解除上端对细节的依赖,把细节放到工厂中去
    /// </summary>
    public class ObjectFactory
    {
        /// <summary>
        /// 创建对象
        /// </summary>
        /// <param name="type"></param>
        /// <returns></returns>
        public static BasePhone CreateBasePhone(PhoneType type)
        {
            switch (type)
            {
                case PhoneType.Galaxy:
                    return new Galaxy();
                case PhoneType.iPhone:
                    return new iPhone();
                case PhoneType.Honor:
                    return new Honor();
                default:
                    throw new Exception("wrong PhoneType");
            }
        }

        /// <summary>
        /// 枚举
        /// </summary>
        public enum PhoneType
        {
            Galaxy,
            iPhone,
            Honor
        }
    }
}

上端调用

using Interface;
using Model;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            BasePhone galaxy = ObjectFactory.CreateBasePhone(ObjectFactory.PhoneType.Galaxy);
            BasePhone iphone = ObjectFactory.CreateBasePhone(ObjectFactory.PhoneType.iPhone);
            Console.ReadKey();
        }
    }
}

这里写图片描述

到这 实现简单工厂基础版


上面的上端调用 可能看起来还是有点不爽,因为貌似还有点细节

BasePhone galaxy = ObjectFactory.CreateBasePhone(ObjectFactory.PhoneType.Galaxy);

ObjectFactory.PhoneType.Galaxy

我就是不想让上端写明传什么枚举类型

接着改造 我的工厂类 这回我用了配置文件

using Interface;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Model
{
    /// <summary>
    /// 解除上端对象细节的依赖,把细节放到工厂中去
    /// </summary>
    public class ObjectFactory2
    {
        /// <summary>
        /// 枚举
        /// </summary>
        public enum PhoneType
        {
            Galaxy,
            iPhone,
            Honor
        }

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public static BasePhone CreateBasePhoneConfig()
        {
            //把字符串转换成枚举类型
            PhoneType type = (PhoneType)Enum.Parse(typeof(PhoneType), ConfigurationManager.AppSettings["PhoneType"]);
            switch (type)
            {
                case PhoneType.Galaxy:
                    return new Galaxy();
                case PhoneType.iPhone:
                    return new iPhone();
                default:
                    throw new Exception("wrong PhoneType");
            }
        }
    }
}

配置文件

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <startup> 
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
    </startup>

  <appSettings>
    <!--<add key="PhoneType" value="iPhone"/>-->
    <add key="PhoneType" value="Galaxy"/>
  </appSettings>
</configuration>

上端调用

using Interface;
using Model;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            BasePhone galaxy = ObjectFactory2.CreateBasePhoneConfig();
            Console.ReadKey();
        }
    }
}

这里写图片描述


既然可以读取配置文件来搞,那么干脆用反射玩

改造下简单工厂类

using Interface;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Model
{
    /// <summary>
    /// 解除上端对象细节的依赖,把细节放到工厂中去
    /// </summary>
    public class ObjectFactory3
    {
        public static BasePhone CreateBasePhoneConfigReflection()
        {
            //通过配置文件获取程 序集名称 [命名空间]
            string dllName = ConfigurationManager.AppSettings["dllName"];
            //通过配置文件获取类 型全名称 [命名空间+类名]
            string className = ConfigurationManager.AppSettings["className"];
            //反射创建对象
            return (BasePhone)Activator.CreateInstance(dllName,className).Unwrap();
        }
    }
}

配置文件

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <startup> 
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
    </startup>

  <appSettings>
    <!--程序集名称 [命名空间]-->
    <add key="dllName" value="Model"/>
    <!--类型全名称 [命名空间+类名]-->
    <add key="className" value="Model.Galaxy"/>
  </appSettings>
</configuration>

上端调用

using Interface;
using Model;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            BasePhone galaxy = ObjectFactory3.CreateBasePhoneConfigReflection();
            Console.ReadKey();
        }
    }
}

这里写图片描述

最后交代一下,用反射的方式玩工厂是最灵活的,从代码上来说 枚举都可以去掉了 !
比方说要加个“小米”手机,那么我们搞个“小米”类,继承一下”手机父类”, 编译一下,就可以跑起来,当然配置文件要改动

从程序设计原则上讲,简单工厂是违背了 “单一职责”
程序设计没有银弹

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
简单工厂模式(Simple Factory Pattern)是一种创建型设计模式,它通过一个工厂类来创建不同类型的对象,而无需暴露对象创建的逻辑给客户端。在Python中,简单工厂模式可以通过一个工厂类来创建不同的产品对象。下面是一个简单的示例: ```python class Product: def operation(self): pass class ConcreteProductA(Product): def operation(self): print("Performing operation A.") class ConcreteProductB(Product): def operation(self): print("Performing operation B.") class SimpleFactory: @staticmethod def create_product(product_type): if product_type == "A": return ConcreteProductA() elif product_type == "B": return ConcreteProductB() else: raise ValueError("Invalid product type.") # 使用简单工厂创建产品对象 factory = SimpleFactory() product_a = factory.create_product("A") product_a.operation() product_b = factory.create_product("B") product_b.operation() ``` 在上述示例中,`Product` 是一个抽象产品类,`ConcreteProductA` 和 `ConcreteProductB` 是具体产品类。`SimpleFactory` 是工厂类,通过 `create_product` 方法根据不同的产品类型创建相应的产品对象。 通过简单工厂模式,客户端无需知道具体的产品类,只需要通过工厂类来创建产品对象。这样可以降低客户端与具体产品类的耦合度,并且当需要新增产品时,只需要修改工厂类即可。 希望这个简单的示例能帮助你理解简单工厂模式在Python中的应用。如果有任何进一步的问题,请随时提问!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值