23种设计模式[3]:抽象工厂模式

一、简单工厂模式(静态工厂方法,不属于23种GOF设计模式之一)

定义:定义一个用于创建产品对象的方法,由该工厂类根据传入的参数,动态决定应该创建哪一个产品类(这些产品类继承自一个父类或接口)的实例。

类型:创建类模式

public interface SmsService {
    void sendSms();
}

public class MontnetsService implements SmsService {
    @Override
    public void sendSms() {
        System.out.println("通过梦网发送!");
    }
}

public class EtonenetSmsService implements SmsService {
    @Override
    public void sendSms() {
        System.out.println("通过移通发送!");
    }
}

public class SmsServiceFactory {

    public static SmsService getSmsService(int providerId) {
        SmsService ss;

        switch (providerId) {
            case 0:
                ss = new MontnetsService();
                break;
            case 1:
                ss = new EtonenetSmsService();
                break;
            default:
                ss = new EtonenetSmsService();
        }

        return ss;
    }

    public static void main(String[] args) {
        SmsService ss = SmsServiceFactory.getSmsService(0);
        //发送短信
        ss.sendSms();
    }
}

二、工厂方法模式

定义:定义一个用于创建产品对象的接口,由子类决定实例化哪一个类,工厂方法使一个类的实例化延迟到其子类。

类型:创建类模式

类图:

工厂方法模式代码:

public interface SmsService {
    void sendSms();
}

//工厂接口
public interface SmsServiceFactory {
    SmsService getSmsService(int providerId);
}

public class MontnetsService implements SmsService {
    @Override
    public void sendSms() {
        System.out.println("通过梦网发送!");
    }
}

public class EtonenetSmsService implements SmsService {
    @Override
    public void sendSms() {
        System.out.println("通过移通发送!");
    }
}

/**
 * 工厂实现类
 */
public class SmsServiceFactoryImpl implements SmsServiceFactory{

    @Override
    public SmsService getSmsService(int providerId) {
        SmsService ss;

        switch (providerId) {
            case 0:
                ss = new MontnetsService();
                break;
            case 1:
                ss = new EtonenetSmsService();
                break;
            default:
                ss = new EtonenetSmsService();
        }

        return ss;
    }

    public static void main(String[] args) {
     //向上转型为工程接口
        SmsServiceFactory ssf = new SmsServiceFactoryImpl();
        SmsService ss = ssf.getSmsService(0);
        //发送短信
        ss.sendSms();
    }
}

工厂方法模式:

  通过工厂方法模式的类图可以看到,工厂方法模式有四个要素:

  • 工厂接口。工厂接口是工厂方法模式的核心,与调用者直接交互用来提供产品。在实际编程中,有时候也会使用一个抽象类来作为与调用者交互的接口,其本质上是一样的。
  • 工厂实现。在编程中,工厂实现决定如何实例化产品,是实现扩展的途径,需要有多少种产品,就需要有多少个具体的工厂实现。
  • 产品接口。产品接口的主要目的是定义产品的规范,所有的产品实现都必须遵循产品接口定义的规范。产品接口是调用者最为关心的,产品接口定义的优劣直接决定了调用者代码的稳定性。同样,产品接口也可以用抽象类来代替,但要注意最好不要违反里氏替换原则。
  • 产品实现。实现产品接口的具体类,决定了产品在客户端中的具体行为。

  上文提到的简单工厂模式跟工厂方法模式极为相似,区别是:简单工厂只有三个要素,他没有工厂接口,并且得到产品的方法一般是静态的(红色注释部分)。因为没有工厂接口,所以在工厂实现的扩展性方面稍弱,可以算所工厂方法模式的简化版。

三、抽象工厂模式

定义:为创建一组相关或相互依赖的对象提供一个接口,而且无需指定他们的具体类。

类型:创建类模式

类图:

抽象工厂模式代码:

public interface SmsService {
    void sendMsg();
}

public interface NoticeService {
    void sendMsg();
}

public interface MsgServiceFactory {
    SmsService getSmsService();

    SmsService getNoticeService();
}

