• 工厂方法模式小试


    一、介绍

    今天,我们来回顾一下工厂方法模式,这个模式很简单。

    《研磨设计模式》中的定义是:定义一个用于创建对象的接口,让子类决定实例化哪个类,“Factory Mehod”使一个类的实例化延迟到子类。

    工厂方法模式的本质是——延迟到子类来选择实现

    什么意思呢?简单来说,就是面向接口编程。

    打个比方,我现在需要一个水果类,就可以直接写一个简单的水果接口 interface Fruit{},至于实现类是什么,我不关心。直接使用这个接口就是了,反正java对象是运行时绑定。怎么使用这个接口呢,当然是抽象方法了。这样,不同的子类继承的时候就可以选择不同的实现类。

    二、结构

    1、Product——需要创建的对象的接口。

    2、ConcreteProduct——需要创建的对象的实现类。

    3、Creator——工厂方法接口,有一个返回所需对象的抽象方法,留给子类选择实现。也可以提供默认的实现。

    4、ConcreteCreator——工厂方法实现类。用来提供具体的选择实现。

    三、我的实现

    1、首先我们有一个简单的产品接口和它的2个实现,如下:

    package factoryMethod;
    
    public interface Product {
    
        public void autoFly();
    }
    package factoryMethod;
    
    public class ProductImpl1 implements Product{
    
        public void autoFly() {
            // TODO Auto-generated method stub
            System.out.println("product1 is flying!");
        }
    
    }
    package factoryMethod;
    
    public class ProductImpl2 implements Product{
    
        public void autoFly() {
            // TODO Auto-generated method stub
            System.out.println("product2 is flying!");
        }
    
    }

    2、我们建立了一个工厂,使用这个工厂,就可以实现产品的功能

    package factoryMethod;
    
    public abstract class MyFactory {
    
        protected abstract Product getMyProduct();
        
        public void fly(){
            getMyProduct().autoFly();
        }
    }

    如上,我们编写的这个工厂为一个抽象类,我们不知道它的具体实现,但是它已经完成了逻辑调用。它的具体调用,留到子类去实现

    3、那么我们编写2个工厂子类,如下:

    package factoryMethod;
    
    public class Factory1 extends MyFactory {
    
        @Override
        protected Product getMyProduct() {
            // TODO Auto-generated method stub
            return new ProductImpl1();
        }
    
    }
    package factoryMethod;
    
    public class Factory2 extends MyFactory {
    
        @Override
        protected Product getMyProduct() {
            // TODO Auto-generated method stub
            return new ProductImpl2();
        }
    
    }

    如上,工厂的子类只需要实现父类没有完成功能,而无需改变父类的基本功能。

    4、那么客户端调用如下:

    package factoryMethod;
    
    public class Client {
    
        public static void main(String[] args) {
            MyFactory factory = new Factory1();
            factory.fly();
        }
    }

    如上,我们是直接通过工厂来调用产品功能,工厂本身并不负责选择实现。选择实现是简单工厂模式的本质。

    我们可以看到,工厂方法模式是通过工厂类简单的抽象来实现的。

    如果我们需要创建某个接口的对象,但是又不知道具体的实现,那么我们可以使用工厂方法模式。

    5、另外,工厂方法模式还有另一种用法,那就是工厂类本身有默认的实现,这种情况下,工厂类可以构造为普通类,而不是抽象类。如下:

    package factoryMethod;
    
    public class NewFactory {
    
        protected Product getMyProduct() {
            // TODO Auto-generated method stub
            return new ProductImpl1();
        }
    
        public void fly() {
            getMyProduct().autoFly();
        }
    }

    6、然后,当我们需要另一个产品的时候,就可以继承NewFactory,重写getMyProduct()方法,如下:

    package factoryMethod;
    
    public class SonOfNewFacory1 extends NewFactory{
    
        @Override
        protected Product getMyProduct() {
            // TODO Auto-generated method stub
            return new ProductImpl2();
        }
    }

    客户端调用就毋须演示了。

    7、同样,工厂方法模式可以与简单工厂模式结合起来,在工厂方法模式中选择实现。如下:

    package factoryMethod;
    
    public class FunctionFactory {
    
        protected Product getMyProduct(int type) {
            Product product = null;
            if (type == 1) {
                product = new ProductImpl1();
            } else {
                product = new ProductImpl2();
            }
            return product;
        }
    
        public void fly(int type) {
            getMyProduct(type).autoFly();
        }
    }

    8、如果需要添加一个新的实现,《研磨设计模式》中提到了一种优雅的方式,如下:

    package factoryMethod;
    
    public class SonOfFunctionFactory1 extends FunctionFactory {
    
        @Override
        protected Product getMyProduct(int type) {
            // TODO Auto-generated method stub
            if (type == 3) {
                return new ProductImpl3();
            }
            //其他的让父类去实现
            return super.getMyProduct(type);
        }
    }
    /**
    *   ————————如果觉得本博文还行,别忘了推荐一下哦,谢谢!
    *   作者:钱书康
    *   欢迎转载,请保留此段声明。
    *   出处:http://www.cnblogs.com/zrtqsk/
    */
  • 相关阅读:
    【月度盘点】《金秋10月》
    selenium简单使用
    数据解析模块BeautifulSoup简单使用
    爬虫简介
    SQLAlchemy简介
    Flask Blueprint
    Flask基于websocket的简单聊天室
    Flask send_file request
    初识Flask
    Python pip简单使用
  • 原文地址:https://www.cnblogs.com/zrtqsk/p/3622685.html
Copyright © 2020-2023  润新知