zoukankan      html  css  js  c++  java
  • 工厂方法模式

    这个什么是工厂方法模式呢?

      工厂方法模式使用的频率非常高,在我们日常的开发中总能见到他的身影。其定义为:
      Define an interface for creating an object,but let subclasses decide which class to instanitate Factory Method lets a class defer instantiation to subclasses
      (定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类)

      也可以这样理解:

       工厂模式是我们最常用的实例化对象模式了,是用工厂方法代替new操作的一种模式。著名的Java论坛 ,就大量使用了工厂模式工厂模式在Java程序系统可以说是随处可见。因为工厂模式就相当于创建实例对象的new,我们经常要根据类Class生成实例对象,如A a=new A() 工厂模式也是用来创建实例对象的,所以以后new时就要多个心眼,是否可以考虑使用工厂模式,虽然这样做,可能多做一些工作,但会给你系统带来更大的可扩展性和尽量少的修改量。

      其UML图

      首先来看一个有意思的小故事。就是这个女娲那个时代觉得一个人太无聊了,就想造几个和自己差不多的东西来做伴。

      于是女娲就用她的八卦炉来生产我们人类。

      在这个过程中涉及三个对象:女娲,八卦炉,不同的人。女娲就类似一个客户,八卦炉就是一个工厂,而人就是产品

      来让我们用代码来实现这个造人计划

      First

      人类的总称:

    package com;
    
    public interface Human {
        //每个人种的皮肤都有相应的颜色
        public void getColor();
        //人类会说话
        public void talk();
    }

    //不同的人
    package com;
    public class WhiteHuman implements Human { @Override public void getColor() { System.out.println("这是白种人的颜色"); } @Override public void talk() { System.out.println("这是白种人说的话"); } }
    package com;
    //黄种人
    public class YellowHuman implements Human {
    
        @Override
        public void getColor() {
            System.out.println("这是黄种人的颜色");
            
        }
    
        @Override
        public void talk() {
            System.out.println("这是黄种人说的话");
            
        }
    
    }

    然后来创建工厂

    package com;
    
    /*
     * 作为一个生产者来说,我们只要知道生产了什么,而不需要事物的具体信息。
     * 通过分析,我们发现八卦炉生产人类的方法输入参数类型应该是Human接口的实现类
     */
    public abstract class AbstractHumanFactory {
        public abstract <T extends Human> T createHuman(Class<T> c);
    }

    实现抽象工厂的人工类

    package com;
    
    public class HumanFactory extends AbstractHumanFactory{
    
        @Override
        public <T extends Human> T createHuman(Class<T> c) {
            //定义一个生产人种
            Human human=null;
            
            try {
                //产生一个人
                human=(Human)Class.forName(c.getName()).newInstance();
            } catch (Exception e) {
                e.printStackTrace();
            }
            return (T) human;
        }
        
    }

    测试类

    package com;
    
    public class NvWa {
        public static void main(String[] args){
            //声明阴阳八卦炉
            AbstractHumanFactory YinYangLu=new HumanFactory();
            System.out.println("生产白人");
            Human whiteman=YinYangLu.createHuman(WhiteHuman.class);
            whiteman.getColor();
            whiteman.talk();
        }
        
    
    }

    这是一个工厂的通用源码

    //抽象产品类
        public abstract class Product{
            public void method1(){
                
            }
            
            public abstract void method2();
        }
        
        //具体产品类1
        public class ConcreteProduct1 extends Product{
    
            @Override
            public void method2() {
                //业务逻辑
            }
        }
        //具体产品类2
        public class ConcreteProduct2 extends Product{
            @Override
            public void method2() {
                //业务逻辑
            }
            
        }
        
        //抽象工厂类
        public abstract class Cretor{
            /*
             * 创建一个产品对象,其输入参数类型可以自行设置
             * 通常String,Enum,Class 等,当然也可以为空
             */
            public abstract <T extends Product> T createProduct(Class<T> c);
            
        }
        
        //具体工厂类
        public class ConcreteCreator extends Cretor{
    
            @Override
            public <T extends Product> T createProduct(Class<T> c) {
                Product product=null;
                try {
                    product=(Product)Class.forName(c.getName()).newInstance();
                } catch (Exception e) {
                    e.printStackTrace();
                }
                return (T) product;
            }
            
        }
        
        //场景类
        public  class Client{
            public static void main(String[] args){
                Cretor creator=new ConcreteCreator();
                Product product=creator.createProduct(ConcreteProduct1.class);
            }
        }
            

    优点:
    ·  首先,良好的封装性,代码结构清晰。一个对象创建时有条件约束的,如一个调用者需要一个具体的产品对象,只要知道这个产品的类名(或约束字符串)就可以了,
      不用知道创建对象的艰辛过程,降低了模块间的耦合性

      其次,工厂方法模式的扩展性非常优秀,只要适当的修改工厂类或扩展一个工厂类,就可以完成”拥抱变化“

      再次,屏蔽产品类。这一特点非常重要,产品类的实现如何变化,调用者都不需要关心,它只需要关心产品的接口,只要接口保持不变,系统中的上层模块就不要发生变化

      最后,工厂方法模式是典型的解耦和性框架

  • 相关阅读:
    RapidJavaEE 项目 开发流程说明
    [转]Ext自定义vtype动态验证
    博客园cnblogs chrome右键插件 开发
    extjs 2.0 回车切换表单,支持chrome,firefox,ie
    简单备份策略
    搜狗室验室 Web开发相关技术报告下载
    <转>记录一些BCB6的使用心得
    (转)远程桌面3389多用户登陆补丁及端口修改(XP+WIN7)
    <转>Java调用C/C++编写的第三方dll动态链接库(非native API) JNI
    清理SVN目录中.SVN
  • 原文地址:https://www.cnblogs.com/yaobolove/p/5602247.html
Copyright © 2011-2022 走看看