抽象工厂模式简单使用

21 篇文章 0 订阅
19 篇文章 0 订阅

前言

工厂方法模式指定了抽象了产品的功能,等待具体产品去实现该功能,而工厂方法不管产品的任何实现,只需要按需返回指定产品类;但是当工厂类生产的产品差别很大的时候,要对每一个产品区别化时,我们需要去更改具体的Product类的方法,比如汽车的例子,我们两个车的引擎不一样,那么我们就要去改Product类里面的Engine的具体实现,这种情况下,抽象工厂模式就更适合。抽象工厂模式可以对产品的零部件做一个基类,然后列出所有需要的实现部件类,然后等待具体的产品Factory类去组装产品,这时候Factory不单单是之前的模式了,所以,每个产品都应该有一个工厂实现类,当然可以在统一工厂类,通过判断决定产生何种产品。通过这些描述我们也知道了抽象工厂模式的弊端,就是实现一个生产过程需要很多类,所以使用的时候还得考虑一下,因为如果工厂很大,或许java会报65535的错。

角色扮演

抽象工厂说起来很多类,但说到底还是4个主要类:
AbstractFactory: 抽象工厂角色,所有工厂类的抽象基类,只定义抽象方法。

ConcreteFactory:具体工厂角色,实现抽象方法,多个产品会有多个具体实现类。

AbstractProduct:抽象产品角色,定义一个产品的抽象基类,因为各个工厂类会有不同的产品类,所以这里并不需要实现。

ConcreteProduct: 具体产品角色,实现产品的具体功能。

其实这个和工厂方法模式很像,只是抽象方法增多了,易于对产品的扩展。

代码实现

生产奔驰汽车的时候发现汽车车型不同,汽车的发动机、内饰都不相同,那么抽象引擎、内饰、外壳为产品,可以使用抽象工厂模式。

定义奔驰汽车抽象工厂类:

package com.demo.abstractfactory;

/**
 * Created by italkbb on 2017/12/14.
 */

public abstract class BenzCarFactory {
    /**
     * 装配内饰
     * @return
     */
    public abstract IDecoration addDecoration();

    /**
     * 装配引擎
     * @return
     */
    public abstract IEngine addEngine();

    /**
     * 装配外壳
     * @return
     */
    public abstract IShell addShell();
}

抽象工厂模式定义了汽车不同零件的装配方法,那么我们来列出所有的抽象产品类和具体产品类:

package com.demo.abstractfactory;

/**
 * Created by italkbb on 2017/12/14.
 */

public interface IDecoration {
    /**
     * 内饰实现方法
     */
    void docoration();
}

具体内饰实现类,内饰分为普通和豪华:

package com.demo.abstractfactory;

import android.util.Log;

/**
 * Created by italkbb on 2017/12/14.
 */

public class NormalDecoration implements IDecoration {
    // 类名,用于日志区分
    public final static String CLASSNAME = NormalDecoration.class.getSimpleName();

    @Override
    public void docoration() {
        Log.v(CLASSNAME,"普通内饰");
    }
}
package com.demo.abstractfactory;

import android.util.Log;

/**
 * Created by italkbb on 2017/12/14.
 */

public class LuxuryDecoration implements IDecoration {
    // 类名,用于日志区分
    public final static String CLASSNAME = LuxuryDecoration.class.getSimpleName();

    @Override
    public void docoration() {
        Log.v(CLASSNAME,"豪华内饰");
    }
}

同样,引擎分为国外跟国产类,同样的列出抽象类和具体类:

package com.demo.abstractfactory;

/**
 * Created by italkbb on 2017/12/14.
 */

public interface IEngine {
    /**
     * 引擎装配
     */
    void engine();
}
package com.demo.abstractfactory;

import android.util.Log;

/**
 * Created by italkbb on 2017/12/14.
 */

public class DomesticEngine implements IEngine {
    // 类名
    public final static String CLASSNAME = DomesticEngine.class.getSimpleName();
    @Override
    public void engine() {
        Log.v(CLASSNAME,"国产发动机");
    }
}
package com.demo.abstractfactory;

import android.util.Log;

/**
 * Created by italkbb on 2017/12/14.
 */

public class AbroadEngine implements IEngine {
    // 类名
    public final static String CLASSNAME = AbroadEngine.class.getSimpleName();
    @Override
    public void engine() {
        Log.v(CLASSNAME,"进口发动机");
    }
}

同样外壳也分为豪华和普通,但是因为代码都一样就不贴了。
接下来,我们要生产A级车和B级车,这时候相当于按需求拼装了,那么就会有两个工厂具体类:

package com.demo.abstractfactory;

/**
 * Created by italkbb on 2017/12/14.
 */

public class BenzAFactory extends BenzCarFactory {
    @Override
    public IDecoration addDecoration() {
        return new NormalDecoration();
    }

    @Override
    public IEngine addEngine() {
        return new DomesticEngine();
    }

    @Override
    public IShell addShell() {
        return new NormalShell();
    }
}
package com.demo.abstractfactory;

/**
 * Created by italkbb on 2017/12/14.
 */

public class BenzBFactory extends BenzCarFactory {
    @Override
    public IDecoration addDecoration() {
        return new LuxuryDecoration();
    }

    @Override
    public IEngine addEngine() {
        return new AbroadEngine();
    }

    @Override
    public IShell addShell() {
        return new SportsShell();
    }
}

这样产品的生产就完成了,使用的时候按需生产相关的类就行了,贴一下使用的代码:

package com.demo.abstractfactory;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;

import teltplay.example.com.kotlindemo.R;

public class AbstractFactoryActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_abstract_factory);
        // 生产A级车
        BenzCarFactory mACarFactory = new BenzAFactory();
        // 查询一下当前车辆信息
        mACarFactory.addDecoration().docoration();
        mACarFactory.addEngine().engine();
        mACarFactory.addShell().shell();

        // 生产B级车
        BenzCarFactory mBCarFactory = new BenzAFactory();
        // 查询一下当前车辆信息
        mBCarFactory.addDecoration().docoration();
        mBCarFactory.addEngine().engine();
        mBCarFactory.addShell().shell();
    }
}

简单的抽象工厂模式demo就写完了,类似于这种组装逻辑,抽象工厂模式还是游刃有余,但是你很容易发现,如果在增加一个车型,我们会增加一个工厂实现类,如果在增加一个部件,那么又会增加一个部件的基类以及多个部件实现类,同样的功能,抽象工厂模式会有很多类文件,这就是缺点了。

后记

抽象工厂分离接口和实现,很大程度上满足了高内聚低耦合的宗旨,产品生产也不需要你去具体实现,只需要自己寻找已有的零件,组装合成,很容易生产新产品。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值