文档章节

设计模式之工厂设计模式

Skqing
 Skqing
发布于 2017/03/31 17:14
字数 935
阅读 26
收藏 1

下面我从分析问题的角度,谈谈用工厂类的设计模式

第 1 个问题:我们经常一些功能类似的类,所以我们的思路是对进行抽象,使用接口暴露公共的方法,使用抽象类来提供公共的实现。

public interface IProduct {
    void print(); // 这是要暴露的方法
}

public abstract class AbstractProduct implements IProduct {
    protected void printBefore(){
        System.out.println("before print"); // 这里所公共的实现
    }
}

public class AProduct extends AbstractProduct {
    private String name;
    public AProduct(String name){ 
        this.name = name;
    }
    @Override
    public void print() {
        this.printBefore();
        System.out.println("print A >>>"+name);
    }
}

public class BProduct extends AbstractProduct {
    private String name;
    public BProduct(String name){ 
        this.name = name;
    }
    @Override
    public void print() {
        this.printBefore();
        System.out.println("print B >>>"+name);
    }
}


第 2 个问题:这些功能类似的类的实例化成为了一个问题,每个类的构造方法参数还不一样,每次 new 对象很麻烦,封装成简单工厂模式

public class SimpleFactory {
    public static IProduct getProduct(String name){
        if("A".equals(name)){
            return new AProduct(name);
        }else if("B".equals(name)){
            return new BProduct(name);
        }else{
            throw new IllegalArgumentException();
        }
    }
}

第 3 个问题:简单工厂模式不利于拓展,违背了**开闭原则**,每次添加一个类,都要修改工厂类(如果是工厂类和业务类是两个小伙伴分开写的,那不是要花很多时间来沟通...),所以就有工厂方法模式,其原理就是对简单工厂也进行抽象。

public interface IFactory {
    IProduct getProduct();
}

public class AFactory implements IFactory {
    @Override
    public IProduct getProduct() {
        return new AProduct(AProduct.class.getName());
    }
}

public class BFactory implements IFactory {
    @Override
    public IProduct getProduct() {
        return new BProduct(BProduct.class.getName());
    }
}

 

第 4 个问题:突然发现有些糟糕了,因为代码变得很多了,因为功能类似的产品我们进行 3 层抽象,针对每个产品我们还抽象出了 2 层的工厂类。但是我们在某个具体的业务场景中,不单单是只实例化一个类啊。举一个例子,在游戏中,我们要一个战士配装备,首先我们需要配一把枪械(枪械有很多,步枪,狙击枪等,使用问题 1 进行抽象),但是配了枪械之后,我们还需要配子弹啊(继续使用问题 1 的方法进行抽象),好了,现在可以抽象出 2 层的工厂类了,针对现在的情况我们是不是可以让一个工厂既生产枪械,又生产子弹呢? 这就是抽象工厂模式。简单来说,可以把有一些有联系或者相近的产品,放到一个工厂去生产,没有必要单独再开一个工厂了

下面举一个具体的案例来说,来说明工厂方法的应用吧

我们都知道 Java 的泛型是采用类型擦除来实现的(在 javac 编译过程的中把泛型去掉,加上强制类型转换)。所以我们不能直接 new T()来实例化一个对象。其实可以采用工厂方法模式设计模式来解决。

假设我们有一个类,里面要用到了泛型的实例化。

public class Foo<T>(){
    private T t;
    public Foo(){
       t = new T(); // 这个代码是有问题的,我们使用工厂设计模式进行改进
    }
}

我们给出工厂接口如下:

public interface IFactory<T>(){
   T create();
}


 

进而我们可以采用如下的方法进行改进

public class Foo<T>(){
    private T t;
    public <F extends IFactory<T>> Foo(F factory){
        // t = new T(); 
        factory.create();       
    }
}


