Java设计模式——工厂模式

工厂模式

简单工厂模式
工厂方法模式
抽象工厂模式

1.简单工厂模式

1.基本介绍

1)简单工厂模式也叫静态工厂模式,是属于创建型模式,是工厂模式的一种,简单工厂模式是由一个工厂对象决定创建哪一种产品类的实例。简单工厂模式是工厂模式种最简单实用的模式。
2)简单工厂模式:定义了一个创建对象的类,由这个类来封装实例化对象的行为
3)在软件开发中,当我们会用到大量的创建某种、某类或者某批对象时,就会使用到工厂模式.

2.解决的问题

将"类实例化的操作"与''使用对象的操作"分开,让使用者不需要知道具体参数就可以实例化出所需要的''产品''类,从而避免了在客户段种显示指定,实现了解耦,即使用者可以直接消费产品而不需要知道其生产的细节。

3.模式的组成

抽象产品(Product):描述产品的公共接口,是具体产品的父类。
具体产品(ConcreteProduct):描述生产的具体产品,抽象产品的子类,工厂类创建的目标类。
工厂(Factory):根据传入不同的参数从而创建不同具体产品类的实例,被外界调用。

4.使用步骤

  • 创建抽象产品类&定义具体产品的公共接口;
  • 创建具体产品类(继承抽象产品类),定义生产的具体产品;
  • 创建工厂类,通过创建静态方法更具传入不同参数从而创建不同具体产品类的实例。
  • 外界通过调用工厂类的静态方法,传入不同参数从而创建不同具体产品类的实例。

5.优点

  • 将创建实例的工作与使用实例的工作分开,使用者不必关心类对象如何创建,实现了解耦。
  • 把初始化实列时的工作放到工厂里进行,是代码更容易维护。更符合面向对象的原则。

5.缺点

  • 工厂类集中了所有实例(产品)的创建逻辑,一旦这个工厂不能正常工作,整个系统都会受到影响。
  • 违背”开发封闭原则“,一旦添加新产品就不得不修改工厂类的逻辑,这样就会造成工厂逻辑过于复杂。
  • 简单工厂模式由于使用了静态工厂方法,静态方法不能被继承和重写,会造成工厂角色无法形成基于继承的等级结构。

6.示例
目的:奶茶店有三种奶茶原味,珍珠和红豆,老板希望使用简单工厂模式生产这>三种奶茶。

代码:

public class SampleFactoryPattern {

    public static void main(String[] args) {
        Factor.makeProduct("红豆").make();;
        Factor.makeProduct("珍珠").make();;
        Factor.makeProduct("原味").make();;
    }

}
//1.创建抽象产品类,定义具体用户点单的公共接口
interface Product{
    public void make();
}
//2.创建具体产品类(实现接口),定义生产的具体产品
class ProductPlain implements Product{
    //原味奶茶
    @Override
    public void make() {
        System.out.println("生产了原味奶茶");
    }
}
class ProductPearl implements Product{
    //珍珠奶茶
    @Override
    public void make() {
        System.out.println("生产了珍珠奶茶");
    }
}
class ProductRedBeans implements Product{
    //红豆奶茶
    @Override
    public void make() {
        System.out.println("生产了红豆奶茶");
    }
}

//3.创建工厂类,通过创建静态方法从而根据传入不同参数创建不同具体产品类的实例。
class Factor{
    public static Product makeProduct(String name) {
        switch(name) {
        case "原味":
            return new ProductPlain();
        case "珍珠":
            return new ProductPearl();
        case "红豆":
            return new ProductRedBeans();
        default:
            return null;
        }
    }
}

截图:


image.png
2.工厂方法模式

1.基本介绍

工厂方法模式:定义了一个创建对象的抽象方法,由子类决定要实例化的类。工厂方法模式将对象的实例化推迟到子类。

2.主要作用

将类的实例化(具体产品的创建)延迟到工厂类的子类(具体工厂)种完成,即由子类决定应用实例(创建)哪一个类。

