简单工厂:
(emmm中文写名好像是有点不伦不类的)
产品类:
abstract class 方便面{
private String 口味;
abstract public void 查看信息();
public 方便面(String 口味) {
this.口味 = 口味;
}
public String get口味() {
return 口味;
}
}
class 泡椒牛肉面 extends 方便面{
public 泡椒牛肉面() {
super("泡椒牛肉");
}
@Override
public void 查看信息() {
System.out.println("1号产品:"+get口味());
}
}
class 麻辣牛肉面 extends 方便面{
public 麻辣牛肉面() {
super("麻辣牛肉");
}
@Override
public void 查看信息() {
System.out.println("1号产品:"+get口味());
}
}
简单工厂类
class 方便面简单工厂{
public 方便面 生产方便面(String name){
switch (name){
case "泡椒牛肉面":
return new 泡椒牛肉面();
case "麻辣牛肉面":
return new 麻辣牛肉面();
default:
throw new RuntimeException("没有这种面");
}
}
}
测试方法:
@Test
public void test(){
方便面简单工厂 f = new 方便面简单工厂();
try {
方便面 ff = f.生产方便面("泡脚牛肉面");
}catch (RuntimeException e){
e.printStackTrace();
}
方便面 ff = f.生产方便面("泡椒牛肉面");
ff.查看信息();
ff = f.生产方便面("麻辣牛肉面");
ff.查看信息();
}
简单工厂模式,就像它的名字一样,简单,但是如果增添了其他类,就得修改工厂的代码,这不符合开放封闭原则。不过由于简单用得还是挺多的。
工厂方法:
这种模式可以形象的被称为工厂的工厂,一个工厂只负责一个产品的生产,如果另外还有产品需要生产,则创建新的工厂与产品联系起来。
这样就解决之前的问题啦
如果有新的产品出现,只需要再写个工厂就行了。
之前的产品类不用改动,工厂类写成:
interface I方便面工厂{
方便面 生产方便面();
}
class 泡椒牛肉面工厂 implements I方便面工厂{
@Override
public 方便面 生产方便面() {
return new 泡椒牛肉面();
}
}
class 麻辣牛肉面工厂 implements I方便面工厂{
@Override
public 方便面 生产方便面() {
return new 麻辣牛肉面();
}
}
测试代码:
@Test
public void test(){
I方便面工厂 ifc = new 泡椒牛肉面工厂();
方便面 f = ifc.生产方便面();
f.查看信息();
ifc = new 麻辣牛肉面工厂();
f = ifc.生产方便面();
f.查看信息();
}
抽象工厂
抽象工厂是工厂方法的升级版,也就说多了多个产品族群,每一个工厂都不止生产一个产品而是生产一堆产品(或许叫产品群工厂方法更合适?)
抽象方便面类:
abstract class 火腿肠方便面{
private String 口味;
private final String 配菜 = "火腿肠";
abstract public void 查看信息();
public 火腿肠方便面(String 口味) {
this.口味 = 口味;
}
public String get口味() {
return 口味+配菜;
}
}
abstract class 鸭蛋方便面{
private String 口味;
private final String 配菜 = "鸭蛋";
abstract public void 查看信息();
public 鸭蛋方便面(String 口味) {
this.口味 = 口味;
}
public String get口味() {
return 口味+配菜;
}
}
具体方便面类
class 火腿肠泡椒牛肉面 extends 火腿肠方便面{
public 火腿肠泡椒牛肉面() {
super("泡椒牛肉");
}
@Override
public void 查看信息() {
System.out.println("1号产品:"+get口味());
}
}
class 火腿肠麻辣牛肉面 extends 火腿肠方便面{
public 火腿肠麻辣牛肉面() {
super("麻辣牛肉");
}
@Override
public void 查看信息() {
System.out.println("2号产品:"+get口味());
}
}
class 鸭蛋泡椒牛肉面 extends 鸭蛋方便面{
public 鸭蛋泡椒牛肉面() {
super("泡椒牛肉");
}
@Override
public void 查看信息() {
System.out.println("3号产品:"+get口味());
}
}
class 鸭蛋麻辣牛肉面 extends 鸭蛋方便面{
public 鸭蛋麻辣牛肉面() {
super("麻辣牛肉");
}
@Override
public void 查看信息() {
System.out.println("4号产品:"+get口味());
}
}
方便面工厂
interface I方便面工厂{
火腿肠方便面 生产方便面加火腿肠();
鸭蛋方便面 生产方便面加鸭蛋();
}
class 泡椒牛肉面工厂 implements I方便面工厂{
@Override
public 火腿肠方便面 生产方便面加火腿肠() {
return new 火腿肠泡椒牛肉面();
}
@Override
public 鸭蛋方便面 生产方便面加鸭蛋() {
return new 鸭蛋泡椒牛肉面();
}
}
class 麻辣牛肉面工厂 implements I方便面工厂{
@Override
public 火腿肠方便面 生产方便面加火腿肠() {
return new 火腿肠麻辣牛肉面();
}
@Override
public 鸭蛋方便面 生产方便面加鸭蛋() {
return new 鸭蛋麻辣牛肉面();
}
}
生产方便面工厂的工厂。
class 超级方便面工厂{
private 超级方便面工厂(){}
public static I方便面工厂 获取方便面工厂(String fac) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
Class clazz = Class.forName(fac);
return (I方便面工厂) clazz.getDeclaredConstructor().newInstance();
}
}
测试代码:
public class Factoy {
@Test
public void test(){
try {
I方便面工厂 c = 超级方便面工厂.获取方便面工厂("泡椒牛肉面工厂");
c.生产方便面加火腿肠().查看信息();
c.生产方便面加鸭蛋().查看信息();
c = 超级方便面工厂.获取方便面工厂("麻辣牛肉面工厂");
c.生产方便面加火腿肠().查看信息();
c.生产方便面加鸭蛋().查看信息();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
}
}
}
三种模式的比较:
如果业务相对简单,拓展性要求较低(如果使用反射也算是不违背开放封闭原则),那就可以使用简单工厂。代码量少
如果需要扩展且产品只有一类,则使用工厂方法。代码量较多
如果需要扩展且产品很很多类,则可使用抽象工厂。代码量贼多,极其复杂的业务才需要。