欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

设计模式——抽象工厂

程序员文章站 2022-03-09 20:36:08
...

1.抽象工厂

     什么是抽象工厂?简单的来说,抽象工厂是对具体工厂的抽象,它只负责产品的创建,并不负责产品的具体实现,而产品的具体实现是由实现该抽象工厂的具体工厂来完成。

 

2.举例:电子产品工厂

     就拿我们常见的电子产品来做一个抽象工厂的讲解,生活中常见的电子品牌有苹果、小米、华为、魅族等,它们都有自己许多种类相似的产品,如苹果有苹果手机、苹果平板、苹果耳机等等,小米也有小米手机、小米平板、小米耳机等等。

     抽象其实就是把一类事物的共性抽取出去,上面的例子,苹果和小米都能创建手机、平板、耳机这一系列有共同特征的产品。在定义的时候就说过,抽象工厂只负责产品的创建。也就是说这几个产品都可以由抽象工厂创建。

     那我们就可以写一个抽象工厂的接口,代码如下。

//电子产品工厂
public interface ElectronicProductFactory {
    public Phone getPhone();

    public Headset getHeadset();
}

    这里只创建了两个产品,一个是耳机,一个是手机,当然还有其它相似的产品,就不在这里一一写了。

    在定义的时候还说过,产品的具体创建是交给具体工厂完成的,现在我们有两个厂商(小米、苹果)那么也就应该有两个具体工厂,分别负责创建属于自己品牌的产品,代码如下。 

//苹果工厂 只负责创建苹果的产品
public class AppleFactory implements  ElectronicProductFactory{
    @Override
    public Phone getPhone() {

        return new ApplePhone();
    }

    @Override
    public Headset getHeadset() {
        return new AppleHeadset();
    }
}


//小米工厂 只负责创建小米的产品
public class XiaoMiFactory implements ElectronicProductFactory {
    @Override
    public Phone getPhone() {
        return new XiaoMiPhone();
    }

    @Override
    public Headset getHeadset() {
        return new XiaoMiHeadset();
    }
}

      好,现在我们有了具体的工厂,但是我们还没有具体的产品,那么我们就可以创建具体的产品了,首先是对手机的抽象,手机都有很多共有的属性,如有系统,有CPU,有外观等等,手机还有很多共同的方法(行为),如打电话、上网、拍照等等。耳机也有许多共有的属性,如类型、外观、音质等等,耳机共同的方法(行为),如听歌、调音量等等。

     先看对手机的抽象,代码如下。

//我是手机
public abstract class Phone {
    //处理器
    private String cpu;


    public abstract void call();

    public abstract void takePictures();


    public String getCpu() {
        return cpu;
    }

    public void setCpu(String cpu) {
        this.cpu = cpu;
    }
}

    再看对耳机的抽象,代码如下。

//我是耳机
public abstract class Headset {
    
    //音质
    private String timbre;

    public abstract void listenMusic();


    public String getTimbre() {
        return timbre;
    }

    public void setTimbre(String timbre) {
        this.timbre = timbre;
    }
}

        因为内容较多,我就只写一两个属性。然后是每个产品的具体实现,如小米耳机,苹果耳机,小米手机,苹果手机等。代码如下,很容易理解,就不多说了。

//苹果手机的具体实现
public class ApplePhone extends Phone {
    public ApplePhone() {
        setCpu("A系列CPU!");
    }

    @Override
    public void call() {
        System.out.println("我是苹果手机,我能打电话!");
    }

    @Override
    public void takePictures() {
        System.out.println("我是苹果手机,我拍照好!");
    }
}

//小米手机的具体实现

public class XiaoMiPhone extends Phone {

    public XiaoMiPhone() {
        setCpu("高通系列CPU");
    }

    @Override
    public void call() {
        System.out.println("我是小米手机,我也能打电话!");
    }

    @Override
    public void takePictures() {
        System.out.println("我是小米手机,我拍照也还可以!");
    }
}




//苹果耳机的具体实现
public class AppleHeadset extends Headset {
    public AppleHeadset() {
        setTimbre("nice");
    }

    @Override
    public void listenMusic() {
        System.out.println("我是苹果耳机,比较高档,听歌很舒服!");
    }
}


//小米耳机的具体实现
public class XiaoMiHeadset extends Headset {

    public XiaoMiHeadset() {
        setTimbre("good");
    }

    @Override
    public void listenMusic() {
        System.out.println("我是小米耳机,能听歌!");
    }
}

     工厂和产品都已经创建完毕,下面就去测试一下我们的抽象工厂。

      

public class Main {
    
    public static void main(String [] args) {
        //创建一个苹果工厂,只生产苹果的产品。
        ElectronicProductFactory electronicProductFactory = new AppleFactory();
        //拿到一个手机
        Phone phone = electronicProductFactory.getPhone();
        System.out.println("处理器用的是"+phone.getCpu());
        phone.call();
        phone.takePictures();
        //拿到一个耳机
        Headset headset = electronicProductFactory.getHeadset();
        System.out.println("音质是:"+headset.getTimbre());
        headset.listenMusic();
    }
}



//打印结果
处理器用的是A系列CPU!
我是苹果手机,我能打电话!
我是苹果手机,我拍照好!
音质是:nice
我是苹果耳机,比较高档,听歌很舒服!

  3.总结 

   从上面代码可以看出,工厂使用的是抽象的工厂,而产品也是使用的是抽象类,说到这里你应该明白了吧,抽象工厂不仅是要对具体工厂进行抽象,也需要对产品进行抽象。

    抽象工厂和简单工厂以及工厂方法模式不太相同,因为简单工厂和工厂方法模式都是只创建一类产品,如要么只创建手机,要么只创建耳机。而抽象工厂是对一系列产品的创建(产品族),它是工厂的工厂,抽象工厂负责定义创建的产品,而具体工厂是该类的产品(如苹果工厂负责创建苹果的产品,小米工厂负责创建小米的产品)。

     写了这么多,如果你还是不太清楚抽象工厂,那么请仿着上面的代码敲一遍。

     大家有没有想过抽象工厂有什么缺点?我们在定义抽象工厂的时候,是定义创建的产品,就算我们能创建出目前已知的所有产品,如果某天又有了新的产品,假设某天有了个人飞行设备。那么我们就得去修改抽象工厂的接口方法,新增一个个人飞行设备的创建,这样就很明显的违背了开闭原则。

     抽象工厂模式主要是用来解决产品族的创建,也就是上面的某个厂商一系列的产品,好了就写这么多了,大家慢慢消化。