设计模式 简单工厂到抽象工厂

二次信任 提交于 2020-10-03 07:08:00

任何可以产生对象或者方法的类都可以称为工厂,一个方法返回值是一个对象就可以称之为工厂。

单例也是工厂之一,称之为静态工厂,不可以死扣概念!

设计这种东西就是审美没有一种完全死的标准,只不过很多时候你的设计比较丑。

为什么有了new之后,还要有工厂?

是要灵活生产过程,比如有谁有权生产谁无权生产。。。

 

public class Car {

    public void go() {
        System.out.println("Car go wuwuwuwuw....");
    }
}
public class Demo {

    public static void main(String[] args) {
        Car car = new Car();
        car.go();
    }
}

我们的Demo是一个驾驶员,现在对车扩展,比如说能灵活指定交通工具,今天开车,我明天想开飞机。

我们添加一个飞机类

public class Plane {
    public void go() {
        System.out.println("plane flying shushua....");
    }
}

我们换飞机的时候我们可以

然后我们把new Car换成 new Plane,下回我们换个自行车,火车,轮船,需要不停的修改mian方法,这样扩展性很差。

这个时候我们可以建一个接口

public interface Moveable {
    void go();
}

然后所有交通工具实现这个接口

public class Car implements  Moveable {
    public void go() {
        System.out.println("Car go wuwuwuwuw....");
    }
}

public class Plane implements Moveable {
    public void go() {
        System.out.println("plane flying shushua....");
    }
}

public class Broom implements Moveable{
    public void go() {
        System.out.println("broom flying chuachuachua .....");
    }
}

然后我们的main方法就可以改成

public class Demo {
    public static void main(String[] args) {
        Moveable moveable = new Plane();
        moveable.go();
    }
}

需要什么交通工具把new Plane()换掉就可以了;

第一阶段我们可以定制任意的交通工具了

 

第二阶段我们要定制交通工具的生产过程

这个时候我们就不new了

比如说我们new一个交通那个工具的时候我们要控制权限,我们可以写一些代码来控制。因为车,飞机,扫帚的权限是不一样的依然会导致逻辑来回来去的变。

我们可以把产生对象的过程不用new,我交给工厂方法。你是车我就来一个生产工厂,第一种叫简单工厂。

生产对象之前我们可以写一些自己的控制逻辑,这种方式简单,但是可扩展性并不好。

当我们添加一种交通工具的时候我们还要加新的方法,除此之外控制逻辑也要写死。

public class VehicleFactory {

    public Car createCar(){
        //before processiong
        return new Car();
    }

    public Broom createBroom(){
        //before processiong
        return new Broom();
    }

    public Plane createPlane(){
        //before processiong
        return new Plane();
    }

}

 

我们还可以针对每一种产品做一个工厂,针对Car来说我做一个Car的工厂

public class CarFactory {
    public Car createCar(){
        System.out.println("a car created!");
        return new Car();
    }
}
public class Demo {
    public static void main(String[] args) {
        Car car = new CarFactory().createCar();
    }
}

如果我们用Plane就创建一个PlaneFactory,BroomFactory

当我们添加一种新的交通工具的时候我们要把工厂做出来,接下来把new CarFactory().createCar();代码改一下

这样我们在交通工具的维度就可以随意扩展了。可以任意定制交通工具,可以定制生产过程。

想定制任意交通工具的话继承或实现Moveable,定义生产过程呢就是用不同的XXFactory().create()。

 

第三阶段要求 任意定制产品的一族

我们的司机现在不止开车,司机有武器,还可以吃东西。

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

然后我们的实现,可以吃,拿武器,吃东西。

public class Demo {
    public static void main(String[] args) {
        Car car = new Car();
        car.go();
        AK47 ak47 = new AK47();
        ak47.shoot();
        Bread bread = new Bread();
        bread.printName();
    }
}

现在有一个人是魔法世界的,骑扫帚,武器法杖,吃蘑菇

public class Broom {
    public void go() {
        System.out.println("Car go wuwuwuwuw....");
    }
}
public class MagicStick {
    public void shoot() {
        System.out.println("diandian....");
    }
}
public class MushRoom {
    public void printName() {
        System.out.println("dmg");
    }
}

其实我们上述行为是定义了一个产品族,交通工具一族,武器一族,食品一族。

现在实现一种灵活的方式来灵活扩展新的产品族,当新的产品族加入代码的时候不用改得太多。

现在代码就比较复杂,现在换产品族的话 mian方法里面的6句话都需要重写。

然后我们用灵活的方法扩展产品一族。

 

这个时候就需要抽象工厂了,可以生产一系列的产品

public abstract class AbastractFactory {
    abstract Food createFood();
    abstract Vehicle createVehicle();
    abstract Weapon createWeapon();
}
public abstract class Food {
   abstract void printName();
}
public abstract class Vehicle { 
    abstract void go();
}
public abstract class Weapon {
    abstract void shoot();
}
public class AK47 extends Weapon{
    public void shoot() {
        System.out.println("tututututu....");
    }
}
public class Bread extends Food{
    public void printName() {
        System.out.println("wdm");
    }
}
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");
    }
}
public class Car extends Vehicle{

    public void go() {
        System.out.println("Car go wuwuwuwuw....");
    }
}

AbastractFactory可以生产一系列的产品,可以生产抽象一族的Food Vehicle Weapon。

 

 

public class ModernFactory extends AbastractFactory {
    @Override
    Food createFood() {
        return new Bread();
    }

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

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

ModernFactory继承AbastractFactory

他也会生产 Bread Car AK47

 

当我们扩展产品一族的时候我们再来一个

public class MagicFactory extends AbastractFactory {
    @Override
    Food createFood() {
        return new MushRoom();
    }

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

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

MagicFactory继承AbastractFactory

也生产三种东西,只不过是魔法世界对应的三种东西了

 

角色分为抽象的工厂,具体的工厂。抽象的产品,具体的产品。

所以在main里面生产东西的时候用我们具体的工厂来完成就可以了,以后我们扩展只需要修改new ModernFactory(); 具体的工厂就可以了。

所以产品族就可以随意扩展了

public class Demo {
    public static void main(String[] args) {

        AbastractFactory f = new ModernFactory();

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

 

问题Vehicle为什么抽象类?为什么不是接口?Movable为什么用接口不用抽象类?

这是从语义出发。形容词用接口,名词用抽象类。

 

其实 武器 食品 交通工具抽象类可以再实现接口

抽象工厂 可以实现 工厂接口

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!