3.解决的问题

简单工厂模式的缺点,工厂一旦创建需要生产新产品就需要修改工厂类的方法逻辑,违背了"开放封闭原则"。
之所以可以解决简单工厂的问题,是因为工厂方法模式把具体产品的创建推出到工厂类的子类(具体工厂)中,此时工厂类不再负责所有产品的创建,而是给出具体工厂必须实现的接口,这样工厂方法模式再添加新产品的时候就不修改工厂类逻辑而是添加新的工厂子类,符合开放封闭原则,克服了简单工厂模式中的缺点。

4.模式的组成

抽象产品(Product):描述产品的公共接口,是具体产品的父类。
具体产品(ConcreteProduct):描述生产的具体产品,抽象产品的子类,工厂类创建的目标类,描述的具体产品。
抽象工厂(Factory):描述具体工厂的公共接口,具体工厂的父类。
具体工厂(ConcreteCreator):实现FactoryMethod工厂方法创建产品的实例,抽象工厂的子类,被外界调用。

5.使用步骤

1.创建抽象工厂类,定义具体工厂的公共接口;
2.创建抽象产品类,定义具体产品的公共接口
3.创建具体产品类(继承抽象产品类或者实现接口),定义生产的具体产品;
4.创建具体工厂类(继承抽象工厂类或者实现接口),定义创建对应具体产品实例的方法。
5.外界通过调用具体工厂类的放,从而创建不同具体产品类的实例。

6.优点

更符合开放封闭原则,新增一种产品时,只需要增加相应的具体产品类和相应的工厂子类即可,无需修改。
符合单一职责原则,每个具体工厂类只负责创建对应的产品。
不使用静态工厂方法,可以形成基本继承的等级结构。
工厂模式可以说时简单工厂模式的进一步抽象和拓展,在保留了简单工厂封装的优点的同时,让扩展变得更加简单,让继承变得可行,增加了多态性得体现。

7.缺点

添加新产品时,除了增加新产品类外,还要提供与之对应的具体工厂类,系统类的个数将成对增加,在一定程度上增加了系统的复杂度;同时,有更多的类需要编译和运行,会给系统带来一些额外的开销;
·由于考虑到系统的可扩展性,需要引入抽象层,在客户端代码中均使用抽象层进行定义,增加了系统的抽象性和理解难度,且在实现时可能需要用到DOM、反射等技术,增加了系统的实现难度。
·虽然保证了工厂方法内的对修改关闭,但对于使用工厂方法的类,如果要更换另外一种产品,仍然需要修改实例化的具体工厂类;
·一个具体工厂只能创建一种具体产品

8.示例
有一间工厂(仅生产A类产品),随着客户需求的变化,可户需要生产B类产品。
·冲突:改变原有塑料加工厂的配置和变化非常困难,假设下一次客户需要再发生变化,再次改变将增大非常大的成本;
·解决方案:小成决定置办塑料分厂B来生产B类产品;

代码:

public class MethodFactory {

    public static void main(String[] args) {
        FactoryA factoryA=new FactoryA();
        factoryA.manufacture().make();
        FactoryB factoryB=new FactoryB();
        factoryB.manufacture().make();
    }

}

//1.创建抽象工厂类,定义具体工厂的公共接口;
abstract class AbstractFactory{
    public abstract Product manufacture();
}

//2.创建抽象产品类,定义具体产品的公共接口
abstract class Product{
    public abstract void make();
}
//3.创建具体产品类(继承抽象产品类或者实现接口)&定义生产的具体产品;
class ProductA extends Product{
    //具体产品A类
    @Override
    public void make() {
        System.out.println("生产了A类产品");
    }
    
}
class ProductB extends Product{
    //具体产品B类
    @Override
    public void make() {
        System.out.println("生产了B类产品");
    }
    
}
//4.创建具体工厂类(继承抽象工厂类或者实现接口),定义创建对应具体产品实例的方法。
class FactoryA extends AbstractFactory{
    //A工厂
    @Override
    public Product manufacture() {
        
        return new ProductA();
    }
    
}
class FactoryB extends AbstractFactory{
    //B工厂
    @Override
    public Product manufacture() {
        
        return new ProductB();
    }
    
}