public class MontnetsService implements SmsService {
    @Override
    public void sendSms() {
        System.out.println("通过梦网发送!");
    }
}

public class EtonenetSmsService implements SmsService {
    @Override
    public void sendMsg() {
        System.out.println("通过移通发送!");
    }
}

public class ApnsService implements NoticeService {
    @Override
    public void sendMsg() {
        System.out.println("通过APNS发送!");
    }
}

public class JpushService implements NoticeService {
    @Override
    public void sendMsg() {
        System.out.println("通过极光发送!");
    }
}

/**
 * 抽象工厂实现类1
 */
public class MsgServiceFactoryImpl implements MsgServiceFactory{

    @Override
    public SmsService getSmsService() {
        return new MontnetsService();
    }

    @Override
    public NoticeService getNoticeService() {
        return new ApnsService();
    }

    public static void main(String[] args) {
     //向上转型为工程接口
        SmsServiceFactory ssf = new SmsServiceFactoryImpl();
        //发送消息通过短信,移通
        ssf.getSmsService().sendMsg();
        //发送消息通过App,APNS
        ssf.getNoticeService().sendMsg();
    }
}

/**
 * 抽象工厂实现类2
 */
public class MsgServiceFactoryImpl implements MsgServiceFactory{

    @Override
    public SmsService getSmsService() {
        return new EtonenetSmsService();
    }

    @Override
    public NoticeService getNoticeService() {
        return new JpushService();
    }

    public static void main(String[] args) {
     //向上转型为工程接口
        MsgServiceFactory ssf = new MsgServiceFactoryImpl();
        //发送消息通过短信
        ssf.getSmsService().sendMsg();
        //发送消息通过App
        ssf.getNoticeService().sendMsg();
    }
}

  抽象工厂模式是工厂方法模式的升级版本,抽象工厂模式除了具有工厂方法模式的优点外,最主要的优点就是可以在类的内部对产品族进行约束。所谓的产品族,一般或多或少的都存在一定的关联,抽象工厂模式就可以在类内部对产品族的关联关系进行定义和描述,而不必专门引入一个新的类来进行管理。

  在抽象工厂模式中,有一个产品族的概念:所谓的产品族,是指位于不同产品等级结构中功能相关联的产品组成的家族。抽象工厂模式所提供的一系列产品就组成一个产品族;而工厂方法提供的一系列产品称为一个等级结构。

  如上代码中,产品族有短信、App通知。我们要实现消息的下发,可以通过如下两大产品类达到消息下发的目的。实际开发中的代码比如上编写的更紧凑,会结合简单工厂、工厂方法、抽象工厂、反射等编写。

代码类似如下:

public interface SmsService {
    void sendMsg();
}

public interface NoticeService {
    void sendMsg();
}

public interface MsgServiceFactory {
    SmsService getSmsService();

    SmsService getSmsService(int providerId);

    SmsService getSmsService(String className);

    SmsService getNoticeService();

    SmsService getNoticeService(int providerId);

    SmsService getNoticeService(String className);
}

public class MontnetsService implements SmsService {
    @Override
    public void sendSms() {
        System.out.println("通过梦网发送!");
    }
}

public class EtonenetSmsService implements SmsService {
    @Override
    public void sendMsg() {
        System.out.println("通过移通发送!");
    }
}

public class ApnsService implements NoticeService {
    @Override
    public void sendMsg() {
        System.out.println("通过APNS发送!");
    }
}

public class JpushService implements NoticeService {
    @Override
    public void sendMsg() {
        System.out.println("通过极光发送!");
    }
}

/**
 * 抽象工厂实现类
 */
public class MsgServiceFactoryImpl implements MsgServiceFactory{

    @Override
    public SmsService getSmsService() {
        return new EtonenetSmsService();
    }

    @Override
    public SmsService getSmsService(int providerId) {
        SmsService ss;
        switch (providerId) {
            case 0:
                ss = new MontnetsService();
                break;
            case 1:
                ss = new EtonenetSmsService();
                break;
            default:
                ss = new EtonenetSmsService();
        }

        return ss;
    }

