02_工厂方法模式

【工厂方法模式】

定义一个用于创建对象的接口(或抽象类),让子类决定去实例化哪一个类,工厂方法使一个类的实例化延迟到其子类。

【具体案例:小米手机工厂】

package com.Higgin.FactoryMethod;

/**
 * 小米手机接口
 * 其有三个实现类,分别对应小米1,小米2,小米3
 */
interface MiPhone{
    public void getPrice();
    public void call();
}

/**
 * 小米1
 */
class Mi1 implements MiPhone{
    public void getPrice() {
        System.out.println("小米1价格:999元!");
    }
    public void call() {
        System.out.println("小米1打电话...");
    }
}

/**
 * 小米2
 */
class Mi2 implements MiPhone{
    public void getPrice() {
        System.out.println("小米2价格:1999元!");
    }
    public void call() {
        System.out.println("小米2打电话...");
    }
}

/**
 * 小米3
 */
class Mi3 implements MiPhone{
    public void getPrice() {
        System.out.println("小米3价格:2999元!");
    }
    public void call() {
        System.out.println("小米3打电话...");
    }
}

/**
 * 抽象工厂类
 * 定义一个工厂的基本功能
 */
abstract class AbstractMiPhoneFactory{
    /*
     * 泛型使得参数c必须是MiPbone的实现类,且必须是Class类型(这里的Class的C大写!)
     * 其中T表示,只要是实现了MiPhone接口的类都可以作为参数
     */
    public abstract <T extends MiPhone> T createMiPhone(Class<T> c);  
}

/**
 * 具体工厂类
 */
class MiPhoneFactory extends AbstractMiPhoneFactory{
    public <T extends MiPhone> T createMiPhone(Class<T> c) {
        MiPhone miPhone=null;
        try {
            miPhone=(MiPhone) Class.forName(c.getName()).newInstance();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return (T) miPhone;
    }
}

/**
 * 客户端类
 */
public class TestMiPhoneFactory {
    public static void main(String[] args) {
        AbstractMiPhoneFactory miPhoneFactory=new MiPhoneFactory();
        MiPhone mi1=miPhoneFactory.createMiPhone(Mi1.class); //泛型的传入参数:类名.class 这里的class小写
        mi1.getPrice();
        mi1.call();
        MiPhone mi3=miPhoneFactory.createMiPhone(Mi3.class);
        mi3.getPrice();
        mi3.call();
    }
}

【运行结果】

【优点】

* 良好的封装性,代码接口清晰。一个对象的创建是有条件约束的,如一个调用者需要一个具体的产品对象(new Mi3()),只要知道这个产品的类名即可(Mi3.class),不需要知道其具体的创建过程,降低模块之间的耦合。

* 扩展性较为优秀,在增加产品类的,只要适当修改其具体工厂类或扩展一个工厂类即可,如需要增加一个小米4手机,只要增加一个class Mi4 implements MiPhone{...}类即可。

* 屏蔽产品类,调用者无需关心产品类如何变化,只需要关心产品的接口,只要接口不变,系统中的上层模块就不需要发生变化。

* 典型的解耦框架,高层模块只需知道产品的接口(或抽象类),其它实现类都不需要关心,符合迪米特法则;又因为只依赖于产品类的抽象,符合依赖倒置原则;还因为使用产品子类替换产品父类,符合里氏替换原则。

原文地址:https://www.cnblogs.com/HigginCui/p/6201926.html