结果:


image.png
3.抽象工厂模式

1.基本介绍

1)抽象工厂模式:定义了一个 interface 用于创建相关或有依赖关系的对象簇,而无需指明具体的类
2)抽象工厂模式可以将简单工厂模式和工厂方法模式进行整合。
3)从设计层面看,抽象工厂模式就是对简单工厂模式的改进(或者称为进一步的抽象)。
4)将工厂抽象成两层,AbsFactory(抽象工厂) 和 具体实现的工厂子类。程序员可以根据创建对象类型使用对应的工厂子类。这样将单个的简单工厂类变成了工厂簇,更利于代码的维护和扩展。
4)工厂方法模式中一个具体工厂只能创建一类产品,而实际过程中,一个工厂往往需要生产多类产品。为解决这类问题,引入抽象工厂模式。
2.主要作用
允许使用抽象得接口来创建一组相关产品,而不需要知道或关心实际生产出得具体产品是什么,这样就可以从具体产品中被解耦。

3.解决得问题

工厂方法模式得缺点

4.模式的组成

抽象产品簇(AbastractProduct):描述抽象产品得公共接口,抽象产品得父类
抽象产品(Product):描述产品的公共接口,是具体产品的父类。
具体产品(ConcreteProduct):描述生产的具体产品,抽象产品的子类,工厂类创建的目标类,描述的具体产品。
抽象工厂(Factory):描述具体工厂的公共接口,具体工厂的父类。
具体工厂(ConcreteCreator):实现FactoryMethod工厂方法创建产品的实例,抽象工厂的子类,被外界调用。

5.使用步骤

1.创建抽象工厂类,定义具体工厂的公共接口;
2.创建抽象产品簇类,定义抽象产品的公共接口;
3.创建抽象产品类(继承抽象产品簇类或者实现接口),定义具体产品的公共接口;
4.创建具体产品类(继承抽象产品类或者实现接口),定义生产的具体产品。
5.创建具体工厂类(继承抽象工厂类或者接口),定义创建对应具体产品实例的方法。
6.客户端通过实例化具体的工厂类,并调用其创建不同目标产品的方法创建不同具体产品类的实例。

6.优点

降低耦合:抽象工厂模式将具体产品的创建延迟到具体工厂的子类中,这样将对象的创建封装起来,可以减少客户端与具体产品类之间的依赖,从而使系统耦合度降低,这样更有利于后期的维护和扩展。
跟符合开放闭合原则:新增一种产品类时,只需要增加相应的具体产品代码和相应的工厂子类即可。
符合单一职责原则:每个具体工厂类只负责创建对应的产品
不使用静态工厂方法,可以形成基于继续的等级结构。

7.缺点

抽象工厂模式很难支持新种类产品的变化。这是因为抽象工厂接口中已经确定了可以被创建的产品集合,如果需要添加新产品,此时必须去修改抽象工厂的接口,这样就涉及到抽象工厂类的以及所有子类的改变,这样也就违背了开放封闭原则。

8.示例

·背景:小成有两间塑料加工厂(A厂仅生产容器类产品;B厂仅生产模具类产品);随着客户需求的变化,A厂所在地的客户需要也模具类产品,B厂所在地的客户也需要容器类产品;
冲突:没有资源(资金+租位)在当地分别开设多一家注塑分厂
解决方案:在原有的两家塑料厂里增设生产需求的功能,即A厂能生产容器+模具产品;B厂间能生产模具+容器产品。

代码:

public class AbstractFactory {

