简单工厂
没有使用工厂
车类:
package org.garen.factory;
/**
* 车
*/
public class Car {
public void go() {
System.out.println("Car go ...");
}
}
飞机类:
package org.garen.factory;
/**
* 飞机
*/
public class Plane {
public void go() {
System.out.println("Plane go ...");
}
}
测试类:
package org.garen.factory;
/**
* 测试类
*/
public class Main {
public static void main(String[] args) {
Car c = new Car();
c.go();
Plane p = new Plane();
p.go();
}
}
运行结果:
Car go …
Plane go …
使用父接口
父接口:
package org.garen.factory;
/**
* 接口,可以移动的
*/
public interface Moveable {
void go();
}
车类:
package org.garen.factory;
/**
* 车
*/
public class Car implements Moveable{
@Override
public void go() {
System.out.println("Car go ...");
}
}
飞机类:
package org.garen.factory;
/**
* 飞机
*/
public class Plane implements Moveable{
@Override
public void go() {
System.out.println("Plane go ...");
}
}
扫把类:
package org.garen.factory;
/**
* 扫把
*/
public class Broom implements Moveable{
@Override
public void go() {
System.out.println("Broom go ...");
}
}
测试类:
package org.garen.factory;
/**
* 测试类
*/
public class Main {
public static void main(String[] args) {
// 开车
Moveable m1 = new Car();
m1.go();
// 开飞机
Moveable m2 = new Plane();
m2.go();
// 骑扫把
Moveable m3 = new Broom();
m3.go();
}
}
简单工厂
简单工厂类:
package org.garen.factory;
/**
* 交通工具的简单工厂
* 简单工厂的可扩展性不好
*/
public class SimpleVehicleFactory {
// 创建汽车对象
public Car createCar() {
// before processing
return new Car();
}
// 创建飞机对象
public Plane createPlane() {
// before processing
return new Plane();
}
// 创建扫把对象
public Broom createBroom() {
// before processing
return new Broom();
}
}
测试类:
package org.garen.factory;
/**
* 测试类
*/
public class Main {
public static void main(String[] args) {
// 交通工具工厂对象
SimpleVehicleFactory simpleVehicleFactory = new SimpleVehicleFactory();
// 开车
Moveable m1 = simpleVehicleFactory.createCar();
m1.go();
// 开飞机
Moveable m2 = simpleVehicleFactory.createPlane();
m2.go();
// 骑扫把
Moveable m3 = simpleVehicleFactory.createBroom();
m3.go();
}
}
运行结果:
Car go …
Plane go …
Broom go …
简单工厂扩展性不好,每次添加一个类,都要修改简单工厂类,添加相应类的工厂方法。
工厂方法
为每一个类提供一个工厂类
package org.garen.factory;
/**
* Car的工厂类
*/
public class CarFactory {
// 创建对象
public Car create() {
System.out.println("a car created!");
return new Car();
}
}
package org.garen.factory;
/**
* Plane工厂
*/
public class PlaneFactory {
// 创建对象
public Plane create() {
System.out.println("a plane created!");
return new Plane();
}
}
package org.garen.factory;
/**
* Broom工厂
*/
public class BroomFactory {
// 创建对象
public Broom create() {
System.out.println("a broom created!");
return new Broom();
}
}
测试类:
package org.garen.factory;
/**
* 测试类
*/
public class Main {
public static void main(String[] args) {
// 开车
Moveable m1 = new CarFactory().create();
m1.go();
// 开飞机
Moveable m2 = new PlaneFactory().create();
m2.go();
// 骑扫把
Moveable m3 = new BroomFactory().create();
m3.go();
}
}
运行结果:
a car created!
Car go …
a plane created!
Plane go …
a broom created!
Broom go …
好处,可以随意扩展。任意定制交通工具,任意定制生产过程。
抽象工厂
一个游戏中的场景:
1、现实世界的一个人,开着车,吃着面包,拿着AK47扫射
2、魔法世界的一个人,骑着扫把,吃着毒蘑菇,拿着魔法棒发射闪电
用java类来描述:
车:
package org.garen.factory.abstractFactory;
public class Car{
public void go() {
System.out.println("Car go ...");
}
}
面包:
package org.garen.factory.abstractFactory;
public class Bread{
public void eat() {
System.out.println("eat bread");
}
}
AK47:
package org.garen.factory.abstractFactory;
public class AK47{
public void shoot() {
System.out.println("tutututu...");
}
}
测试类:
package org.garen.factory.abstractFactory;
public class Main {
public static void main(String[] args) {
Car c = new Car();
c.go();
AK47 ak47 = new AK47();
ak47.shoot();
Bread bread = new Bread();
bread.eat();
}
}
运行结果:
Car go …
tutututu…
eat bread
如果想换成魔法世界测试,要new三个对象,再输出。
我们改造一下代码,增加3个抽象类,然后实体类继承抽象类。
交通工具:
package org.garen.factory.abstractFactory;
public abstract class Vehicle {
abstract void go();
}
食物:
package org.garen.factory.abstractFactory;
public abstract class Food {
abstract void eat();
}
武器:
package org.garen.factory.abstractFactory;
public abstract class Weapon {
abstract void shoot();
}
实体类:
车:
package org.garen.factory.abstractFactory;
public class Car extends Vehicle{
public void go() {
System.out.println("Car go ...");
}
}
扫把:
package org.garen.factory.abstractFactory;
public class Broom extends Vehicle{
public void go() {
System.out.println("Broom go ...");
}
}
面包:
package org.garen.factory.abstractFactory;
public class Bread extends Food{
public void eat() {
System.out.println("eat bread");
}
}
毒蘑菇:
package org.garen.factory.abstractFactory;
public class MushRoom extends Food{
public void eat() {
System.out.println("eat dmg");
}
}
AK47:
package org.garen.factory.abstractFactory;
public class AK47 extends Weapon{
public void shoot() {
System.out.println("tutututu...");
}
}
魔法棒:
package org.garen.factory.abstractFactory;
public class MagicStick extends Weapon {
public void shoot() {
System.out.println("diandian...");
}
}
抽象工厂:
一系列产品族
package org.garen.factory.abstractFactory;
public abstract class AbstractFactory {
abstract Food createFood();
abstract Vehicle createVehicle();
abstract Weapon createWeapon();
}
实体工厂 - 现实世界:
package org.garen.factory.abstractFactory;
public class ModernFactory extends AbstractFactory{
@Override
Food createFood() {
return new Bread();
}
@Override
Vehicle createVehicle() {
return new Car();
}
@Override
Weapon createWeapon() {
return new AK47();
}
}
实体工厂 - 魔法世界:
package org.garen.factory.abstractFactory;
public class ModernFactory extends AbstractFactory{
@Override
Food createFood() {
return new Bread();
}
@Override
Vehicle createVehicle() {
return new Car();
}
@Override
Weapon createWeapon() {
return new AK47();
}
}
测试类1:
package org.garen.factory.abstractFactory;
public class Main {
public static void main(String[] args) {
AbstractFactory factory = new ModernFactory();
factory.createVehicle().go();
factory.createFood().eat();
factory.createWeapon().shoot();
}
}
运行结果:
Car go …
eat bread
tutututu…
测试类2:
package org.garen.factory.abstractFactory;
public class Main {
public static void main(String[] args) {
AbstractFactory factory = new MagicFactory();
factory.createVehicle().go();
factory.createFood().eat();
factory.createWeapon().shoot();
}
}
Broom go …
eat dmg
diandian…
使用抽象工厂,产品族可以随意扩展了。
选择抽象类还是接口?
其实都可以。但是从语义的角度来讲,Food是人类认知中存在的一类东西,只不过比具体的某个面包要抽象一点,所以用抽象类比较合适;而可移动的,这种具有某种能力的,用接口就比较合适。
简单说,名词用抽象类比较合适,形容词用接口比较合适。
工厂的扩展
产品
车、AK47、面包、扫把、魔法棒、毒蘑菇
扩展:帽子、衣服、宠物。。。
产品一族
现实世界:车、AK47、面包
魔法世界:扫把、魔法棒、毒蘑菇
扩展:
火星世界、海底世界、未来世界。。。
可扩展性
设计模式中,关于工厂模式,只有工厂方法、抽象工厂可以称之为设计模式。下面比较一下两者的可扩展性。
工厂方法:
在产品单一这个维度上,容易扩展。在产品一族这个维度上,不容易扩展。
抽象工厂:
在产品一族这个维度上,容易扩展。在产品单一这个维度上,不容易扩展。
两种模式都有其局限性。更好的解决方案:spring bean工厂。