设计模式(第二式:工厂方法模式)

概念:

  工厂方法模式:定义一个创建对象的接口,让子类决定实例化哪个类。工厂方法使一个类的实例化延迟到了子类。即在实例化对象时,我们不用自己new一个对象,而是将这个过程由另一个类通过反射或者new的方式创建对象并返回。

实现:

  定义书籍接口

public interface Book {
}

  定义工厂接口

public interface BookFactory {
    /**
     * 定义创建Book对象的方法,所有工厂实现该接口创建对应的book。
     * @return book
     */
    Book create();
}

  书籍类别(小说书籍、工具书籍...)

public class NovelBook implements Book {
    private String name;
    private BigDecimal price;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public BigDecimal getPrice() {
        return price;
    }

    public void setPrice(BigDecimal price) {
        this.price = price;
    }
}
public class ToolBook implements Book {
    private String name;
    private BigDecimal price;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public BigDecimal getPrice() {
        return price;
    }

    public void setPrice(BigDecimal price) {
        this.price = price;
    }
}

  工厂类别

public class NovelBookFactory implements BookFactory {
    /**
     * 创建小说的工厂,返回的对象是Book的子类
     * @return book
     */
    @Override
    public Book create() {
        return new NovelBook();
    }
}
public class ToolBookFactory implements BookFactory {
    /**
     * 创建工具类书籍的工厂,返回的对象是Book的子类
     * @return book
     */
    @Override
    public Book create() {
        return new ToolBook();
    }
}

  以上实现时常规的实现方式,一般类别比较少时没什么问题,但如果有一百多种类别,甚至更多种类别呢?不可能创建一百个工厂,所以还有一种扩展的实现方式,见下:

  定义工厂接口:

public interface ExtendFactory {
    <T>T creatBook(Class<T> c);
}

  工厂实现类:

public class ExtendBookFactory implements ExtendFactory {
    @Override
    public <T> T creatBook(Class<T> c) {
        try {
            //Book book_1 = (Book) Class.forName(c.getName()).newInstance(); //Java9 以上标示过时,
            Book book_2 = (Book) Class.forName(c.getName()).getDeclaredConstructor().newInstance();
            return (T) book_2;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}

分析:通过代码可以简单的分析一下

  1.具有良好的封装性。需要什么对象时只需要对应的工厂,如果是扩展式实现,则更为简单,只需需要知道具体的对象类名就可以了。

  2.扩展性良好。普通的实现方式,如果是需要扩展,不需要修改代码,只需要添加对象和对应的工厂,如果是扩展实现,只要添加相应的对象就可以了。

  3.解耦合。在逻辑模块不关心对象的创建过程。

  4.适用场景:

    a.一般和单例等模式一起用,单例一般可能是为了创建一个工厂。

    b.需要一个灵活可扩展的框架时,可以考虑使用。

    ……
经典框架中使用的:

  Spring框架中,管理Bean,默认生成的对象就是以单例模式生成;Struts2框架中,工厂对象基本都是使用单例模式生成。等等……

posted @ 2019-04-09 11:18  Mario0315  阅读(119)  评论(0编辑  收藏  举报