- 任何可以产生对象的方法或类,都可以称为工厂
- 单例也是一种工厂
- 为什么有了new以后,还要有工厂?
1、灵活控制生产过程
2、权限、修饰、日志……
接口模式
package cn.xhl.interfacemodel;
public interface IFruit {
public void plant();
public void harvest();
public void grow();
}
package cn.xhl.interfacemodel;
public class Apple implements IFruit {
int treeAge = 5;
public void plant() {
// TODO Auto-generated method stub
log("苹果种植ֲ********");
}
public void harvest() {
// TODO Auto-generated method stub
log("苹果收获******");
}
public void grow() {
// TODO Auto-generated method stub
log("苹果增长****");
}
public static void log(String msg) {
System.out.println(msg);
}
}
package cn.xhl.interfacemodel;
public class Grape implements IFruit {
boolean seedful=false;
public void plant() {
// TODO Auto-generated method stub
log("葡萄种植ֲ********");
}
public void harvest() {
// TODO Auto-generated method stub
log("葡萄收获******");
}
public void grow() {
// TODO Auto-generated method stub
log("葡萄生长****");
}
public static void log(String msg) {
System.out.println(msg);
}
}
package cn.xhl.interfacemodel;
public class Strawberry implements IFruit {
public void plant() {
// TODO Auto-generated method stub
log("草莓种植********");
}
public void harvest() {
// TODO Auto-generated method stub
log("草莓收获******");
}
public void grow() {
// TODO Auto-generated method stub
log("草莓生长****");
}
public static void log(String msg) {
System.out.println(msg);
}
}
package cn.xhl.interfacemodel;
public class Client1 {
public static void main(String[] args) {
// TODO Auto-generated method stub
IFruit[] fruits = {new Grape(),new Strawberry(),new Apple()};
for(IFruit fruit : fruits) {
fruit .plant();
fruit.grow();
fruit .harvest();
}
}
}
简单工厂模式
一般情况下我们可以用一个FruitFactory去创建不同的Fruit
public class FruitFactory{
public IFruit creatApple(){
//进行一些前置操作,例如设置权限、进行修饰、打印日志……
return new Apple();
}
public IFruit creatGrape(){return new Grape();}
public IFruit creatStrawberry(){return new Strawberry();}
}
但是这不符合开闭原则,每次新增一个品种的IFruit都需要对Factory进行改动。
我们可以对简单工厂模式进行改进,让它符合开闭原则。
package cn.xhl.simpleFactory;
public class FruitGardent {
public static IFruit factory(String which) throws InstantiationException, IllegalAccessException, ClassNotFoundException {
IFruit fruit = null;
String pn = FruitGardent.class.getPackage().getName();
StringBuilder sb = new StringBuilder();
sb.append(pn);
sb.append(".");
sb.append(Character.toUpperCase(which.charAt(0)));
sb.append(which.substring(1).toLowerCase());
fruit = (IFruit) Class.forName(sb.toString()).newInstance();
return fruit;
}
}
package cn.xhl.simpleFactory;
public class Client1 {
public static void main(String[] args) {
// TODO Auto-generated method stub
String[] strs = {"grape","apple","strawberry"};
for(String str : strs) {
IFruit fruit;
try {
fruit = FruitGardent.factory(str);
fruit.plant();
fruit.harvest();
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
但是这有产生了新的问题,如果对不同的产品对应需要给到不同的权限,也就是在new之前需要进行一些前置操作,且不同的IFruit操作不一样,这样就需要在前面加上判断的语句,判断这是什么IFruit,再进行一些权限设置,最后再创建对象,但这又不符合开闭原则了。
于是我们可以对每一个产品,也就是每一个IFruit都用一个Factory,这样就引出了工厂方法模式。
工厂方法模式
工厂方法方便产品的扩展
package factory1;
public class Client1 {
public static void main(String[] args) {
// TODO Auto-generated method stub
String[] strs = {"ConcreateCreator1","ConcreateCreator2"};
for (String str : strs) {
try {
Creator creator = CreatFactory.factory(str);
creator.factory().show();
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
package factory1;
public class CreatFactory {
public static Creator factory(String which) throws InstantiationException, IllegalAccessException, ClassNotFoundException {
Creator creator = null;
StringBuilder sb = new StringBuilder();
sb.append(CreatFactory.class.getPackageName());
sb.append(".");
sb.append(which);
creator = (Creator) Class.forName(sb.toString()).newInstance();
return creator;
}
}
package factory1;
public interface Creator {
public Product factory();
}
package factory1;
public class ConcreateCreator1 implements Creator {
@Override
public Product factory() {
// 可以进行一些前置操作,例如设置权限、进行修饰、打印日志……
return new ConcreateProduct1();
}
}
package factory1;
public class ConcreateCreator2 implements Creator {
@Override
public Product factory() {
// TODO Auto-generated method stub
return new ConcreateProduct2();
}
}
package factory1;
public interface Product {
public void show();
}
package factory1;
public class ConcreateProduct1 implements Product {
@Override
public void show() {
// TODO Auto-generated method stub
System.out.println("This is Product1111 show");
}
}
package factory1;
public class ConcreateProduct2 implements Product {
@Override
public void show() {
// TODO Auto-generated method stub
System.out.println("This is Product2222 show");
}
}
抽象工厂模式
抽象工厂在于产品族的扩展
工厂方法是只有一种产品族的抽象工厂
package abstractFactory;
public interface Shape {
public void draw();
}
package abstractFactory;
public class Circle implements Shape {
@Override
public void draw() {
// TODO Auto-generated method stub
System.out.println("画一个圆");
}
}
package abstractFactory;
public class Rectangle implements Shape {
@Override
public void draw() {
// TODO Auto-generated method stub
System.out.println("画一个矩形");
}
}
package abstractFactory;
public class Square implements Shape {
@Override
public void draw() {
// TODO Auto-generated method stub
System.out.println("画一个正方形");
}
}
package abstractFactory;
public interface Color {
public void draw();
}
package abstractFactory;
public class Bule implements Color {
@Override
public void draw() {
// TODO Auto-generated method stub
System.out.println("涂蓝色");
}
}
package abstractFactory;
public class Green implements Color {
@Override
public void draw() {
// TODO Auto-generated method stub
System.out.println("涂绿色");
}
}
package abstractFactory;
public class Red implements Color {
@Override
public void draw() {
// TODO Auto-generated method stub
System.out.println("涂红色");
}
}
package abstractFactory;
public class ShapeFactory implements AbstractFactory {
@Override
public Color getColor(String color) {
// TODO Auto-generated method stub
return null;
}
@Override
public Shape getShape(String shape) {
// TODO Auto-generated method stub
Shape sh=null;
String pn = ShapeFactory.class.getPackageName();
StringBuilder sb = new StringBuilder();
sb.append(pn);
sb.append(".");
sb.append(Character.toUpperCase(shape.charAt(0)));
sb.append(shape.substring(1).toLowerCase());
try {
sh=(Shape) Class.forName(sb.toString()).newInstance();
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return sh;
}
}
package abstractFactory;
public class ColorFactory implements AbstractFactory {
public Color getColor(String color) {
Color cl=null;
String pn = ColorFactory.class.getPackageName();
StringBuilder sb = new StringBuilder();
sb.append(pn);
sb.append(".");
sb.append(Character.toUpperCase(color.charAt(0)));
sb.append(color.substring(1).toLowerCase());
try {
cl=(Color) Class.forName(sb.toString()).newInstance();
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return cl;
}
@Override
public Shape getShape(String shape) {
// TODO Auto-generated method stub
return null;
}
}
package abstractFactory;
public interface AbstractFactory {
public Shape getShape(String shape);
public Color getColor(String color);
}
package abstractFactory;
public class FactoryProducer {
public static AbstractFactory getFactory(String which) {
AbstractFactory af=null;
String pn = FactoryProducer.class.getPackageName();
StringBuilder sb = new StringBuilder();
sb.append(pn);
sb.append(".");
sb.append(which);
try {
af = (AbstractFactory) Class.forName(sb.toString()).newInstance();
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return af;
}
}
package abstractFactory;
public class Client {
public static void main(String[] args) {
// TODO Auto-generated method stub
String[] shapes = {"circle","square","RECTANGLE"};
String[] colors = {"bule","red","GREEN"};
String[] factory = {"ShapeFactory","ColorFactory"};
for(String f : factory) {
AbstractFactory af = FactoryProducer.getFactory(f);
for(String c : colors) {
if(af.getColor(c)!=null) {
af.getColor(c).draw();
}
}
for(String s : shapes) {
if(af.getShape(s)!=null) {
af.getShape(s).draw();
}
}
}
}
}
总结
- 简单工厂:把对象的创建放到一个工厂类中,通过参数来创建不同的对象。这个缺点是每添一个对象,就需要对简单工厂进行修改(尽管不是删代码,仅仅是添一个switch case,但仍然违背了“开闭”原则。
- 工厂方法:每种产品由一种工厂来创建,是将创建对象的逻辑与任务交给工厂类,如果增加一个具体的产品,不用像简单工厂方法那样修改里面的代码,可以直接扩展,遵循 “开闭”原则
- 抽象工厂:是工厂方法模式的进一步推广化和抽象化,扩充和升级,在抽象工厂模式中抽象产品可能是一个或者多个,从而构成了一个或多个产品族,只有一个产品族的抽象工厂模式就是工厂方法模式,一般是大项目用。