03 Factory工厂模式

简单工厂

没有使用工厂

车类:

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工厂。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值