设计模式之工厂模式(Factory)

任何可以产生对象的方法或类,都可以称为工厂。

下面的代码定义了Car这种交通工具:

java 复制代码
public class Car {
    public void go() {
        System.out.println("Car go wuwuwuwuw....");
    }
}

然后在main函数里面想要调用调用Car的go方法,就需要new一个car对象,然后调用

java 复制代码
public class Main {
    public static void main(String[] args) {
        Car m = new Car();
        m.go();
    }
}

如果又来了一个飞机,你想开飞机,又得在main函数里面,new一个Plane

java 复制代码
public class Plane {
    public void go() {
        System.out.println("plane flying shushua....");
    }
}
java 复制代码
public class Main {
    public static void main(String[] args) {
        // Car m = new Car();
        Plane m = new Plane();
        m.go();
    }
}

main函数的逻辑会改来改去

可以引入接口,简单多态的应用,car和plane都去实现Moveable这个接口

java 复制代码
public interface Moveable {
    void go();
}
java 复制代码
public class Car implements  Moveable {
    public void go() {
        System.out.println("Car go wuwuwuwuw....");
    }
}
java 复制代码
public class Plane implements Moveable {
    public void go() {
        System.out.println("plane flying shushua....");
    }
}
java 复制代码
public class Main {
    public static void main(String[] args) {
        Moveable m = new Car(); // 简单多态应用
        m.go();
    }
}

通过实现Moveable接口,做到了可以任意定制各种交通工具,只需要实现Moveable接口就行

1.简单工厂 工厂方法(Factory Method) --> 每种产品都对应一个工厂

创建一个工厂类,里面生产Car,Plane和Broom,可扩展性不好,有新的交通工具都得加,要定制的话,

所有的代码都写到了一个类里面

java 复制代码
/**
 * 简单工厂的可扩展性不好
 */
public class SimpleVehicleFactory {
    public Car createCar() {
        //before processing 可以加一些前置操作
        return new Car();
    }

    public Broom createBroom() {
        return new Broom();
    }

    // Plane...
}

可以给Car,Plane分别创建工厂,每个工厂里面可以做任意的定制,代码隔离开了 --> 通过xxxFactory做到了任意定制生产过程

java 复制代码
public class CarFactory {
    public Moveable create() {
        System.out.println("a car created!");
        return new Car();
    }
}
public static void main(String[] args) {
    Moveable m = new CarFactory().create();
    m.go();
}

2.静态工厂

单例也是一种工厂,也被人称为静态工厂。

4.抽象工厂

如何任意扩展产品族?

java 复制代码
public class Car{

    public void go() {
        System.out.println("Car go wuwuwuwuw....");
    }
}
public class AK47 {
    public void shoot() {
        System.out.println("tututututu....");
    }
}
public class Bread {
    public void printName() {
        System.out.println("wdm");
    }
}

有个人开着Car,拿着AK47,tututu,还吃着面包,客户端代码(使用这些类的代码),可能会像下面这样写,但是

如果来了一个人是魔法世界的人,骑得是扫帚,武器是魔法棒,吃的是蘑菇,你的客户端代码就又得重新写

Car,AK47,面包,是一个产品族

扫帚,魔法棒,蘑菇又是一个产品族

有没有一种方法,可以任意选择产品族,客户端代码不用改? --> 抽象工厂

java 复制代码
public class Main {
    public static void main(String[] args) {
        Car car = new Car();
        car.go();
        AK47 ak47 = new AK47();
        ak47.shoot();
        Bread bread = new Bread();
        bread.printName();
    }
}

定义一个抽象工厂类: AbastractFactory可以生产一些列的产品,Food Vehicle Weapon

java 复制代码
public abstract class AbastractFactory {
    abstract Food createFood();
    abstract Vehicle createVehicle();
    abstract Weapon createWeapon();
}

定义三个抽象类:

java 复制代码
//交通工具
public abstract class Vehicle { //interface
    abstract void go();
}
//武器
public abstract class Weapon {
    abstract void shoot();
}
//食物
public abstract class Food {
   abstract void printName();
}

Car,AK47,Bread分别实现上面的抽象类

java 复制代码
public class Car extends Vehicle{

    public void go() {
        System.out.println("Car go wuwuwuwuw....");
    }
}
public class AK47 extends Weapon{
    public void shoot() {
        System.out.println("tututututu....");
    }
}
public class Bread extends Food{
    public void printName() {
        System.out.println("wdm");
    }
}

