设计模式之Factory Method模式

本文介绍了Factory Method设计模式,强调了其注重框架设计的思想。通过一个生产身份证的例子,阐述了如何通过抽象类创建实例并由子类决定具体实现。文章定义了Product和Factory基类,分别表示产品和工厂的行为模式,并探讨了各个类之间的关系和方法。Factory Method模式规范了项目的整体风格,可用于与Template Method模式对比学习。
摘要由CSDN通过智能技术生成

     之前在《设计模式之Template Method模式》一文中详细讲了Template Method的思想,今天我们来讲一片跟这种模式看上去很相似,但是却完全不同的一个设计模式Factory Method模式。

     还是先说说这种模式的思想,这种模式注重“框架”二字,主要思想就是通过抽象类创建需要的实例,然后具体怎么创建交给子类去决定。还是用一个需求来作为例子说明。现在有这么个需求,我想要定义一个工厂,用于生产简单版的身份证。
      就是这么简单的一个需求,现在我们来分析一下这个需求。首先身份证是由国家部门严格把控的,所以这个身份证肯定会跟主人一一对应,并且得注册。具体一张身份证给那个人用,这是由政府部门决定,工厂只是负责生产身份证,在生产的时候就根据政府部门的要求,将编号给固定了。好了,大体的思路现在有了,首先得有一个IDCardFartory类,用于生产IDCard,并且对政府部门提供注册的API。然后还得有一个IDCard类。用于存储IDCard的信息,还得有一个Person类,用于对应IDCard。因为上面讲到了这篇文章讲的是Factory Method模式,还是注重“框架”二字的。那我们肯定得搭建一个固定生产模式的框架出来,上面讲到的这几个类都是具体去实现细节的类,我们设计模式讲究的是一种面向接口,面向抽象的开发模式,所以这儿我们得有两个抽象的基类,用于固定一种模式。首先得有一个产品类Product,用于决定该产品的一些基本信息模式。再接着得有一个工厂Factory类,用于决定这种类型的工厂的行为模式。看具体的实现:

    因为上面说到了,Product类和Factory类是用于决定一种生产模式的“框架的”,那我们把他们都放在同一个包framework包中,Product类,是产品的基类,肯定有一个方法,使用use方法,让用户去使用产品,还得提供一个设置主人的方法,以后这个产品跟人得一一对应。那就必须设定该方法,让相关部门去设定主人。

/**
 * Created by PICO-USER on 2017/3/10.
 */

public abstract class Product {

    public abstract void use();

    public abstract void setOwner(Person owner);

}

      有了产品的基类,我们还差一个工厂的基类Factory,这个工厂类规定了一种模式的工厂,工厂用于生产产品,那肯定有一个createProduct方法,还得提供祖册方法,让相关部门去注册该产品,后面我们想能够拿到该工厂生产的产品都是那些人在用,并且是谁在用哪一个产品,那我们需要一个集合用来存储这些数据,相关部门能查证。

/**
 * Created by PICO-USER Dragon on 2017/3/10.
 */

public abstract class Factory {

    public Product create() {

        Product product = createProduct();

        return product;
    }

    protected abstract Product createProduct();

    public abstract void registerProduct(Product product);

    public abstract Map<Long, Person> getSerials();

}
      框架有了,那接下来就是具体的实现了,还是先来实现产品方面的具体细节,在本例中产品就是IDCard,该类继承了Product类,具有Product类规定的特有方法,还拓展了一些特殊功能,在本例中按理说,产品都应该有产品号,所以cardNumber应该在父类中就有的,但是这儿没有放到分类中,要放到父类中也行。但是这儿我不想在基类中添加变量,故而放到子类中了。

/**
 * Created by PICO-USER on 2017/3/10.
 */

public class IDCard extends Product {

    private long cardNumber;
    private Person owner;

    IDCard(long cardNumber) {
        this.cardNumber = cardNumber;
    }

    public long getCardNumber() {
        return cardNumber;
    }

    public void setCardNumber(long cardNumber) {
        this.cardNumber = cardNumber;
    }

    public Person getOwner() {
        return owner;
    }

    @Override
    public void use() {

        System.out.print(owner.getName() + " is using card ,the cardNumber is " + cardNumber + "\n");
    }

    @Override
    public void setOwner(Person owner) {

        this.owner = owner;
    }
}

产品这边的具体有了,接下来就是工厂的具体实现,该类继承Factory基类,实现createProduct方法用于具体生产产品,该方法是受保护的,在Main类中,因为跟该类不在同一个包,所以无法调用该方法,还有IDCard的构造方法是没有public修饰的,Main类中也不能通过new得到IDCard的对象。强制要求Main类只能通过Factory的create方法得到。registerProduct方法,getSerials方法却是public,这儿为什么要是public修饰呢?因为注册功能,和查询功能应该都是政府部门进行,所以需要对外暴露出来,让Main类中可以调用。

/**
 * Created by PICO-USER Dragon on 2017/3/10.
 */

public class IDCardFactory extends Factory {

    Map<Long, Person> serials = new HashMap<>();

    private long cardNumber = 1000;

    @Override
    protected synchronized Product createProduct() {

        System.out.print("produce the card , number is " + cardNumber + "\n");

        IDCard idCard = new IDCard(cardNumber);
        cardNumber++;
        return idCard;
    }

    @Override
    public void registerProduct(Product product) {

        IDCard idCard = (IDCard) product;

        serials.put(idCard.getCardNumber(), idCard.getOwner());
    }

    @Override
    public Map<Long, Person> getSerials() {
        return serials;
    }

}

再来看看Main类的代码,这是用于测试用的类。不多说了。

public class Main {

    public static void main(String[] args0) {

        Factory cardFactory = new IDCardFactory();
        Product card1 = cardFactory.create();
        card1.setOwner(new Person("A", 18, "girl"));
        cardFactory.registerProduct(card1);

        Product card2 = cardFactory.create();
        card2.setOwner(new Person("B", 20, "boy"));
        cardFactory.registerProduct(card2);

        card1.use();
        card2.use();

        Map<Long, Person> serials = cardFactory.getSerials();

        for (Map.Entry<Long, Person> entry :
                serials.entrySet()) {

            Long key = entry.getKey();
            Person value = entry.getValue();

            System.out.print("number :" + key + " owner :" + value.toString() + "\n");

        }
    }
}


       Factory Method 模式在这儿就讲完了,在这儿再总结一下该模式。上面已经说得很清楚了,该模式侧重的是一种“框架”式的开发,用于规范项目的整体风格。可以跟Template Method模式对照学习。






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值