美文网首页
设计模式之工厂模式

设计模式之工厂模式

作者: sssssss_ | 来源:发表于2020-01-31 00:22 被阅读0次

模式定义

  1. 简单工厂模式:专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类。
  2. 工厂方法模式:定义一个用于创建对象的接口,让子类决定实例化哪个类。
  3. 抽象工厂模式:定义一个接口用于创建相关或有依赖关系的对象族,而无需明确指定具体类。
工厂方法模式UML 抽象工厂UML

模式使用场景

  • 工厂方法模式
    1. 复杂对象的生成,代替new的方式来屏蔽产品类的创建过程:需要一种产品,而不想知道也不需要知道工厂是如何生产出来的,只需要知道具体对应的工厂就行。
    2. 产品的替换需要灵活、可扩展性高的场合。
    3. Android中的Bitmap就是通过工厂方法来创建的。
  • 抽象工厂模式
    1. 一个对象族有相同的约束时可以使用抽象工厂模式,例如生成不同操作系统的程序。

简单工厂模式

简单工厂.jpg
public abstract class Mouse {
    public abstract void sayHi();
}
public class DellMouse extends Mouse {
    @Override
    public void sayHi() {
        System.out.println("DellMouse - sayHi");
    }
}
public class HpMouse extends Mouse {
    @Override
    public void sayHi() {
        System.out.println("HpMouse - sayHi");
    }
}
public class MouseFactory {
    public Mouse createMouse(int i) {
        switch (i) {
            case 0:
                return new DellMouse();
            case 1:
                return new HpMouse();
        }
        return null;
    }
}
public class client {
    public static void main(String[] args) {
        MouseFactory mouseFactory = new MouseFactory();
        Mouse m = mouseFactory.createMouse(0);
        m.sayHi();
    }
}

工厂模式

工厂模式.jpg
// 省略 Mouse 、DellMouse、HpMouse 的代码

public abstract class MouseFactory {
    public abstract Mouse createMouse();
}
public class DellMouseFactory extends MouseFactory {
    @Override
    public Mouse createMouse() {
        return new DellMouse();
    }
}
public class HPMouseFarctrory extends MouseFactory {
    @Override
    public Mouse createMouse() {
        return new HpMouse();
    }
}
public class client {
    public static void main(String[] args) {
        HPMouseFarctrory hpf = new HPMouseFarctrory();
        Mouse mouse = hpf.createMouse();
        mouse.sayHi();
    }
}

抽象工厂模式

抽象工厂.jpg
// 省略 Mouse 、DellMouse、HpMouse 的代码

public abstract class Keyboard {
    public abstract void sayTara();
}
public class DellKeboard extends Keyboard {
    @Override
    public void sayTara() {
        System.out.println("DellKeboard - sayTara");
    }
}
public class HpKeyboard extends Keyboard {
    @Override
    public void sayTara() {
        System.out.println("HpKeyboard - sayTara");
    }
}
public abstract class PcFactory {
    public abstract Mouse createMouse();
    public abstract Keyboard createKeyboard();
}
public class DellFactory extends PcFactory {
    @Override
    public Mouse createMouse() {
        return new DellMouse();
    }
    @Override
    public Keyboard createKeyboard() {
        return new DellKeboard();
    }
}
public class HpFactory extends PcFactory {
    @Override
    public Mouse createMouse() {
        return new HpMouse();
    }
    @Override
    public Keyboard createKeyboard() {
        return new HpKeyboard();
    }
}
public class client {
    public static void main(String[] args) {
        HpFactory hp = new HpFactory();
        Mouse mouse = hp.createMouse();
        mouse.sayHi();
        Keyboard k = hp.createKeyboard();
        k.sayTara();
    }
}

在抽象工厂模式中,假设我们需要增加一个工厂

抽象工厂_产品结构增1.jpg

在抽象工厂模式中,假设我们需要增加一个产品

抽象工厂_产品族增1.jpg

在抽象工厂模式中,采用反射的方式进行

