您好,欢迎来到站长目录(28sn.com)!


设计模式是什么鬼(抽象工厂)

来源:网络整理 浏览:151次 时间:2021-07-23

//本文作者:凸凹里歐
//本文收录菜单栏:《设计模式是什么鬼》专栏中

抽象工厂,意味着工厂的泛化,也就是说对多个工厂共通行为的抽取及概括。这和我们之前讲过的工厂方法模式十分类似,不同之处在于抽象工厂定义了更多的抽象行为,也就是多个工厂方法于抽象工厂中,其实它就是工厂方法的变种而已,所以建议读者先理解好工厂方法模式再回来看本章。

我们都知道,在工厂方法模式中的每个实际的工厂只定义了一个工厂方法,如果产品种类繁多,并且能进行归类分族的话,那么我们便可以顺理成章的定义多个工厂方法,如此可以避免过多的产品造成工厂泛滥的问题。比如宝驹汽车有轿车、SUV、跑车三个等级的产品,而奔痴汽车也同样包括以上三类等级产品,如此便形成了两个产品族,分别由宝驹工厂和奔痴工厂生产,每个工厂都有三个等级的生产线,以及后加入的四环汽车产品族同样可以符合这个规范模式。

我们以一款即时战略游戏来举例,假设游戏中有两个种族,地球人类与外星异形族,其中人类族拥有各种高科技军工制造技术,而怪兽异形族则是以血肉之躯的不断进化与人类抗衡。

在开始代码之前我们先对两族兵种进行分析归纳,我们看到人类兵工厂和怪兽兵工厂(母巢)产出兵种都可以被简单归纳为初、中、高三个等级,如下表所示。

