• 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{...}类即可。

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

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

  • 相关阅读:
    VC中的头文件stdafx.h的作用
    目标跟踪运动跟踪视觉跟踪综述(转)
    【转载】fatal error C1010: unexpected end of file while looking for precompiled header directive
    Realtime Compressive Tracking 刚出的一个跟踪技术
    研究反对称矩阵性质与应用的原因
    OpenGL在MFC下编程原理 Windows操作系统对OpenGL的支持(转)
    我们是不是菜鸟,可用以下情况自我判断。如果常发生以下事情,可自省已。共勉:
    www5net6com
    自定义的GridView控件源代码
    一直想写一本asp.net教程与实验指导,可是......
  • 原文地址:https://www.cnblogs.com/HigginCui/p/6201926.html
Copyright © 2020-2023  润新知