设计模式知识点整理-工厂模式

在Java语言中,我们通常有以下几种创建对象的方式:

(1) 使用new关键字直接创建对象;

(2) 通过反射机制创建对象;

(3) 通过clone()方法创建对象;

(4) 通过工厂类创建对象(其实本质也是通过new关键字或者反射的方式创建实例对象)


为什么要用工厂模式

(1) 解耦 :把对象的创建和使用的过程分开。就是Class A 想调用 Class B ,那么A只是调用B的方法,而至于B的实例化,就交给工厂类。

(2)降低代码重复: 如果创建某个对象的过程都很复杂,需要一定的代码量,而且很多地方都要用到,那么就会有很多的重复代码。

(3) 降低维护成本 :由于创建过程都由工厂统一管理,所以发生业务逻辑变化,不需要找到所有需要创建对象B的地方去逐个修正,只需要在工厂里修改即可,降低维护成本。


工厂模式可以分为三类

(1) 简单工厂模式(Simple Factory)

(2)工厂方法模式(Factory Method)

(3)抽象工厂模式(Abstract Factory)


 这三种模式从上到下逐步抽象,并且更具一般性。 GOF在《设计模式》一书中将工厂模式分为两类:工厂方法模式(Factory

Method)与抽象工厂模式(Abstract Factory)。将简单工厂模式(Simple Factory)看为工厂方法模式的一种特例,两者归为一类。


简单工厂模式

简单工厂模中的角色

工厂(Factory)角色 :简单工厂模式的核心,它负责实现创建所有实例的内部逻辑。工厂类可以被外界直接调用,创建所需的产品对象。

抽象产品(Product)角色:简单工厂模式所创建的所有对象的父类,它负责描述所有实例所共有的公共接口。

具体产品(Concrete Product)角色:简单工厂模式的创建目标,所有创建的对象都是充当这个角色的某个具体类的实例。


简单工厂示例

设计一个手机工厂,这个手机工厂可以同时生产华为手机、小米手机


抽象产品角色-手机接口

public interface Mobile {

public void createMobile();

}


具体产品角色-华为手机类

public class Huawei implements Mobile {

@Override

public void createMobile() {

System.out.println("生产华为手机");

}

}

具体产品角色-小米手机类

public class Xiaomi implements Mobile {

@Override

public void createMobile() {

System.out.println("生产小米手机");

}

}


工厂角色

public class MobileFactory {

public Mobile cretaeMobie(String type){

switch(type){

case "huawei":

return new Huawei();

case "xiaomi":

return new Xiaomi();

default:

break;

}

return null;

}

}


测试类

public class Customer {

public static void main(String[]

args) {

MobileFactory mobileFactory = new

MobileFactory();

Mobile huaweiMobile =

mobileFactory.cretaeMobie("huawei");

huaweiMobile.createMobile();

Mobile xiaomiMobile =

mobileFactory.cretaeMobie("xiaomi");

xiaomiMobile.createMobile();

}

}

简单工厂模式只有一个统一的工厂类,当新增一个类时,要在工厂类中增加相应的创建业务逻辑,这显然是违背开闭原则的,我们可以使用工厂方法模式进行优化


工厂方法模式

工厂方法模式中的角色

抽象工厂(Abstract Factory)角色:是工厂方法模式的核心,与应用程序无关。任何在模式中创建的对象的工厂类必须实现这个接口。

具体工厂(Concrete Factory)角色 :这是实现抽象工厂接口的具体工厂类,包含与应用程序密切相关的逻辑,并且受到应用程序调用以创建某一种产品对象。

抽象产品(AbstractProduct)角色 :工厂方法模式所创建的对象的超类型,也就是产品对象的共同父类或共同拥有的接口。

具体产品(Concrete Product)角色 :这个角色实现了抽象产品角色所定义的接口。某具体产品有专门的具体工厂创建,它们之间往往一一对应


工厂方法模式示例

设计一个华为手机工厂,一个小米手机工厂,分别用来生产华为手机和小米手机


抽象产品角色

public interface Mobile {

public void createMobile();

}


具体产品角色-华为手机类

public class Huawei implements Mobile {

@Override

public void createMobile() {

System.out.println("生产华为手机");

}

}

具体产品角色-小米手机类

public class Xiaomi implements Mobile {

@Override

public void createMobile() {

System.out.println("生产小米手机");

}

}


抽象工厂角色

public interface AbstractFactory {

public Mobile createMobile();

}


具体工厂角色-华为手机工厂

public class HuaweiFactory implements AbstractFactory{

@Override

public Mobile createMobile() {

return new Huawei();

}

}