这个时候,我们可以采用如下的方式实例化 Foo

    new Foo(new Ifactory<Integer>(){
        Integer create(){
            return new Integer(0);
        }
    });

    new Foo(new Ifactory<String>(){
        String create(){
            return "Hello";
        }
    });

作者:郭小成
链接:https://www.zhihu.com/question/24843188/answer/110361396
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

本文转载自:https://www.zhihu.com/question/24843188/answer/110361396

上一篇: Redis学习文档
下一篇: Log4j 2使用教程
Skqing

Skqing

粉丝 39
博文 206
码字总数 26375
作品 0
深圳
后端工程师
私信 提问
设计模式梳理(一)

设计模式梳理(一) 总体来说设计模式分为三大类: @案例源码地址:https://gitlab.com/lxqxsyu/DisgnPattern 创建型模式 简单工厂模式 工厂类是整个模式的关键。它包含必要的判断逻辑,能够...

lxq_xsyu
2017/11/02
0
0
PHP设计模式(一):简介及创建型模式

我们分三篇文章来总结一下设计模式在PHP中的应用,这是第一篇创建型模式。 一、设计模式简介 首先我们来认识一下什么是设计模式: 设计模式是一套被反复使用、容易被他人理解的、可靠的代码设...

juhenj
2014/05/15
282
2
设计模式之抽象工厂模式(创建型)

模式定义 抽象工厂模式(Abstract Factory Pattern):提供一个创建一系列相关或相互依赖对象的接口,而无须指定它们具体的类。抽象工厂模式又称为Kit模式,属于对象创建型模式。 模式角色 抽象...

smileNicky
01/01
0
0
设计模式Java Design Pattern-工厂方法模式FactoryMethod

我的博客 一、 设计模式的分类 大体可以分为三类: 创建型模式(5个) 单例模式、原型模式、工厂方法模式、抽象工厂模式、建造者模式 结构性模式(7个) 适配器模式、装饰器模式、代理模式、...

勇敢写信
2018/03/22
0
0
Design Patterns In FE --- 工厂模式

示例代码地址: github.com/FatGe/Desig… 工厂模式 工厂,是构造方法的抽象,用来实现不同的分配方案。它所涉及三类模式,简单工厂模式、工厂方法模式、抽象工厂模式本质上都是为了实例化。...

Yzz
08/06
0
0

没有更多内容

加载失败,请刷新页面

加载更多

当阿里云工程师回到了家乡......

根据真实故事改编 略有浮夸 但重要的是 9月25日13:30-16:30 云栖大会「5G边缘计算专场」 一定要来哦 !!! 本文作者:樰篱 原文链接 本文为云栖社区原创内容,未经允许不得转载。...

Mr_zebra
10分钟前
2
0
文件操作工具类 FileUtils常用方法

文件操作工具类(FileUtils) 使用该工具类的前提是项目里导入commons-io 包 import org.apache.commons.io.FileUtils; List<String> lines=new ArrayList<String>(); lines.add("欢迎访问:......

AndLong
17分钟前
2
0
maven-shade-plugin

最近,用规则引擎(drools)的封装了一个jar包,给别人使用。用的是maven-assembly-plugin打的包,可以把多个jar包里的class 给打成一个jar,感觉还是满好用的,但是打包成功后,发现报空指针错...

internetafei
22分钟前
2
0
Cassandra repair 工具使用

前言 Cassandra是一款去中心化的分布式数据库。一份数据会分布在多个对等的节点上,即有多个副本。我们需要定期的对多个副本检查,看是否有不一致的情况。比如因为磁盘损坏,可能会导致副本丢...

阿里云官方博客
25分钟前
1
0
element-vue使用富文本编辑器【前端】

一、前言 1.富文本编辑器选择的为vue-quill-editor 官方地址:https://quilljs.com/docs/quickstart/ 2.安装 cnpm install vue-quill-editor cnpm install quill 3.在对应的页面引入,在com...

一代码农码一代
30分钟前
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部