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时间复杂度、空间复杂度的深入详解
下一篇: Java 类与对象重难点详解