具体工厂角色-小米手机工厂

public class XiaomiFactory implements AbstractFactory{

@Override

public Mobile createMobile() {

return new Xiaomi();

}

}


测试方法

public class Customer {

public static void main(String[] args) {

HuaweiFactory huaweiFactory = new HuaweiFactory();

Mobile huawei = huaweiFactory.createMobile();

huawei.createMobile();


XiaomiFactory xiaomiFactory = new XiaomiFactory();

Mobile xiaomi = xiaomiFactory.createMobile();

xiaomi.createMobile();

}

}



在工厂方法模式中,我们使用某个工厂生产同一类产品,当产品种类非常多时,会出现大量的与之对应的工厂对象,这不是我们所希望的。抽象工厂模式是工厂方法的仅一步深化,在这个模式中的工厂类不单单可以创建一种产品,而是可以创建一组产品


抽象工厂模式

抽象工厂模式中的角色

抽象工厂(AbstractFactory)角色 :是工厂方法模式的核心,与应用程序无关。任何在模式中创建的对象的工厂类必须实现这个接口。

具体工厂类(ConreteFactory)角色 :这是实现抽象工厂接口的具体工厂类,包含与应用程序密切相关的逻辑,并且受到应用程序调用以创建某一种产品对象。

抽象产品(Abstract Product)角色 :工厂方法模式所创建的对象的超类型,也就是产品对象的共同父类或共同拥有的接口。

具体产品(Concrete Product)角色 :抽象工厂模式所创建的任何产品对象都是某一个具体产品类的实例。在抽象工厂中创建的产品属于同一产品族。


抽象工厂模式是工厂方法的仅一步深化,在这个模式中的工厂类不单单可以创建一个对象,而是可以创建一组对象。这是和工厂方法最大的不同点。


抽象工厂模式实例

设计工厂用来生产华为手机和小米手机,华为手机跟小米手机由不同的cpu和不同屏幕组成


抽象产品角色-cpu接口

public interface Cpu {

public void createCpu();

}


具体产品角色-麒麟cpu

public class KirinCpu implements Cpu {

@Override

public void createCpu() {

System.out.println("生产麒麟cpu");

}

}


具体产品角色-骁龙cpu

public class SnapdragonCpu implements Cpu {

@Override

public void createCpu() {

System.out.println("生产骁龙cpu");

}

}


抽象产品角色-屏幕接口

public interface Screen {

public void createScreen();

}


具体产品角色-三星屏幕

public class SamsungScreen implements Screen {

@Override

public void createScreen() {

System.out.println("生产三星屏幕");

}

}


具体产品角色-LG屏幕

public class LGScreen implements Screen{

@Override

public void createScreen() {

System.out.println("生产LG屏幕");

}

}


抽象工厂角色

public interface AbstractFactory {

public Cpu createCpu();

public Screen createScreen();

}


具体工厂角色-华为手机工厂

public class HuaweiFactory implements AbstractFactory{


@Override

public Cpu createCpu() {

return new KirinCpu();

}


@Override

public Screen createScreen() {

return new LGScreen();

}

}


具体工厂角色-小米手机工厂

public class XiaomiFactory implements AbstractFactory{

@Override

public Cpu createCpu() {

return new SnapdragonCpu();

}


@Override

public Screen createScreen() {

return new SamsungScreen();

}

}


测试类

public class Customer {

public static void main(String[] args) {

HuaweiFactory huaweiFactory = new HuaweiFactory();

Cpu huaweiCpu = huaweiFactory.createCpu();

huaweiCpu.createCpu();

Screen huaweiScreen = huaweiFactory.createScreen();

huaweiScreen.createScreen();


XiaomiFactory xiaomiFactory = new XiaomiFactory();

Cpu xiaomiCpu = xiaomiFactory.createCpu();

xiaomiCpu.createCpu();

Screen xiaomiScreen = xiaomiFactory.createScreen();

xiaomiScreen.createScreen();

}

}


抽象工厂的工厂和工厂方法的区别:

厂方法模式中的工厂只生产单一的产品,而抽象工厂模式中的工厂生产多个产品,工厂方法模式的具体工厂类只能创建一个具体产品类的实例,而抽象工厂模式可以创建多个。


工厂模式适用的一些场景

(1)对象的创建过程/实例化准备工作很复杂,需要初始化很多参数、查询数据库等。

(2)类本身有好多子类,这些类的创建过程在业务中容易发生改变,或者对类的调用容易发生改变。

(3)客户端不需要知道它所创建的对象的类,只知道创建它的工厂名就完成了创建过程。

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

推荐阅读更多精彩内容