工厂模式专门负责将大量有共同接口的类实例化。工厂模式可以动态决定将哪一个类实例化,不必事先知道每次要实例化哪个类。
工厂模式的三个状态
简单工厂模式:
例子:以农庄中的水果为例,Strawberry、Apple、Grape类都实现Fruit接口并且有独自的类属性和辅助方法,它们通过FruitGardener类中的工厂方法动态对外提供对象创建服务。
/**
* @author : Jack Wu
* @Title: Fruit
* @ProjectName test_project
* @Description: Fruit 接口
* @date 2019/2/23 20:40
*/
public interface Fruit {
void plant();
void grow();
void harvest();
}
/**
* @author : Jack Wu
* @Title: Apple
* @ProjectName test_project
* @Description: Fruit接口的实现类Apple,该类是简单工厂中的其中一个类
* @date 2019/2/23 20:42
*/
public class Apple implements Fruit {
//苹果类实现Fruit接口,并有自己的属性和辅助方法
private int treeAge;
@Override
public void plant() {
System.out.println("Apple has bean planted!");
}
@Override
public void grow() {
System.out.println("Apple is growing……");
}
@Override
public void harvest() {
System.out.println("Apple has bean harvested!");
}
public int getTreeAge() {
return treeAge;
}
public void setTreeAge(int treeAge) {
this.treeAge = treeAge;
}
public static void showAge(int treeAge){
System.out.println("age :"+treeAge);
}
}
**
* @author : Jack Wu
* @Title: Grape
* @ProjectName test_project
* @Description: Grade 类实现Fruit接口
* @date 2019/2/23 20:50
*/
public class Grape implements Fruit {
//Grape类添加属性seedless
private boolean seedless;
@Override
public void plant() {
System.out.println("Grape has been planted!");
}
@Override
public void grow() {
System.out.println("Grape is growing……");
}
@Override
public void harvest() {
System.out.println("Grape has been harvest!");
}
public boolean isSeedless() {
return seedless;
}
public void setSeedless(boolean seedless) {
this.seedless = seedless;
}
//Grape类增加辅助方法showSeedLess
public static void showSeedLess(boolean seedless){
System.out.println("seedless:"+seedless);
}
}
/**
* @author : Jack Wu
* @Title: Strawberry
* @ProjectName test_project
* @Description: Strawberry实现Fruit接口
* @date 2019/2/23 20:55
*/
public class Strawberry implements Fruit {
@Override
public void plant() {
System.out.println("Strawberry has been planted!");
}
@Override
public void grow() {
System.out.println("Strawberry is growing……");
}
@Override
public void harvest() {
System.out.println("Strawberry has been harvested!");
}
}
/**
* @author : Jack Wu
* @Title: FruitGardener
* @ProjectName test_project
* @Description: TODO
* @date 2019/2/23 21:00
*/
public class FruitGardener {
//对外提供动态创建对象的静态工厂方法
public static Fruit fruitFactory(String msg) throws FruitNotFoundException{
if(msg.equalsIgnoreCase("apple")){
return new Apple();
}else if (msg.equalsIgnoreCase("strawberry")){
return new Strawberry();
}else if(msg.equalsIgnoreCase("grape")){
return new Grape();
}else {
throw new FruitNotFoundException("fruit not fount, sorry");
}
}
}
通过该例子可以看出,简单工厂中、子类继承抽象类或实现接口,工厂类提供静态工厂方法来动态创建对象。简单工厂模式是其他设计模式的基础,如单例模式、多例模式、备忘录模式,MVC模式中的多视图控制等都用到简单工厂模式。
缺点:简单工厂模式使用静态方法作为工厂方法,因而工厂类的方法无法被继承扩展,只是在有限的程度上支持“开—闭原则”。
工厂方法模式:
在简单工厂的基础上,定义一个创建产品对象的工厂接口,将实际创建工作推迟到子类中
/**
* @author : Jack Wu
* @Title: FruitGardener
* @ProjectName test_project
* @Description: TODO
* @date 2019/2/23 21:47
*/
public interface FruitGardener {
Fruit fruitFactory();
}
/**
* @author : Jack Wu
* @Title: AppleFacory
* @ProjectName test_project
* @Description: TODO
* @date 2019/2/23 21:48
*/
public class AppleFacory implements FruitGardener {
@Override
public Fruit fruitFactory() {
return new Apple();
}
}
/**
* @author : Jack Wu
* @Title: GrapeFactory
* @ProjectName test_project
* @Description: TODO
* @date 2019/2/23 21:48
*/
public class GrapeFactory implements FruitGardener {
@Override
public Fruit fruitFactory() {
return new Grape();
}
}
/**
* @author : Jack Wu
* @Title: Strawberry
* @ProjectName test_project
* @Description: Strawberry实现Fruit接口
* @date 2019/2/23 20:55
*/
public class Strawberry implements Fruit {
@Override
public void plant() {
System.out.println("Strawberry has been planted!");
}
@Override
public void grow() {
System.out.println("Strawberry is growing……");
}
@Override
public void harvest() {
System.out.println("Strawberry has been harvested!");
}
}
抽象工厂模式:
在工厂方法模式上,可定制和组合工厂返回的对象,抽象工厂模式能更好的扩展
如下例子,Bus和Bike实现了交通工具的Car接口,Milk和Egg实现BreakFast接口,而Student和Adult通过实现ThingsToDo工厂接口,来获得不同的对象。更大程度上支持“开—闭原则。
/**
* @author : Jack Wu
* @Title: Car
* @ProjectName test_project
* @Description: TODO
* @date 2019/2/23 22:45
*/
public interface Car {
void goToWork();
}
/**
* @author : Jack Wu
* @Title: BreakFast
* @ProjectName test_project
* @Description:BreakFast
* @date 2019/2/23 22:46
*/
public interface BreakFast {
void eatFood();
}
/**
* @author : Jack Wu
* @Title: Bike
* @ProjectName test_project
* @Description: TODO
* @date 2019/2/23 22:47
*/
public class Bike implements Car{
@Override
public void goToWork() {
System.out.println("go to school by bike");
}
}
/**
* @author : Jack Wu
* @Title: Bus
* @ProjectName test_project
* @Description: TODO
* @date 2019/2/23 22:48
*/
public class Bus implements Car {
@Override
public void goToWork() {
System.out.println("go to work by Bus");
}
}
/**
* @author : Jack Wu
* @Title: Egg
* @ProjectName test_project
* @Description: TODO
* @date 2019/2/23 23:06
*/
public class Egg implements BreakFast {
@Override
public void eatFood() {
System.out.println("adult eat egg");
}
}
/**
* @author : Jack Wu
* @Title: Milk
* @ProjectName test_project
* @Description: TODO
* @date 2019/2/23 22:58
*/
public class Milk implements BreakFast{
@Override
public void eatFood() {
System.out.println("student eat milk");
}
}
/**
* @author : Jack Wu
* @Title: Student
* @ProjectName test_project
* @Description: TODO
* @date 2019/2/23 23:02
*/
public class Student implements ThingsToDo {
@Override
public Car doTask() {
return new Bike();
}
@Override
public BreakFast eatBreakfast() {
return new Milk();
}
}
/**
* @author : Jack Wu
* @Title: Adult
* @ProjectName test_project
* @Description: TODO
* @date 2019/2/23 23:04
*/
public class Adult implements ThingsToDo {
@Override
public Car doTask() {
return new Bus();
}
@Override
public BreakFast eatBreakfast() {
return new Egg();
}
}
通过上面例子可以看出,抽象工厂模式其实是在工厂方法模式的基础上对工厂方法实现类的进一步抽象,通过继承抽象类或实现接口,能更好的扩展工厂类返回的对象。最大程度上支持“开—闭原则。