zoukankan      html  css  js  c++  java
  • Factory Method (工厂模式)

    什么是工厂设计模式

    根据名字即可了解,工厂肯定是用来生产产品的,在我们的程序开发中,需要用到不同的类,对于熟悉SSH、SSM开发的可以知道,在初期学习的时候,总是有一个框架提供好的的factory供我们使用,利用它可以创建访问数据库的连接等操作。

    定义:

    利用template method设计模式创建我们想要的实例,就称之为factory method。

    具体到面向对象

    • 《framework》生成实例框架:可以理解为在我使用factoy method时这个是必须的,组成元素在这个包下
    • 《product》: 具体的产品类,你需要生成什么就可以创建自己的产品。加工处理

    UML 代码

    这个例子就是实现创建一个身份证,然后使用它

    • framework包下
      - Factory :创建实例的方法 这里要注意创建 注册都是维护的protected方法
      - Product : 定义操作的方法

    • product包下
      - IdCard :具体的产品
      - IdCardFactory :实现了具体的创建。

    • Factory

    package base.factory.framework;
    
    /**
     * @program: DesignPatterns
     * @description: 创建实例的类
     * @author: Mr.Dai
     * @create: 2018-05-07 15:48
     **/
    public abstract class Factory {
    
        public final Product create(String name){
            Product product = createProduct(name);
            registerProduct(product);
            return product;
        }
    
        protected abstract Product createProduct(String name);
        protected abstract void registerProduct(Product product);
    }
    
    
    • Product
    
    package base.factory.framework;
    
    /**
     * @program: DesignPatterns
     * @description: 定义具体方法的类
     * @author: Mr.Dai
     * @create: 2018-05-07 15:51
     **/
    public abstract class Product {
    
        public abstract void use();
    
    }
    
    
    • IdCard
    
    package base.factory.idcard;
    
    import base.factory.framework.Product;
    
    /**
     * @program: DesignPatterns
     * @description: 具体的身份类
     * @author: Mr.Dai
     * @create: 2018-05-07 15:57
     **/
    public class IdCard extends Product {
    
        private String name;
    
        IdCard(String name){
            System.out.println("创建了"+name+"的身份证");
            this.name=name;
        }
        @Override
        public void use() {
            System.out.println("使用了"+name+"的身份证");
        }
    
        public String getOwer(){
            return this.name;
        }
    }
    
    
    • IdCardFactory
    
    package base.factory.idcard;
    
    import base.factory.framework.Factory;
    import base.factory.framework.Product;
    
    import java.util.Vector;
    
    /**
     * @program: DesignPatterns
     * @description: 生产身份证具体的类
     * @author: Mr.Dai
     * @create: 2018-05-07 16:00
     **/
    public class IdCardFactory extends Factory {
    
        private Vector idcards=new Vector<String>();
    
        @Override
        public Product createProduct(String name) {
            return new IdCard(name);
        }
    
        @Override
        public void registerProduct(Product product) {
                idcards.add(((IdCard)product).getOwer());
        }
    
        public Vector<String> getIdCards(){
            return idcards;
        }
    }
    
    
    • 结果

    具体说明

    • product:是生成实例具有的接口方法,具体处理由子类决定
    • CreatedProduct:具体的产品 由idcard承担
    • CreatedCreator:具体的创建者 由IdCardFactory承担
    • IdCardFactory是具体的承担者,父类Factory将会解除与子类的耦合,实际上是子类具体的创建者来生成具体的实例。
    • 实际运用中,我们没有必要去修改framework下的任何内容,假设我们这里要维护一台电视机,只需要创建具体的类即可。

    实例产生的三种方式

    • 指定为抽象方法
    
    public abstract class Factory {
    
        public final Product create(String name){
    
    
    • 直接生成
    public abstract class Factory {
    
        public  Product create(String name){
      return new Product(name);//这样的话,product就不能为抽象类
    
    

    Televison 电视类 并且实现 保存编号 以及所有者之间的对应表

    • Televison
    package base.factory.television;
    
    import base.factory.framework.Product;
    
    /**
     * @program: DesignPatterns
     * @description: 电视类
     * @author: Mr.Dai
     * @create: 2018-05-07 16:40
     **/
    public class Televison extends Product {
    
        private String name;
        Televison(String name){
            this.name=name;
        }
    
        @Override
        public void use() {
            open();
            runing();
            close();
        }
    
        public void open(){
            System.out.println("开电视"+name);
        }
        public void runing(){
            System.out.println("看电视"+name);
        }
        public void close(){
            System.out.println("关闭电视"+name);
        }
    
        public String getName(){
            return  this.name;
        }
    }
    
    
    • TelevisionFactory
    package base.factory.television;
    
    import base.factory.framework.Factory;
    import base.factory.framework.Product;
    
    import java.util.HashMap;
    import java.util.Map;
    import java.util.TreeMap;
    
    /**
     * @program: DesignPatterns
     * @description: 创建televi
     * @author: Mr.Dai
     * @create: 2018-05-07 16:45
     **/
    public class TelevisionFactory  extends Factory {
    
        private TreeMap<Integer,String> teleS=new TreeMap<>();
        private int i=0;
        @Override
        protected Product createProduct(String name) {
            return new Televison(name);
        }
    
        @Override
        protected void registerProduct(Product product) {
            teleS.put(++i,((Televison)product).getName());
        }
        public TreeMap getTeles(){
            return  teleS;
        }
    }
    
    

    相关设计模式

    • template method :factory method就是模板设计模式的延伸。
    • singleton :单例模式,这里我们的产品可以改为单例模式,我们实际运用中使用的到的类比如hibernate中的,都是单例的 如数据库连接等。
    • Composite: composite模式用于product角色
    • Iterator: 在Iterator模式中使用iterator方法生成Iterator实例会使用Factory Method。

    还有一个问题是,使用Factory Method 设计模式,必须在具体的Product作注释,不然使用者必须了解上层代码,或者维护可能会修改使用者的具体用意。

  • 相关阅读:
    JSP标准标签库(JSTL)--JSTL简介与安装
    JSP标签编程--简单标签
    Tomcat数据源
    Linux 更新vim
    perl 函数
    js 使用a标签 下载资源
    js arrayBuffer 字节序问题,小端法,大端法
    js 的 ArrayBuffer 和 dataView
    ajax 获取服务器返回的XML字符串
    遍历form表单里面的表单元素,取其value
  • 原文地址:https://www.cnblogs.com/dgwblog/p/9003648.html
Copyright © 2011-2022 走看看