Broom,MagicStick,MushRoom分别实现上面的抽象类

java 复制代码
public class Broom extends Vehicle{
    public void go() {
        System.out.println("Car go wuwuwuwuw....");
    }
}
public class MagicStick extends Weapon{
    public void shoot() {
        System.out.println("diandian....");
    }
}
public class MushRoom extends Food{
    public void printName() {
        System.out.println("dmg");
    }
}

定义具体的ModernFactory:

java 复制代码
public class ModernFactory extends AbastractFactory {
    @Override
    Food createFood() {
        return new Bread();
    }

    @Override
    Vehicle createVehicle() {
        return new Car();
    }

    @Override
    Weapon createWeapon() {
        return new AK47();
    }
}

定义具体的MagicFactory:

java 复制代码
public class MagicFactory extends AbastractFactory {
    @Override
    Food createFood() {
        return new MushRoom();
    }

    @Override
    Vehicle createVehicle() {
        return new Broom();
    }

    @Override
    Weapon createWeapon() {
        return new MagicStick();
    }
}

AbastractFactory可以生产一些列的产品,Food Vehicle Weapon

定义一个ModernFactory,继承自AbastractFactory,现代的工厂可以生产Car,AK47,Bread(分别继承自Vehicle Weapon Food)

定义一个MagicFactory,也继承自AbastractFactory,魔法工厂可以生产Broom,MagicStick,MushRoom(分别继承自Vehicle Weapon Food)

一共有:抽象的工厂,具体的工厂,抽象的产品,具体的产品

在Main方法里面就只需要创建具体的工厂,然后调用方法就行,不用像之前,创建各种不同的对象之后再调用对应的方法:

java 复制代码
public class Main {
    public static void main(String[] args) {
        AbastractFactory f = new ModernFactory(); // 如果是魔法世界的人,只需要该这一行代码就行,new MagicFactory(),非常方便

        Vehicle c = f.createVehicle();
        c.go();
        Weapon w = f.createWeapon();
        w.shoot();
        Food b = f.createFood();
        b.printName();
    }
}

探讨: 这里Vehicle类,用的是抽象类,只有一个抽象方法,是不是用接口也行?就像前面的Moveable一样? --> 形容词用接口,名词用抽象类

工厂方法和抽象工厂比较:

工厂方法方便在产品上进行扩展,有新的产品来了,只需要加新的xxxFactory就行,如果想要加新的族,就比较麻烦

如果是产品一族上进行扩展,抽象工厂就比较方便,只需要加具体的工厂就行(例如加火星工厂),但是要加的产品就比较麻烦,抽象工厂得加方法,具体工厂也得加方法

例如要加衣服这个产品,就需要在抽象工厂里面加creat衣服的方法,后面的具体工厂也得加

工厂方法: 添加产品维度方便

抽象工厂: 产品一族扩展方便

有没有一种方法,加新的产品和扩展一族产品比较方便呢? --> Spring bean 工厂

相关推荐
lzb_kkk2 分钟前
【JavaEE】JUC的常见类
java·开发语言·java-ee
SEEONTIME2 分钟前
python-24-一篇文章彻底掌握Python HTTP库Requests
开发语言·python·http·http库requests
起名字真南21 分钟前
【OJ题解】C++实现字符串大数相乘:无BigInteger库的字符串乘积解决方案
开发语言·c++·leetcode
爬山算法26 分钟前
Maven(28)如何使用Maven进行依赖解析?
java·maven
tyler_download32 分钟前
golang 实现比特币内核:实现基于椭圆曲线的数字签名和验证
开发语言·数据库·golang
小小小~33 分钟前
qt5将程序打包并使用
开发语言·qt
hlsd#33 分钟前
go mod 依赖管理
开发语言·后端·golang
小春学渗透35 分钟前
Day107:代码审计-PHP模型开发篇&MVC层&RCE执行&文件对比法&1day分析&0day验证
开发语言·安全·web安全·php·mvc
杜杜的man37 分钟前
【go从零单排】迭代器(Iterators)
开发语言·算法·golang
亦世凡华、38 分钟前
【启程Golang之旅】从零开始构建可扩展的微服务架构
开发语言·经验分享·后端·golang