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


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

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

    public class Car {
        public void go() {
            System.out.println("Car go wuwuwuwuw....");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

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

    public class Main {
        public static void main(String[] args) {
            Car m = new Car();
            m.go();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

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

    public class Plane {
        public void go() {
            System.out.println("plane flying shushua....");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    public class Main {
        public static void main(String[] args) {
            // Car m = new Car();
            Plane m = new Plane();
            m.go();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    main函数的逻辑会改来改去

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

    public interface Moveable {
        void go();
    }
    
    • 1
    • 2
    • 3
    public class Car implements  Moveable {
        public void go() {
            System.out.println("Car go wuwuwuwuw....");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    public class Plane implements Moveable {
        public void go() {
            System.out.println("plane flying shushua....");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    public class Main {
        public static void main(String[] args) {
            Moveable m = new Car(); // 简单多态应用
            m.go();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

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

    1.简单工厂 工厂方法(Factory Method) --> 每种产品都对应一个工厂
    创建一个工厂类,里面生产Car,Plane和Broom,可扩展性不好,有新的交通工具都得加,要定制的话,
    所有的代码都写到了一个类里面

    /**
     * 简单工厂的可扩展性不好
     */
    public class SimpleVehicleFactory {
        public Car createCar() {
            //before processing 可以加一些前置操作
            return new Car();
        }
    
        public Broom createBroom() {
            return new Broom();
        }
    
        // Plane...
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

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

    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();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

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

    4.抽象工厂
    如何任意扩展产品族?

    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");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    有个人开着Car,拿着AK47,tututu,还吃着面包,客户端代码(使用这些类的代码),可能会像下面这样写,但是
    如果来了一个人是魔法世界的人,骑得是扫帚,武器是魔法棒,吃的是蘑菇,你的客户端代码就又得重新写
    Car,AK47,面包,是一个产品族
    扫帚,魔法棒,蘑菇又是一个产品族
    有没有一种方法,可以任意选择产品族,客户端代码不用改? --> 抽象工厂

    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();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

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

    public abstract class AbastractFactory {
        abstract Food createFood();
        abstract Vehicle createVehicle();
        abstract Weapon createWeapon();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    定义三个抽象类:

    //交通工具
    public abstract class Vehicle { //interface
        abstract void go();
    }
    //武器
    public abstract class Weapon {
        abstract void shoot();
    }
    //食物
    public abstract class Food {
       abstract void printName();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

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

    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");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

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

    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");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    定义具体的ModernFactory:

    public class ModernFactory extends AbastractFactory {
        @Override
        Food createFood() {
            return new Bread();
        }
    
        @Override
        Vehicle createVehicle() {
            return new Car();
        }
    
        @Override
        Weapon createWeapon() {
            return new AK47();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    定义具体的MagicFactory:

    public class MagicFactory extends AbastractFactory {
        @Override
        Food createFood() {
            return new MushRoom();
        }
    
        @Override
        Vehicle createVehicle() {
            return new Broom();
        }
    
        @Override
        Weapon createWeapon() {
            return new MagicStick();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    AbastractFactory可以生产一些列的产品,Food Vehicle Weapon
    定义一个ModernFactory,继承自AbastractFactory,现代的工厂可以生产Car,AK47,Bread(分别继承自Vehicle Weapon Food)
    定义一个MagicFactory,也继承自AbastractFactory,魔法工厂可以生产Broom,MagicStick,MushRoom(分别继承自Vehicle Weapon Food)

    一共有:抽象的工厂,具体的工厂,抽象的产品,具体的产品
    在这里插入图片描述
    在Main方法里面就只需要创建具体的工厂,然后调用方法就行,不用像之前,创建各种不同的对象之后再调用对应的方法:

    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();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

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

    工厂方法和抽象工厂比较:
    工厂方法方便在产品上进行扩展,有新的产品来了,只需要加新的xxxFactory就行,如果想要加新的族,就比较麻烦
    如果是产品一族上进行扩展,抽象工厂就比较方便,只需要加具体的工厂就行(例如加火星工厂),但是要加的产品就比较麻烦,抽象工厂得加方法,具体工厂也得加方法
    例如要加衣服这个产品,就需要在抽象工厂里面加creat衣服的方法,后面的具体工厂也得加

    工厂方法: 添加产品维度方便
    抽象工厂: 产品一族扩展方便

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

  • 相关阅读:
    java 多态
    软考信息安全工程师案列分析
    【Essential C++学习笔记】第四章 基于对象的编程风格
    论文总结-交通预测(未完成)
    DNS域名解析系统
    0909hw
    导出pdf高清
    【华为OD题库-008】座位调整-Java
    LeetCode每日一题——2520. Count the Digits That Divide a Number
    【前端灵魂脚本语言JavaScript⑤】——JS中数组的使用
  • 原文地址:https://blog.csdn.net/u011069294/article/details/134255326