    public static void main(String[] args) {
        //A厂
        FactoryA fA=new FactoryA();
        fA.manufactureContainer().make();
        fA.manufactureMould().make();
        
        //B厂
        FactoryB fB=new FactoryB();
        fB.manufactureContainer().make();
        fB.manufactureMould().make();
        

    }

}
//1.创建抽象工厂类,定义具体工厂的公共接口;
abstract class Factory{
    public abstract AbstractProduct manufactureContainer();
    public abstract AbstractProduct manufactureMould();
}
//2.创建抽象产品簇类,定义抽象产品的公共接口;
abstract class AbstractProduct{
    public abstract void make();
}
//3.创建抽象产品类(继承抽象产品簇类或者实现接口),定义具体产品的公共接口;
abstract class ContainerProduct extends AbstractProduct{
    //容器抽象类
    public abstract void make();
}
abstract class MouldProduct extends AbstractProduct{
    //模具抽象类
    public abstract void make();
}

//4.创建具体产品类(继承抽象产品类或者实现接口),定义生产的具体产品。
class ContainerProductA extends ContainerProduct{
    //容器产品A类
    @Override
    public void make() {
        System.out.println("生产出了容器产品A类");
    }
    
}
class ContainerProductB extends ContainerProduct{
    //容器产品B类
    @Override
    public void make() {
        System.out.println("生产出了容器产品B类");
    }
    
}
class MouldProductA extends MouldProduct{
    //模具产品A类
    @Override
    public void make() {
        System.out.println("生产出了模具产品A类");
    }
    
}
class MouldProductB extends MouldProduct{
    //模具产品B类
    @Override
    public void make() {
        System.out.println("生产出了模具产品B类");
    }
    
}
//5.创建具体工厂类(继承抽象工厂类或者接口),定义创建对应具体产品实例的方法。
class FactoryA extends Factory{
    //工厂A,生产模具和容器
    @Override
    public AbstractProduct manufactureContainer() {
        
        return new ContainerProductA();
    }

    @Override
    public AbstractProduct manufactureMould() {
        
        return new MouldProductA();
    }
    
}
class FactoryB extends Factory{
    //工厂B,生产模具和容器
    @Override
    public AbstractProduct manufactureContainer() {
        
        return new ContainerProductB();
    }

    @Override
    public AbstractProduct manufactureMould() {
        
        return new MouldProductB();
    }
    
}


截图:


image.png

emmmm 当看到大佬的博客的时候,为了以后复习和加深记忆,不知不觉又当上了博客搬运工,如果想看原文参考下方链接。


image.png

参考链接://www.greatytc.com/p/d0c444275827

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,039评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,426评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 165,417评论 0 356
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,868评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,892评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,692评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,416评论 3 419
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,326评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,782评论 1 316
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,957评论 3 337
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,102评论 1 350
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,790评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,442评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,996评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,113评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,332评论 3 373
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,044评论 2 355

推荐阅读更多精彩内容

  • 前言 最近在复习java设计模式中的工厂模式。本来有一点小小的理解。感觉都写的不错,就是有点太零散了,最后还是决定...
    斌林诚上阅读 18,751评论 3 25
  • 一、工厂模式简介 意图定义一个创建对象的接口,让其子类自己决定实例化哪一个工厂类,工厂模式使其创建过程延迟到子类进...
    怡红快绿阅读 603评论 0 0
  • 一、简单工厂 定义 简单工厂其实并不属于23种GOF设计模式之一,该模式是工厂方法模式的弱化(或者说是工厂方法模式...
    tianranll阅读 198评论 0 0
  • 一、工厂模式主要是为创建对象提供过渡接口,以便将创建对象的具体过程屏蔽隔离起来,达到提高灵活性的目的。 工厂模式在...
    李序锴阅读 559评论 0 0
  • 在java中,通常使用new操作符创建对象的实例。但是在一些情况下,new操作符直接生成对象会带来一些问题,例如:...
    步积阅读 864评论 2 3