Java简单工厂模式详细解释

作者:回忆酿的甜 时间:2021-09-20 16:12:07 

简单工厂模式概述

1.定义:定义一个工厂类,他可以根据参数的不同返回不同类的实例,被创建的实例通常都具有共同的父类

2.在简单工厂模式中用于被创建实例的方法通常为静态(static)方法,因此简单工厂模式又被成为静态工厂方法(Static Factory Method)

3.需要什么,只需要传入一个正确的参数,就可以获取所需要的对象,而无需知道其实现过程

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

简单工厂模式的结构与实现

结构:

Java简单工厂模式详细解释

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.为了简化简单工厂模式,将抽象产品类和工厂类合并,将静态工厂方法移到抽象产品类中

Java简单工厂模式详细解释

客户端可以调用产品父类的静态工厂方法,根据不同的参数创建不同类型的产品子类对象。

简单工厂模式的优缺点和适用环境

简单工厂模式的优点

(1)工厂类包含必要的逻辑判断,可以决定在什么时候创建哪一个产品的实例。客户端可以免除直接创建产品对象的职责

(2)客户端无需知道所创建具体产品的类名,只需知道参数即可

(3)也可以引入配置文件,在不修改客户端代码的情况下更换和添加新的具体产品类。(这也是我在开始的披萨店里遇到没有的披萨的解决情况)

简单工厂模式的缺点

(1)工厂类集中了所有产品的创建逻辑,职责过重,一旦异常,整个系统将受影响

(2)使用简单工厂模式会增加系统中类的个数(引入新的工厂类),增加系统的复杂度和理解难度

(3)系统扩展困难,一旦增加新产品不得不修改工厂逻辑,在产品类型较多时,可能造成逻辑过于复杂

(4)简单工厂模式使用了static工厂方法,造成工厂角色无法形成基于继承的等级结构。

简单工厂模式的适用环境

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

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

简单案例

题目:

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

UML:

Java简单工厂模式详细解释


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:" + 2 * 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 = 0;//生成图形计数
       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:" + 2 * 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 = 0;//生成图形计数
       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();
           }
       }
   }
}

运行结果:

Java简单工厂模式详细解释

来源:https://www.cnblogs.com/ygsworld/p/10649491.html

标签:Java,工厂模式,详解
0
投稿

猜你喜欢

  • Java详解IO流创建读取与写入操作

    2023-01-23 01:50:28
  • Java从同步容器到并发容器的操作过程

    2021-10-14 05:26:58
  • android开发之Json文件的读写的示例代码

    2021-12-02 11:55:18
  • java实现求两个字符串最长公共子串的方法

    2023-04-03 12:15:05
  • MyBatis-Plus 集成动态多数据源的实现示例

    2023-06-26 17:56:35
  • C#后台创建控件并获取值的方法

    2022-10-20 08:39:46
  • C#利用反射来判断对象是否包含某个属性的实现方法

    2023-02-26 06:57:52
  • IDEA报错:无效的源发行版解决方案

    2022-06-05 08:38:58
  • 详谈jvm--Java中init和clinit的区别

    2022-01-10 10:35:22
  • C#实现过滤sql特殊字符的方法集合

    2022-01-30 23:58:04
  • 浅谈byte和长度为8的boolean数组互相转换

    2023-11-07 00:34:37
  • Android 3D滑动菜单完全解析 Android实现推拉门式的立体特效

    2022-04-19 04:36:01
  • 微信小程序获取手机号,后端JAVA解密流程代码

    2023-11-29 07:57:26
  • C# 解析XML和反序列化的示例

    2023-02-20 01:16:52
  • Java 8中的18个常用日期处理(收藏)

    2023-03-02 02:01:54
  • JAVA演示阿里云图像识别API,印刷文字识别-营业执照识别

    2022-04-21 15:05:22
  • MybatisPlus使用@TableId主键id自增长无效的解决

    2023-01-30 15:59:41
  • SpringBoot @CompentScan excludeFilters配置无效的解决方案

    2022-08-01 09:06:42
  • 剑指Offer之Java算法习题精讲二叉树与N叉树

    2023-04-22 00:20:42
  • SpringBoot文件访问映射如何实现

    2022-07-22 00:36:07
  • asp之家 软件编程 m.aspxhome.com