一天一个设计模式:抽象方法模式

为什么引入抽象工厂模式?

或者说抽象工厂模式与工厂方法模式的区别?

工厂方法模式针对的是一类产品的等级结构,而抽象工厂模式针对的是多个产品等级结构(一个产品族)。

引入概念:产品族与产品等级

产品族:指在不同的产品等级结构中,功能相关联的产品组成的家族。 产品等级:同类产品的不同产品区分。

抽象工厂的作用:

就是创建不同产品等级,但属于同一产品族的产品

那抽象工厂的定义:

创建不同产品等级,但属于同一产品族的产品的工厂的抽象。 那么具体的实现工厂就对应了不同的产品等级下的同一产品族的所有产品。

抽象工厂模式结构:

抽象工厂定义了一个产品族的生产功能,然后交由具体的产品工厂去生产。 

注:抽象工厂的接口不是随意堆砌的,而是相互关联或依赖的方法集成在一起的。

例子如下图:以电脑为例

优点:

    分离接口与实现     使用抽象工厂来创建所需要的对象,客户端仅仅是面向接口来编程,客户端可以实现从产品中解耦。     使切换产品族变得更容易     因为一个具体的工厂实现代表一个产品族,仅替换实现工厂即可切换。

缺点:

    不易扩展     产品族如果有新产品出现,就需要对抽象工厂进行修改,这会导致需要更新所有的工厂类。

实例:

 抽象工厂:

public interface AbstractFactory {
    /**
     * 创建CPU对象
     * @return CPU对象
     */
    public Cpu createCpu();
    /**
     * 创建主板对象
     * @return 主板对象
     */
    public Mainboard createMainboard();
}

英特尔工厂:

public class IntelFactory implements AbstractFactory {

    @Override
    public Cpu createCpu() {
        // TODO Auto-generated method stub
        return new IntelCpu(755);
    }

    @Override
    public Mainboard createMainboard() {
        // TODO Auto-generated method stub
        return new IntelMainboard(755);
    }

}

amd工厂:

public class AmdFactory implements AbstractFactory {

    @Override
    public Cpu createCpu() {
        // TODO Auto-generated method stub
        return new IntelCpu(938);
    }

    @Override
    public Mainboard createMainboard() {
        // TODO Auto-generated method stub
        return new IntelMainboard(938);
    }

}

装机人员:

public class ComputerEngineer {
    /**
     * 定义组装机需要的CPU
     */
    private Cpu cpu = null;
    /**
     * 定义组装机需要的主板
     */
    private Mainboard mainboard = null;
    public void makeComputer(AbstractFactory af){
        /**
         * 组装机器的基本步骤
         */
        //1:首先准备好装机所需要的配件
        prepareHardwares(af);
        //2:组装机器
        //3:测试机器
        //4:交付客户
    }
    private void prepareHardwares(AbstractFactory af){
        //这里要去准备CPU和主板的具体实现,为了示例简单,这里只准备这两个
        //可是,装机工程师并不知道如何去创建,怎么办呢?
        
        //直接找相应的工厂获取
        this.cpu = af.createCpu();
        this.mainboard = af.createMainboard();
        
        //测试配件是否好用
        this.cpu.calculate();
        this.mainboard.installCPU();
    }
}

测试代码:

public class Client {
    public static void main(String[]args){
        //创建装机工程师对象
        ComputerEngineer cf = new ComputerEngineer();
        //客户选择并创建需要使用的产品对象
        AbstractFactory af = new IntelFactory();
        //告诉装机工程师自己选择的产品,让装机工程师组装电脑
        cf.makeComputer(af);
    }
}

最后补充一句:

看到i7-9900k的售价,英特尔真是骗傻子钱多有恃无恐。干他妈的英特尔,amd加油!!!

参考链接:

https://www.cnblogs.com/java-my-life/archive/2012/03/28/2418836.html

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Java学习网

程序员偷偷深爱的 9 个不良编程习惯

程序员偷偷深爱的 9 个不良编程习惯 我们曾经都做过这样的事情:当妈妈不注意的时候,偷偷地吃糖果零食,然后导致有了蛀牙。同样的,我们都违背过一些编程的基本规则,...

25710
来自专栏编程

程序员偷偷深爱的9个不良编程习惯

关注「实验楼」,每天分享一个项目教程 下面这9个编码习惯,虽然在编程规则中是被驳斥的,但我们很多人就是会不由自主地使用它们。 正文共:4751字 预计阅读时间:...

1930
来自专栏Golang语言社区

伙计们,Go 并没有那么简单

出于好奇,我最近开始接触一些 Go 的代码。我之前对它有一些了解,但是从来没有尝试去写(没有需求)。但是现在我们团队选择使用 Go 来开发一个项目,所以我觉得这...

3166
来自专栏Crossin的编程教室

【Python 第16课】 字符串格式化2

今天我又改回到直接发送课程内容的方式。不要怪我多变,是我实在受不了微信公众平台。发送文本消息几乎就没有办法成功,也没有提示到底是哪里出了问题。昨天短短一段话,发...

2659
来自专栏Java帮帮-微信公众号-技术文章全总结

【大牛经验】写好Java代码的30条经验总结

成为一个优秀的Java程序员,有着良好的代码编写习惯是必不可少的。下面就让我们来看看代码编写的30条建议吧。 (1) 类名首字母应该大写。字段、方法以及对象(句...

3969
来自专栏Java技术分享圈

给一些想要学习Java同学的一些建议

最近在授课过程中,发现了各式各样学生在学习Java时遇到的问题。有同学会问我:“杨老师,Java可以自学吗”,这就好像一千个人心中有一千个哈利波特一样,这个答案...

1361
来自专栏晨星先生的自留地

一道小CTF

3314
来自专栏Java帮帮-微信公众号-技术文章全总结

Java基础-day05-超市收银系统案例题

Java基础-day05-超市收银系统案例题 案例描述 将超市购物小票案例中,键盘录入部分封装为方法。 将switch语句完成的三个分支代码逻辑封装为3个方法 ...

5434
来自专栏take time, save time

你所能用到的数据结构(六)

八、数据结构不一定很枯燥   正如我现在实习的公司的一个同事说的那样,数据结构是一本催眠的书,我想对于大多数人应该是这样的,当然对我也是,看着一大堆的算法,结...

3345
来自专栏ACM算法日常

唯快不破的01序列——位运算初识

众所周知,计算机的运算使用的就是二进制,它会把十进制的数转化为二进制,然后进行二进制运算,最后再转回十进制展现给我们。而位运算指的是:由于数字在计算机里...

1113

扫码关注云+社区

领取腾讯云代金券