public class client {
    public static void main(String[] args) {
        PcFactory factory = new ConcreteFactory();
        Mouse m = factory.createMouse(DellMouse.class);
        Keyboard k = factory.createKeyboard(DellKeboard.class);
        m.sayHi();
        k.sayTara();
    }
}
public abstract class PcFactory {
    public abstract <T extends Mouse> T createMouse(Class<T> mcls);
    public abstract <K extends Keyboard> K createKeyboard(Class<K> kcls);
}
// 具体的工厂,动态传入
public class ConcreteFactory extends PcFactory {
    @Override
    public <T extends Mouse> T createMouse(Class<T> mcls) {
        Mouse mouse = null;
        try {
            mouse = (Mouse) Class.forName(mcls.getName()).newInstance();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return (T) mouse;
    }
    @Override
    public <K extends Keyboard> K createKeyboard(Class<K> kcls) {
        Keyboard keyboard = null;
        try {
            keyboard = (Keyboard) Class.forName(kcls.getName()).newInstance();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return (K) keyboard;
    }
}

依赖抽象原则:

  1. 变量不要持有具体类的引用;
  2. 不要让类继承自具体类,要继承自抽象类或接口;
  3. 不要覆盖基类中已实现的方法;

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

抽象工厂模式与工厂方法模式的最大区别就在于,工厂方法模式针对的是一个产品等级结构;而抽象工厂模式则需要面对多个产品等级结构

产品族和产品等级的概念

所谓产品族,是指位于不同产品等级结构中,功能相关联的产品组成的家族。比如AMD的主板、芯片组、CPU组成一个家族,Intel的主板、芯片组、CPU组成一个家族。而这两个家族都来自于三个产品等级:主板、芯片组、CPU。一个等级结构是由相同的结构的产品组成。

产品族和产品等级

模式优缺点

简单工厂模式

  • 优点1:使代码结构清晰;
  • 优点2:对调用者屏蔽具体的产品类;
  • 优点3:降低耦合度;
  • 缺点1:当需求变动的时候,需要对原有的类进行修改,违背了开放封闭原则。

工厂方法模式

  • 优点1:加入新产品符合开闭原则,提高可扩展性;(接口)
  • 缺点1:类的个数容易过多,增加复杂度;
  • 缺点2:增加了系统的抽象性和理解难度;

抽象方法模式

  • 优点1:分离接口与实现;
  • 优点2:在切换产品类时更灵活、容易;
  • 缺点1:类文件的爆炸性增加;
  • 缺点2:不太容易扩展新的产品类,因为增加一个产品类需要修改抽象工厂,那么所有的具体工厂均会被修改。(所以使用抽象工厂模式时,对产品等级结构的划分是非常重要的。)

总结

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

参考资料

相关文章

  • iOS设计模式(三)之抽象工厂模式

    设计模式系列传送门 iOS设计模式(一)之简单工厂模式iOS设计模式(二)之工厂模式iOS设计模式(三)之抽象工厂...

  • iOS设计模式(一)之简单工厂模式

    设计模式系列传送门 iOS设计模式(一)之简单工厂模式iOS设计模式(二)之工厂模式iOS设计模式(三)之抽象工厂...

  • iOS设计模式(二)之工厂模式

    设计模式系列传送门 iOS设计模式(一)之简单工厂模式iOS设计模式(二)之工厂模式iOS设计模式(三)之抽象工厂...

  • iOS设计模式之美-适配器模式

    iOS设计模式之美-工厂模式iOS设计模式之美-抽象工厂模式iOS设计模式之美-生成器模式iOS设计模式之美-适配...

  • iOS设计模式之美-抽象工厂模式

    iOS设计模式之美-工厂模式iOS设计模式之美-抽象工厂模式iOS设计模式之美-生成器模式iOS设计模式之美-适配...

  • iOS设计模式之美-工厂模式

    iOS设计模式之美-工厂模式iOS设计模式之美-抽象工厂模式iOS设计模式之美-生成器模式iOS设计模式之美-适配...

  • iOS设计模式之美-生成器模式

    iOS设计模式之美-工厂模式iOS设计模式之美-抽象工厂模式iOS设计模式之美-生成器模式iOS设计模式之美-适配...

  • 设计模式之工厂模式

    设计模式之工厂模式 标签(空格分隔): 设计模式 工厂模式 设计模式的感念 设计模式的应用 工厂设计模式的产生 工...

  • 设计模式系列

    创建型模式: 设计模式之工厂模式(Factory Pattern)设计模式之抽象工厂模式(Abstract Fac...

  • 简单工厂模式

    Android进阶之设计模式 简单工厂模式 简单工厂模式(又叫作静态工厂方法模式), 其属于创建型设计模式,但并不...

网友评论

      本文标题:设计模式之工厂模式

      本文链接:https://www.haomeiwen.com/subject/xdiplctx.html