Java简单工厂模式详细解释

 更新时间:2021年11月05日 14:39:29   作者:回忆酿的甜  
本文主要介绍了JAVA简单工厂模式(从现实生活角度理解代码原理)的相关知识。具有很好的参考价值。下面跟着小编一起来看下吧

简单工厂模式概述

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

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

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

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

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

结构:

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

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

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

简单工厂模式的优点

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

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

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

简单工厂模式的缺点

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

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

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

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

简单工厂模式的适用环境

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

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

简单案例

题目:

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

UML:

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中的LinkedHashMap及LRU缓存机制详解

    Java中的LinkedHashMap及LRU缓存机制详解

    这篇文章主要介绍了Java中的LinkedHashMap及LRU缓存机制详解,LinkedHashMap继承自HashMap,它的多种操作都是建立在HashMap操作的基础上的,同HashMap不同的是,LinkedHashMap维护了一个Entry的双向链表,保证了插入的Entry中的顺序,需要的朋友可以参考下
    2023-09-09
  • Java使用elasticsearch基础API使用案例讲解

    Java使用elasticsearch基础API使用案例讲解

    这篇文章主要介绍了Java使用elasticsearch基础API使用案例讲解,本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下
    2021-08-08
  • SpringBoot整合Kotlin构建Web服务的方法示例

    SpringBoot整合Kotlin构建Web服务的方法示例

    这篇文章主要介绍了SpringBoot整合Kotlin构建Web服务的方法示例,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2019-02-02
  • springboot省去配置Tomcat的步骤问题

    springboot省去配置Tomcat的步骤问题

    这篇文章主要介绍了springboot省去配置Tomcat的步骤问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-06-06
  • springboot 启动项目打印接口列表的实现

    springboot 启动项目打印接口列表的实现

    这篇文章主要介绍了springboot 启动项目打印接口列表的实现方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-09-09
  • Java 中Object的wait() notify() notifyAll()方法使用

    Java 中Object的wait() notify() notifyAll()方法使用

    这篇文章主要介绍了Java 中Object的wait() notify() notifyAll()方法使用的相关资料,需要的朋友可以参考下
    2017-05-05
  • mvn compile报错“程序包com.XXX不存在”

    mvn compile报错“程序包com.XXX不存在”

    本文主要介绍了mvn compile报错“程序包com.XXX不存在”,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-01-01
  • SpringCloud-Hystrix实现原理总结

    SpringCloud-Hystrix实现原理总结

    通过hystrix可以解决雪崩效应问题,它提供了资源隔离、降级机制、融断、缓存等功能。接下来通过本文给大家分享SpringCloud-Hystrix实现原理,感兴趣的朋友一起看看吧
    2021-05-05
  • Java使用路径通配符加载Resource与profiles配置使用详解

    Java使用路径通配符加载Resource与profiles配置使用详解

    这篇文章主要介绍了Java使用路径通配符加载Resource与profiles配置使用详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-06-06
  • Maven依赖冲突原因以及解决方法

    Maven依赖冲突原因以及解决方法

    依赖冲突是指项目依赖的某一个 jar 包,有多个不同的版本,因而造成类包版本冲突依赖冲突很经常是类包之间的间接依赖引起的,本文将给大家介绍Maven依赖冲突原因以及解决方法,需要的朋友可以参考下
    2023-12-12

最新评论