好了,产品族已经定义清楚了,开始建立数据模型。首先定义产品的父类抽象兵种Unit,这里我们使用抽象类以达到属性延申遗传给子类的目的。

 1public abstract class Unit {// 兵种 2 3    protected int attack;// ***力 4    protected int defence;// 防御力 5    protected int health;// 血量 6    protected int x;// 横坐标 7    protected int y;// 纵坐标 8 9    public Unit(int attack, int defence, int health, int x, int y) {10        this.attack = attack;11        this.defence = defence;12        this.health = health;13        this.x = x;14        this.y = y;15    }1617    public abstract void show();1819    public abstract void attack();2021}

不管是什么兵种必然会具有***力、防御力、血量体力值、坐标方位等等属性,我们都定义为protected以供子类继承,除此之外还有两个抽象方法显示和***。接下来是人类的产品族海军陆战队士兵、变形坦克和巨型战舰,它们分别对应初、中、高级兵种。

 1public class Marine extends Unit {// 海军陆战队士兵 2 3    public Marine(int x, int y) { 4        super(6, 5, 40, x, y); 5    } 6 7    @Override 8    public void show() { 9        System.out.println("士兵出现在坐标:[" + x + "," + y + "]");10    }1112    @Override13    public void attack() {14        System.out.println("士兵用机关枪射击,***力:" + attack);15    }1617}
 1public class Tank extends Unit {// 坦克 2 3    public Tank(int x, int y) { 4        super(25, 100, 150, x, y); 5    } 6 7    @Override 8    public void show() { 9        System.out.println("坦克出现在坐标:[" + x + "," + y + "]");10    }1112    @Override13    public void attack() {14        System.out.println("坦克用炮轰击,***力:" + attack);15    }1617}
 1public class Battleship extends Unit {// 巨型战舰 2 3    public Battleship(int x, int y) { 4        super(25, 200, 500, x, y); 5    } 6 7    @Override 8    public void show() { 9        System.out.println("战舰出现在坐标:[" + x + "," + y + "]");10    }1112    @Override13    public void attack() {14        System.out.println("战舰用激光炮打击,***力:" + attack);15    }1617}

可以看到每个兵种的属性值都不同,我们在第4行的构造方法中调用了父类构造,直接赋值给遗传下来的属性,兵种越高***防御越高(当然制造成本也更高,这里我们忽略价格),而且都重写了自己的展示和***方法,行为差异化,当然也许坦克会具备其他特有的行为比如变形什么的(异形也许会打洞钻地),我们此处依然忽略,保持简约。然后定义外星生物家族的三级兵种,分别是:蟑螂、毒液、猛犸。

 1public class Roach extends Unit {// 外星蟑螂兵 2 3    public Roach(int x, int y) { 4        super(5, 2, 35, x, y); 5    } 6 7    @Override 8    public void show() { 9        System.out.println("蟑螂兵出现在坐标:[" + x + "," + y + "]");10    }1112    @Override13    public void attack() {14        System.out.println("蟑螂兵用爪子挠,***力:" + attack);15    }1617}
 1public class Spitter extends Unit {// 外星毒液口水兵 2 3    public Spitter(int x, int y) { 4        super(10, 8, 80, x, y); 5    } 6 7    @Override 8    public void show() { 9        System.out.println("口水兵出现在坐标:[" + x + "," + y + "]");10    }1112    @Override13    public void attack() {14        System.out.println("口水兵用毒液喷射,***力:" + attack);15    }1617}
 1public class Mammoth extends Unit {// 外星猛犸巨兽 2 3    public Mammoth(int x, int y) { 4        super(20, 100, 400, x, y); 5    } 6 7    @Override 8    public void show() { 9        System.out.println("猛犸巨兽兵出现在坐标:[" + x + "," + y + "]");10    }1112    @Override13    public void attack() {14        System.out.println("猛犸巨兽用獠牙顶,***力:" + attack);15    }1617}

没什么好说的,大同小异。重点来了,接下来是我们的抽象工厂,概括出三个等级兵种的标准制造方法,我们这里以接口来定义它。

1public interface AbstractFactory {23    public Unit createLowClass();// 工厂方法:制造低级兵种45    public Unit createMidClass();// 工厂方法:制造中级兵种67    public Unit createHighClass();// 工厂方法:制造高级兵种8}

可以看到,三个等级的接口意味着子类具体工厂必须具备初、中、高级三条生产线,它们同属一个家族,或者说是一个品牌的不同型号系列。理解了这一点后我们可以开始定义人类兵工厂的实现。

 1public class HumanFactory implements AbstractFactory{ 2 3    //人族工厂坐标 4    private int x; 5    private int y; 6 7    public HumanFactory(int x, int y) { 8        this.x = x; 9        this.y = y;10    }1112    @Override13    public Unit createLowClass() {14        Unit unit = new Marine(x, y);15        System.out.println("制造海军陆战队员成功。");16        return unit;17    }1819    @Override20    public Unit createMidClass() {21        Unit unit = new Tank(x, y);22        System.out.println("制造变形坦克成功。");23        return unit;24    }2526    @Override27    public Unit createHighClass() {28        Unit unit = new Battleship(x, y);29        System.out.println("制造巨型战舰成功。");30        return unit;31    }3233}

可以看到,这个兵工厂实现了人类兵种产品族的制造方法,分别对应三个等级兵种的制造方法,注意第14行的坐标初始化意思是在工厂的坐标位置上出兵。接下来是异形母巢的工厂实现。

 1public class AlienFactory implements AbstractFactory{ 2 3    //外星虫族工厂坐标 4    private int x; 5    private int y; 6 7    public AlienFactory(int x, int y) { 8        this.x = x; 9        this.y = y;10    }1112    @Override13    public Unit createLowClass() {14        Unit unit = new Roach(x, y);15        System.out.println("制造蟑螂兵成功。");16        return unit;17    }1819    @Override20    public Unit createMidClass() {21        Unit unit = new Spitter(x, y);22        System.out.println("制造毒液兵成功。");23        return unit;24    }2526    @Override27    public Unit createHighClass() {28        Unit unit = new Mammoth(x, y);29        System.out.println("制造猛犸巨兽成功。");30        return unit;31    }3233}

显而易见,同样地分三级制造异形家族的产品系列,工厂准备完毕可以造兵打架了,运行游戏客户端。

 1public class Client { 2    public static void main(String[] args) { 3        System.out.println("游戏开始。。。"); 4        System.out.println("双方挖矿攒钱。。。"); 5 6        //第一位玩家选择了地球人族 7        System.out.println("工人建造人族工厂。。。"); 8        AbstractFactory factory = new HumanFactory(10, 10); 910        Unit marine = factory.createLowClass();11        marine.show();1213        Unit tank = factory.createMidClass();14        tank.show();1516        Unit ship = factory.createHighClass();17        ship.show();1819        //另一位玩家选择了外星族20        System.out.println("工蜂建造外星虫族工厂。。。");21        factory = new AlienFactory(200, 200);2223        Unit roach = factory.createLowClass();24        roach.show();2526        Unit spitter = factory.createMidClass();27        spitter.show();2829        Unit mammoth = factory.createHighClass();30        mammoth.show();3132        System.out.println("两族开始大混战。。。");33        marine.attack();34        roach.attack();35        spitter.attack();36        tank.attack();37        mammoth.attack();38        ship.attack();3940        /*41            游戏开始。。。42            双方挖矿攒钱。。。43            工人建造人族工厂。。。44            制造海军陆战队员成功。45            士兵出现在坐标:[10,10]46            制造变形坦克成功。47            坦克出现在坐标:[10,10]48            制造巨型战舰成功。49            战舰出现在坐标:[10,10]50            工蜂建造外星虫族工厂。。。51            制造蟑螂兵成功。52            蟑螂兵出现在坐标:[200,200]53            制造毒液兵成功。54            口水兵出现在坐标:[200,200]55            制造猛犸巨兽成功。56            猛犸巨兽兵出现在坐标:[200,200]57            两族开始大混战。。。58            士兵用机关枪射击,***力:659            蟑螂兵用爪子挠,***力:560            口水兵用毒液喷射,***力:1061            坦克用炮轰击,***力:2562            猛犸巨兽用獠牙顶,***力:2063            战舰用激光炮打击,***力:25 64         */65    }66}

这里我们可以看到,不管玩家选择哪个种族,只要替换工厂实现就可以完成不同兵种的制造,假设玩家又需要一个新的种族,依然按照这种模式去实现一个新族工厂就可以了。

至此,我们用各族工厂对种类繁多的产品进行了划分、归类,产品虽然繁多,但总得有品牌、型号之分,以各族工厂和产品线划界,分而治之,横向拆分产品家族,纵向则拆分产品等级。

推荐站点

  • 我爱发烧音乐我爱发烧音乐

    我爱发烧音乐囊括了从流行音乐到古典音乐多个类型的音乐作品,专栏推荐最新的音乐,提供音乐排名榜单!可供免费线上收听音乐,歌曲流畅,音效极佳! 网站提供的钢琴以及二胡专栏,可供收听者,陶冶情操,改善心情,是难得的轻音乐典藏!

    www.520fs.com
  • 世纪音乐网世纪音乐网

    世纪音乐网是专业的在线音乐试听MP3下载网站。歌曲总计30余万首,收录了网上最新歌曲和流行音乐,DJ舞曲,非主流音乐,经典老歌,劲舞团歌曲,搞笑歌曲,儿童歌曲,英文歌曲等。是您上网听歌的最佳网站。

    www.ssjj.com
  • 杭州网杭州网

      杭州网是杭州地区唯一的新闻门户网站,由中共杭州市委宣传部、杭州日报报业集团和杭州广播电视集团共同组建的杭州网络传媒有限公司运营。

    www.hangzhou.com.cn
  • 深圳在线深圳在线

      深圳在线 www.szol.net是深圳本地最大、最早的地方生活资讯网站之一,网站名“深圳在线www.szol.net”由南方报业传媒集团编辑委员会总编辑、南方日报社总编辑、南方都市报总编辑、南方书画院名誉院长王春芙亲笔题名,深圳在线www.szol.net团队与深圳热线www.szonline.net、奥一网www.oeeee.com都源于全国最早成立于1996年的知名网络公司——深圳万用网。

    www.szol.net
  • 今题网今题网

     今题网- 中国领先的社区服务网,提供社区服务, 在线交友和商家推广服务,于2004年创建上线,公司现有员工超过百名。今题网自成立以来,凭借其独特的定位和丰富的社区交友功能, 凭借其团队超强的搜索引擎优化技术吸引超过千万的用户成为今题网的注册会员。

    www.jinti.com

鄂公网安备 42062502000001号