浅谈简单工厂,工厂方法,抽象工厂的区别和使用

  工厂模式是分为三种,分别是简单工厂,工厂方法,抽象工厂。其中工厂方法和抽象工厂是GoF23种设计模式中的一种,而简单工厂则不是一种设计模式,更加可以理解的是一种编码时候预定俗称的一种习惯。那么,就在接下来三点中分别去分析理解工厂模式。

一 简单工厂:通过实例化一个工厂类,来获取对应的产品实例。我们不需要关注产品本身如何被创建的细节,只需要通过相应的工厂就可以获得相应的实例。简单工厂包括三种角色:

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

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

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

比如以下例子:

                            (类设计的UML图)

1.Drinks作为产品的抽象类并且有抽象方法produce();(抽象产品
public  abstract class Drinks {      protected abstract void produce();}
2.Sprite继承Drinks是要被具体生产出来的产品,他重写了produce()方法。(具体产品)
public class Sprite extends Drinks {

@Override    protected void produce() {        System.out.println("drink sprite");    }}

3.Cola同样也继承了Drinks,是要被生产出来的具体产品。
(具体产品)
public class Cola extends Drinks {

@Override    protected void produce() {        System.out.println("Drink Cola");    }}

4.DrinksFactory为简单工厂,向外暴露produceDrink方法来获取产品的实例(工厂
public class DrinksFactory {

public Drinks produceDrink(Class className){        try {            return (Drinks) Class.forName(className.getName()).newInstance();        } catch (InstantiationException e) {            e.printStackTrace();        } catch (IllegalAccessException e) {            e.printStackTrace();        } catch (ClassNotFoundException e) {            e.printStackTrace();        }

return null;    }}

5.Client为应用层,Client端想要获取到Cola或者Sprite对象,只要通过DrinkFactory中的produceDrink方法传入相对应的对应的产品
public class Client {    public static void main(String[] args) {        DrinksFactory factory = new DrinksFactory();        Cola cola = (Cola) factory.produceDrink(Cola.class);        cola.produce();    }}
简单工厂的优点:1.不需要关心类的创建细节。2.减轻类之间的耦合依赖,具体类的实现只是依赖于简单工厂,而不依赖其他类。

简单工厂的缺点:1.扩展复杂,当简单工厂需要生产出另外一种产品的时候,需要扩展工厂的内部创建逻辑,比较有可能引起较大的故障2.由于工厂类集中了所有实例的创建逻辑,违反了高内聚责任分配原则,将全部创建逻辑集中到了一个工厂类中

二.工厂方法

  工厂方法的定义是:定义一个创建对象的接口,让实现这个接口的的类去决定实例化具体的类。工厂方法让类的实例化推迟到实现接口的子类中进行。

  比如说,我现在需要一瓶可乐,有可口可乐公司生产的可乐也有百事可乐公司生产的可乐,那么对于可乐这个产品等级(抽象工厂中会具体说明),具体生产什么可乐并不是在一个工厂实现,而是由一个可乐工厂指定一个标准(接口里面的抽象方法),可口可乐公司百事可乐公司只要按照这个标准去生产就可以了。  

                                             (2)工厂方法的Uml类图

1.Cola此类是产品的父类
public abstract class Cola {    protected abstract  void drinks();}
2.PepsiCola继承Cola,是要生产的产品之一
public class PepsiCola extends  Cola {

@Override    protected void drinks() {        System.out.println("Drinks PepsiCola");    }}
3.CoCoCola同样继承Cola,也是要生产的产品之一
public class CoCoCola extends Cola {

@Override    protected void drinks() {        System.out.println("Drinks cococoLa");    }}
4.ColaFacotry定义抽象工厂,指定要生产此类产品的规范(存在的方法与属性),指定工厂方法
public interface ColaFacotry {

Cola produce(Class<Cola> cola);}
5.PepsiColaFactory定义子类工厂,它继承抽象工厂,实现了对某一产品等级的产品的获得
public class PepsiColaFactory implements ColaFacotry {

public PepsiCola produce(Class cola) {        if (cola.isInstance(PepsiCola.class)){            return  new PepsiCola();        }        return null;    }}
6.ColaFacotry,是规定工厂方法去获得拿一些的产品等级的商品,比如说,我规定生产的产品等级是可乐和草莓可乐,那么对于它的实现类来说,也就是其子类中的重载方法来说去具体实现获取产品的具体实现。
public interface ColaFacotry {

Cola produce(Class<Cola> cola);}

三.抽象工厂

  抽象工厂是提供了创建一系列服务的的对象的接口。那么问题就来了,怎么区分和工厂方法中的服务对象宁?此时就需要对一组概念有所理解,即产品等级和产品族,我从网上找到下面这张图,进行解释说明。在图(4)中,我们可以通过横向和纵向的比较,横向是某一个手机厂商如苹果,小米等,他们不仅仅生产手机,还生产电脑,耳机等一系类产品,那么我们把苹果,小米,华为这样的厂商可以认为他们生产的是一个产品族,而他们自己本身就是一个抽象工厂的具体实现;那么纵向来看,不管是小米华为还是苹果,他们生产的产品是按照一定的规则来生产,显示屏,电池,处理器等等,所以对于纵向的产品来说,他们又是属于同一个产品等级,我们亦可以称他们的实现为工厂方法。

  综上所述,抽象工厂解决的是横向的产品族,工厂方法解决的是纵向的产品等级。具体抽象工厂请看代码。

(3)产品等级和产品族(图片来自https://laravel-china.org/topics/18598?order_by=created_at&)

                          (4)产品等级示意图

1.AbstractFactory 抽象工厂

public  interface AbstractFactory {

public Phone producePhone();

public Computer producaComputer();}2.AppleFactory具体工厂的实现一
public class AppleFactory implements AbstractFactory {    public Phone producePhone() {        return new Iphone();    }

public Computer producaComputer() {        return new Mac();    }}
3.MiFactory具体工厂的实现二
public class MiFactory implements AbstractFactory {    public Phone producePhone() {        return new MiPhone();    }

public Computer producaComputer() {        return new MiComputer();    }}
4.Phone抽象产品等级一
public abstract class Phone {    public abstract void call();}
5.Iphone具体产品一
public class Iphone extends Phone {

@Override    public void call() {        System.out.println("Iphone call");    }}
6.MiPhone具体产品一
public class MiPhone extends Phone {

@Override    public void call() {        System.out.println("Mi Phone call");    }}
7.Computer抽象产品等级二
public  abstract class Computer {

public abstract void work();}
8.Mac具体产品一
public class Mac extends Computer {

@Override    public void work() {        System.out.println("MAC work");    }}9.MiComputer 具体产品二
public class MiComputer extends Computer {

@Override    public void work() {        System.out.println("MI computer word");    }}10.客户端
public class Clint {

public static void main(String[] args) {        AppleFactory appleFactory = new AppleFactory();        appleFactory.producaComputer().work();        appleFactory.producePhone().call();

MiFactory miFactory = new MiFactory();        miFactory.producaComputer().work();        miFactory.producePhone().call();    }}

                        (5)抽象工厂UML类图

从UML类图中不难看出,我们如果需要拓展抽象工厂里面的方法会比较麻烦,因为我们必须修改抽象类以及添加对应的产品等级,这样修改量比较大,但是每种产品之间相互解耦,符合程序设计的“高内聚低耦合”的思想。

最后,不管是抽象工厂还是工厂方法甚至是简单工厂,他们的存在都有一定的优缺点,在设计程序的时候要根据具体情况进行取舍,不存在那种设计好那种设计特别差,只是针对不同的业务场景的不一样的处理。

原文地址:https://www.cnblogs.com/gclokok/p/10029088.html

时间: 2024-10-10 01:25:51

浅谈简单工厂,工厂方法,抽象工厂的区别和使用的相关文章

浅谈简单工厂,工厂方法,抽象工厂的使用

前言 这几天了解了工厂模式,自己也整理下思路,任何一种模式的出现都是为了让我们的程序有更好的可扩展性,工厂模式也不例外. 简单工厂 在实际的代码coding中我们在创建对象(也就是实例化一个类)的时候往往需要new class()这样来操作.举个例子: 这是项目结构 //这是一个中国人的类public class ChinesePepole { public void Show() { Console.WriteLine("I'm a {0}", this.GetType().Name

详解设计模式之工厂模式(简单工厂+工厂方法+抽象工厂)

园子里关于23种设计模式的博文已经可以说是成千上万.车载斗量.屯街塞巷.不计其数.数不胜数.摩肩接踵.汗牛充栋.车水马龙.门庭若市.琳琅满目直至让人眼花缭乱了.在这样的大环境下之所以来写设计模式类的博文,并不是像一些"非主流"的爱情观那样"宁缺毋滥". 只是其一呢,因为相当于给自己做一个总结,加深一下自己这方面的认识,因为掌握了和把它写出来我感觉后者还可以对技能有一个提升,其二呢是因为最近公司有一个内部的training需要讲设计模式. v写在前面 在这里呢,需要向

2 简单工厂模式、工厂模式、抽象工厂模式

简单工厂模式: -----------------------------------Pizza.java-------------------- package com; public abstract class Pizza { public abstract void prepare(); public abstract void bake(); public abstract void cut(); } -----------------------------------APizza.

创建和使用解耦——工厂模式详解(工厂方法+抽象工厂)

1.前言 直接new一个对象是最简单的创建对象的方式,但大量出现在业务代码中会带来至少两个问题.1:创建对象的细节直接暴露在业务代码中,修改实现细节必须修改相关的大量客户端代码.2:直接面向具体类型编程,违反了面向接口编程的原则,系统进行扩展时也不得不进行大量修改.要使得系统具有的良好的可扩展性以及后期易于维护,必须实现对产品的获取和对产品的使用解耦.要做到这两点,首先要对客户端代码屏蔽掉创建产品的细节,其次,客户端必须面向产品的抽象编程,利用java的多态特性在运行时才确定具体的产品.而这,正

工厂模式[3] 抽象工厂 Abstract Factory

简介 1.简单工厂,或静态工厂,产品接口 定义:专门定义一个类来负责创建其他类的实例,被创建的实例通常具有共同的父类或实现同一接口 优点:客户端可以直接消费产品,而不必关心具体产品的实现(不关心对象的构造方法是怎么new的),消除了客户端直接创建产品对象的责任,实现了对责任的分割. 缺点:工厂类记录了所有产品的创建逻辑,一旦不能正常工作,整个系统都会受到影响:而且当产品种类多.结构复杂的时候,把所有创建工作放进一个工厂中来,会使后期程序的扩展较为困难. 2.工厂方法,工厂接口+产品接口 定义:在

6创建型模式之工厂模式与抽象工厂模式

工厂模式 概念 工厂方法模式同样属于类的创建型模式又被称为多态工厂模式 . 工厂方法模式的意义是定义一个创建产品对象的工厂接口,将实际创建工作推迟到子类当中. 核心工厂类不再负责产品的创建,这样核心类成为一个抽象工厂角色,仅负责具体工厂子类必须实现的接口,这样进一步抽象化的好处是使得工厂方法模式可以使系统在不修改具体工厂角色的情况下引进新的产品. 类图角色和职责 抽象工厂(Creator)角色 工厂方法模式的核心,任何工厂类都必须实现这个接口. 具体工厂( Concrete  Creator)角

工厂模式和抽象工厂模式

工厂模式: 定义一个用于创建对象的接口,让他的子类决定实例化哪个类.使类的实例化延迟到子类. 1.普通的工厂模式: public class GoodProduct implements Product { private String prodInfo = "Iam the good prod"; public String getProductInfo() { // TODO Auto-generated method stub return this.prodInfo; } pu

Delphi 设计模式:《HeadFirst设计模式》Delphi代码---工厂模式之抽象工厂[转]

 1 2 {<HeadFirst设计模式>工厂模式之抽象工厂 } 3 { 抽象工厂的产品                       } 4 { 编译工具:Delphi7.0                  } 5 { E-Mail :[email protected]          } 6 7unit uPizzaIngredient; 8 9interface1011type12  TDough = class(TObject)13  end;1415  TThinCrustDoug

浅谈设计模式3-模板方法模式

模版方法模式,个人认为还是用处比较多的一个设计模式,而且也是比较好学和理解的一个.依然来通过模拟一个场景来慢慢了解. 现在我们来实现一下泡茶这个过程.首先我们需要烧开一壶水,然后往茶壶中放茶叶,加入开水,等待茶泡好. 经过前两次的分享,大家应该具备了基本的面向对象的思想了,这里就不再用面向过程的方式演示了. 首先,有一种普通人,他泡茶的方式是这样的 public class Common     { public void MakeTea()         {             Heat