    @Override
    public SmsService getSmsService(String className) {
        //使用反射
        Class clazz = Class.forName(className);
        return (SmsService) clazz.newInstance();
    }

    @Override
    public SmsService getNoticeService() {
        return new ApnsService();
    }

    @Override
    public NoticeService getNoticeService(int providerId) {
        NoticeService ns;
        switch (providerId) {
            case 0:
                ns = new JpushService();
                break;
            case 1:
                ns = new ApnsService();
                break;
            default:
                ns = new ApnsService();
        }

        return ns;
    }

    @Override
    public NoticeService getNoticeService(String className) {
        //使用反射
        Class clazz = Class.forName(className);
        return (NoticeService) clazz.newInstance();
    }

    public static void main(String[] args) {
     //向上转型为工程接口
        SmsServiceFactory ssf = new SmsServiceFactoryImpl();
        //发送消息通过短信,移通
        ssf.getSmsService(0).sendMsg();
        //发送消息通过App,APNS
        ssf.getNoticeService(1).sendMsg();
    }
}

四、总结

  无论是简单工厂模式,工厂方法模式,还是抽象工厂模式,他们都属于工厂模式,在形式和特点上也是极为相似的,他们的最终目的都是为了解耦。在使用时,我们不必去在意这个模式到底工厂方法模式还是抽象工厂模式,因为他们之间的演变常常是令人琢磨不透的。经常你会发现,明明使用的工厂方法模式,当新需求来临,稍加修改,加入了一个新方法后,由于类中的产品构成了不同等级结构中的产品族,它就变成抽象工厂模式了;而对于抽象工厂模式,当减少一个方法使的提供的产品不再构成产品族之后,它就演变成了工厂方法模式。

  所以,在使用工厂模式时,只需要关心降低耦合度的目的是否达到了,不需要完全遵守各种模式的特点和约束来实现业务代码。

如写的不好,欢迎拍砖!

PS:

http://blog.csdn.net/zhengzhb/article/details/7359385

原文地址:https://www.cnblogs.com/phpdragon/p/8302710.html

时间: 2024-11-08 04:33:01

23种设计模式[3]:抽象工厂模式的相关文章

【Unity与23种设计模式】抽象工厂模式(Abstract Factory)

GoF中定义: "提供一个能够建立整个类群组或有关联的对象,而不必指明它们的具体类." 意思就是 根据不同的执行环境产生不同的抽象类子类 抽象工厂模式经常在面试中会涉及到 下面的例子为工厂1和工厂2 两个工厂都可以生成产品A和B 但是两个工厂工艺不同 所以工厂1只能生产产品A1和B1 工厂2只能生产产品A2和B2 //可生成各抽象成品对象的操作 public abstract class AbstractFactory{ public abstract AbstractProductA

23种设计模式之抽象工厂模式

抽象工厂模式(Abstract Factory):提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类. package designMode.abstractFactory; class User { private int id; private String name; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() {

23种设计模式(2)-简单工厂模式

这些设计模式都是在这么多年的软件开发中,先辈对软件重构的经验总结提炼的结果,这些设计模式要遵循软件设计的六原则.每一种设计模式都有相应的需求场景的.有了这些设计模式的思想和面向对象的思想,在软件设计特定的需求中会给你解决思路. 一,需求场景 在此,我也借用书上看到的一个例子.计算器工厂给我们留了一些任务,设计一个计算器做成成品卖给买家.但是这个任务是分两个阶段让我们实现的.如下: 阶段一:买家目前只需要计算器具有加减程序的功能即可.别的功能待市场需求再做设计.也就是阶段二的任务. 阶段二:阶段一

23种设计模式之抽象工厂

抽象工厂 当想创建一组密不可分的对象时,工厂方法似乎就不够用了 抽象工厂是应对产品族概念的.应对产品族概念而生,增加新的产品线很容易,但是无法增加新的产品.比如,每个汽车公司可能要同时生产轿车.货车.客车,那么每一个工厂都要有创建轿车.货车和客车的方法 优点:向客户端提供一个接口,使得客户端在不必指定产品具体类型的情况下,创建多个产品族中的产品对象 缺点:增加新的产品等级结构很复杂,需要修改抽象工厂和所有的具体工厂类,对“开闭原则”的支持呈现倾斜性 1 public interface IRac

二十四种设计模式:抽象工厂模式(Abstract Factory Pattern)

抽象工厂模式(Abstract Factory Pattern) 介绍提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类. 示例有Message和MessageModel,Message有一个Insert()方法,该方法的参数是MessageModel. AbstractMessageModel using System; using System.Collections.Generic; using System.Text; namespace Pattern.Abstract

23种设计模式之简单工厂模式

模式是基于在面对对象的思想上实现的计算机编程模式思维面对对象的模式思维有四大好处:可维护,可复用,可拓展,灵活性好基于三个步骤,封装,继承,多态举个例子:计算机要完成两个数字之间的运算一.就要考虑到定义一个可被继承类1.需要两个数的字段并且将之属性化2. 一个virtual的虚方法在每一个运算方法中都可以实现调用 二.要将运算的方法类继承,完成运算方法 三.创建工厂类,将根据运算符号来判断使用哪种运算类 四.在客户端中使用多态调用工厂类,输出结果就OK了 具体代码如下: 原文地址:https:/

重头开始学23种设计模式:三大工厂(简单工厂,工厂方法,抽象工厂)

在开发当中我们经常会使用三个设计模式,来帮我们解决项目代码的可扩展性. 在简单工厂,工厂方法,抽象工厂这三个设计模式当中,代码其实都很简单,主要是要理解运用. 简单工厂: 简单工厂说白了,就是利用Switch根据传递的参数,进行实例化. 工厂方法: 工厂方法,为解决每次都去增加Swicth的简单工厂的升级.为每一个产品提供一个工厂类. 抽象工厂: 抽象工厂,我觉得也是对工厂方法的再次升级,工厂方法每次只能创作一个产品,而抽象工厂就是产品线的产品族. 总结下,从网上找到一个大牛的回复: 我认为不能

设计模式之抽象工厂模式20170803

创建型设计模式之抽象工厂模式: 一.含义 为创建一组相关或相互依赖的对象提供一个接口,而且无需指定它们的具体类. 具体来说, 为一组具有相同约束(属性)的对象,提供一个接口,这个接口下有不同的实现,每个实现类对应一种类型的约束(一种具体的属性),同时提供该类型的约束(属性)下所有对象的创建方法 二.代码说明 1.主要有两个角色 1)一组互相影响的产品线(对象),也叫做产品族 2)抽象工厂类及其实现类 抽象工厂类:在N个产品族中,在抽象工厂类中就应该有N个创建方法 实现类:具体实现类是产品族的具体

Java经典23种设计模式之结构型模式(三)------附代理模式、适配器模式、外观模式区别

本文介绍7种结构型模式里的剩下两种:享元模式.代理模式. 一.享元模式FlyWeight 享元模式比较简单且重要,在很多场合都被用到,只不过封装起来了用户看不到.其概念:运用共享内存技术最大限度的支持大量细粒度的对象.这个概念给的有些抽象,说白了就是如果内存中存在某个对象A,如果再次需要使用对象A的时候如果内存中有A这个对象就直接使用它,不要再次new了.如果没有,则重新new一个.基于这个特点,享元模式使用时一般会给待访问对象传递一个Tag,用来标识这个对象,而且要同时使用抽象工厂的方法进行访

C#设计模式之三抽象工厂模式(AbstractFactory)【创建型】

原文:C#设计模式之三抽象工厂模式(AbstractFactory)[创建型] 一.引言 写了3篇有关设计模式的文章了,大家有了些反馈,说能从中学到一些东西,我感到很欣慰,那就继续努力.今天我要写第四个模式了,该模式叫抽象工厂.上一篇文章我们讲了[工厂方法]模式,它是为了解决[简单工厂]模式所面对的问题,它的问题就是:如果我们增加新的产品,工厂类的方法就要修改本身的代码,增加产品越多,其逻辑越复杂,同时这样的修改也是不符合[开放关闭原则OCP],对修改代码关闭,对增加代码开放.为了解决[简单工厂