工厂模式简单介绍
admin
2024-05-02 03:43:32
0

CSDN是我用过的最垃圾的东西

工厂方法模式 - 应用最广泛的模式

###1.介绍:工厂方法模式(Factory Pattern)是创建型设计模式之一。工厂方法模式是一种 结构简单的模式。
###2.定义:定义一个用于创建 对象的接口,让子类决定实例化哪个类。

###3.使用场景:在任何需要生成复杂对象的地方,都可以使用工厂方法模式。复杂对象适合使用工厂模式,用new 就可以完成创建的对象无需使用工厂模式。

###4.:栗子和分析

  • 举个栗子:工厂模式的通用模式代码
    public abstract class Product {
    /**
    * 产品类的抽象方法
    * 由具体的产品类来实现
    */
    public abstract void method();
    }

    public class ConcreteProductA extends Product{
    @Override
    public void method() {
    System.out.println(“这是具体的产品A”);
    }
    }
    public class ConcreteProductB extends Product{
    @Override
    public void method() {
    System.out.println(“这是具体的产品B”);
    }
    }
    public abstract class Factory {
    /**
    * 抽象工厂方法
    * 具体生产的产品由子类去实现
    /
    public abstract Product createProduct();
    }
    /
    *

    • 具体的工厂实现类
      /
      public class ConcreteFactory extends Factory{
      @Override
      public Product createProduct() {
      return new ConcreteProductA();
      }
      }
      /
      *
    • 客户类
      */
      public class Client {
      public static void main(String[] args) {
      Factory factory = new ConcreteFactory();
      Product product = factory.createProduct();
      product.method();
      }
      }
  • 1.代码分析:ConcreteProductA,和ConcreteProductB继承了抽象类Product,并重写了父类的抽象方法,method。

  • 2.ConcreteFactory类继承了抽象类Factory并且重写了父类的createProduct方法:返回一个创建了的CocreteProductA对象。

  • 3.Client类,在该类的main方法中,创建了ConcreteFactory对象,并且通过调用ta的createProduct方法,获取了Product对象(实际是ConcreteProductA对象),接着该product对象调用ta的method方法:在console上输出打印的message。

  • 模式分析:这里的几个角色都很简单,主要分为四个模块,

  • 一是抽象工厂,这是工厂模式核心

  • 二是具体工厂,实现具体的业务逻辑

  • 三是抽象产品,是工厂方法模式所创建的产品的父类

  • 四是具体产品,为实现抽象产品的某个具体产品的对象

  • 以上就是工厂模式的四个重要组成部分。

  • 上述的代码中在Client类中构造了一个工厂对象,同工作其生产了一个产品对象,这里获取而是ConcreteProductA对象的实例;如果想得到ConcreteProductB对象只需更改createProduct方法的返回对象即可。

  • 这种方式很简单,需要哪一个产品就生产哪一个。

  • 更简洁的生产具体对象的方法:反射。此时需要在工厂方法的参数列表中传入一个Clss类来决定是哪个产品类。具体代码如下咯:
    public abstract class Factory2 {
    /**
    * 抽象工厂方法
    * 具体生产什么由子类去实现
    /
    public abstract T createProduct(Class clz);
    }
    public class ConcreteFactory2 extends Factory2{
    /
    *
    *
    * @param clz 产品对象的类型
    * @param 泛型
    * @return 具体的产品对象
    /
    @Override
    public T createProduct(Class clz) {
    Product product = null;
    try {
    product = (Product) Class.forName(clz.getName()).newInstance();
    } catch (InstantiationException e) {
    e.printStackTrace();
    } catch (IllegalAccessException e) {
    e.printStackTrace();
    } catch (ClassNotFoundException e) {
    e.printStackTrace();
    }
    return (T) product;
    }
    }
    public class Client2 {
    /
    *
    *
    * @param args
    */
    public static void main(String[] args) {
    Factory2 factory2 = new ConcreteFactory2();
    ConcreteProductB productB = factory2.createProduct(ConcreteProductB.class);
    productB.method();
    }
    }

  • 重点:使用到了反射以及泛型

  • 分析:需要哪个类就传入按个类的类型就可以,这种方法比较简洁,动态;若不用这种方式还可以为每一个产品都定义一个具体的工厂,各司其职。代码如下:

    public class ConcreteFactoryA extends Factory{
    @Override
    public Product createProduct() {
    return new ConcreteProductA();
    }
    }

    public class ConcreteFactoryB extends Factory{
    @Override
    public Product createProduct() {
    return new ConcreteProductB();
    }
    }
    public class Client {
    public static void main(String[] args) {
    Factory factoryA = new ConcreteFactoryA();
    Product productA = factoryA.createProduct();
    productA.method();
    Factory factoryB = new ConcreteFactoryB();
    Product productB = factoryA.createProduct();
    productB.method();
    }
    }

  • 像这种拥有多个工厂的方式我们称为多工厂方法模式,**同样地,回到我们最初的那个工厂模式,当我们的工厂只有一个的时候,我们还是为工厂模式提供了一个抽象类,那么我们是否可以将其简化掉呢?**如果确定你的工厂类中只有一个,那么简化掉抽象类肯定是没问题的:我们只需要将对应的工厂方法改为静态方法即可。如下:

    public class Factory {
    public static Product createProduct() {
    return new ConcreteProductA();
    }
    }

  • 像这样的方式又称为简单工厂模式,它是工厂方法模式的一个弱化版本。工厂方法模式是完全符合设计原则的:降低了对象之间的耦合度,而且,工厂方法模式依赖于抽象的架构,其将实例化的任务交给子类去完成,有非常好的可拓展性。

模式的简单实现

  • 现在,需要生产某款suv的三种车型,例如Q3,Q5,Q7,对于这类车型而言,内部结构差役并不是很大,因此一种生产线就可以应付这三种车型,下面是该生产线的抽象类定义

public abstract class AudiFactory {
/**
*
* @param clz 具体的SUV型号
* @param 泛型
* @return 具体型号的SUV车对象
*/
public abstract T createAudiCar(Class clz);
}

  • 因为这三种suv在主结构上并没有什么差异,所以没有必要对每中车型都提供一条不同的生产线,一条生产线就可以了。

    public class AudiCarFactory extends AudiFactory{
    @Override
    public T createAudiCar(Class clz) {
    AudiCar audiCar = null;
    try {
    audiCar = (AudiCar) Class.forName(clz.getName()).newInstance();
    } catch (InstantiationException e) {
    e.printStackTrace();
    } catch (IllegalAccessException e) {
    e.printStackTrace();
    } catch (ClassNotFoundException e) {
    e.printStackTrace();
    }
    return (T) audiCar;
    }
    }

  • 对于这三种车型呢,除了一些车都有的基本功能外,还提供了自动驾驶功能:这些功能都使用一个抽象的基类来声明

    public abstract class AudiCar {
    /**
    * 驾驶的功能
    /
    public abstract void drive();
    /
    *
    * 汽车的抽象产品类
    * 定义汽车的一个行为方法:自动驾驶
    */
    public abstract void selfNavigation();
    }

  • 家下来就是生产每一种具体的车型:
    public class AudiQ3 extends AudiCar{
    @Override
    public void drive() {
    System.out.println(“AudiQ3开始启动上路啦”);
    }
    @Override
    public void selfNavigation() {
    System.out.println(“AudiQ3开始自动驾驶啦”);
    }
    }
    public class AudiQ5 extends AudiCar{
    @Override
    public void drive() {
    System.out.println(“AudiQ5开始启动上路啦”);
    }
    @Override
    public void selfNavigation() {
    System.out.println(“AudiQ5开始自动驾驶啦”);
    }
    }
    public class AudiQ7 extends AudiCar{
    @Override
    public void drive() {
    System.out.println(“AudiQ7开始启动上路啦”);
    }
    @Override
    public void selfNavigation() {
    System.out.println(“AudiQ7开始自动驾驶啦”);
    }
    }

  • 最后我们将各个部分组装起来,完成生产线的功能

    public class Client {
    public static void main(String[] args) {
    AudiCarFactory factory = new AudiCarFactory();
    AudiQ3 audiQ3 = factory.createAudiCar(AudiQ3.class);
    audiQ3.drive();
    audiQ3.selfNavigation();
    AudiQ5 audiQ5 = factory.createAudiCar(AudiQ5.class);
    audiQ5.drive();
    audiQ5.selfNavigation();
    AudiQ7 audiQ7 = factory.createAudiCar(AudiQ7.class);
    audiQ7.drive();
    audiQ7.selfNavigation();
    }
    }

  • 以上代码结构简单,逻辑也类似,很容易理解的。

###6.Android 源码中工厂方法模式的实现

  • 工厂方法模式的应用很广发,大家平时开发过程中经常会使用到数据结构中其实就有对工厂模式的应用:List和Set,List和Set都继承与Collection接口,而Collection接口继承与Iterable接口,Iterable接口很简单,就一个iterator方法。
    public inteface Iterable{
    Iterator iterator();
    }

  • 这意味着List和Set也会继承该方法,平时比较常用的两个间接实现类ArraylistHashSet中iterator烦恼歌发的实现就是构造并返回一个迭代器对象。 page - 93.

  • Arraylist 源码
    /**
    * Returns an iterator over the elements in this list in proper sequence.
    *
    *

    The returned iterator is fail-fast.
    *
    * @return an iterator over the elements in this list in proper sequence
    /
    public Iterator iterator() {
    return new Itr();
    }
    /
    *
    * An optimized version of AbstractList.Itr
    */
    private class Itr implements Iterator {
    int cursor; // index of next element to return
    int lastRet = -1; // index of last element returned; -1 if no such
    int expectedModCount = modCount;
    public boolean hasNext() {
    return cursor != size;
    }
    @SuppressWarnings(“unchecked”)
    public E next() {
    checkForComodification();
    int i = cursor;
    if (i >= size)
    throw new NoSuchElementException();
    Object[] elementData = ArrayList.this.elementData;
    if (i >= elementData.length)
    throw new ConcurrentModificationException();
    cursor = i + 1;
    return (E) elementData[lastRet = i];
    }
    public void remove() {
    if (lastRet < 0)
    throw new IllegalStateException();
    checkForComodification();
    try {
    ArrayList.this.remove(lastRet);
    cursor = lastRet;
    lastRet = -1;
    expectedModCount = modCount;
    } catch (IndexOutOfBoundsException ex) {
    throw new ConcurrentModificationException();
    }
    }
    @Override
    @SuppressWarnings(“unchecked”)
    public void forEachRemaining(Consumer consumer) {
    Objects.requireNonNull(consumer);
    final int size = ArrayList.this.size;
    int i = cursor;
    if (i >= size) {
    return;
    }
    final Object[] elementData = ArrayList.this.elementData;
    if (i >= elementData.length) {
    throw new ConcurrentModificationException();
    }
    while (i != size && modCount == expectedModCount) {
    consumer.accept((E) elementData[i++]);
    }
    // update once at end of iteration to reduce heap write traffic
    cursor = i;
    lastRet = i - 1;
    checkForComodification();
    }
    final void checkForComodification() {
    if (modCount != expectedModCount)
    throw new ConcurrentModificationException();
    }
    }

  • HashSet源码
    /**
    * Returns an iterator over the elements in this set. The elements
    * are returned in no particular order.
    *
    * @return an Iterator over the elements in this set
    * @see ConcurrentModificationException
    */
    public Iterator iterator() {
    return map.keySet().iterator();
    }

  • HashSet的iterator方法中会返回成员变量 backingMap中对应HashSet对象元素的迭代器对象,最终返回的是KeySet中的一个迭代器对象。

  • 分析:ArrayList和HasetSet中的iterator方法其实就相当有一个工厂方法,专为new 对象而存在。这里iterator方法是构造并返回一个具体的迭代器

  • *Android中工厂方法模式的应用

    public class XxActivity extends Activity{
    @override
    protected void onCreate(Bundle savedInstanceState){
    super.Oncreate(savedInstanceState);
    setContentView(new LinearLayout(this));
    }
    }

  • 分析:这里构造一个线性布局LinearLayout对象并且设置为当前Activity的根布局,这段代码看似简单不过,其实这就相当于一个工厂方法,为什么呢?:LinearLayout 是一个viewGroup,ViewGroup继承自View,简单的说,所有的控件都是View的子类。在上面的代码中我们在XxActivity的onCreate方法中构造一个View对象,并设置为当前界面ContentView并返回给framework处理,如果现在又有一个XyActivity,这时又可以通过setContentView方法设置不同的View。可知:这就是一个工厂方法模式的结构!

###7.关于onCreate方法

8.工厂方法模式实战

  • 重要组成部分:
  • 1.抽象的product类
  • 2.具体的product类
  • 3,factory类(根据传入的product类,产生对应的对象)
  • 代码就不贴了

###9.总结

  • 工厂方法模式是很好的设计模式,它的有优点是具有很好的拓展性;它的缺点也是难以避免的,每次我们为工厂方法模式添加新的产品时就要编写一个新的产品类,同时还要引入抽象层,这就必然会导致类结构的复杂化,所以在某些情况比较简单时,是否使用该模式,需要细细权衡。

相关内容

热门资讯

奉献爱心的成语 奉献爱心的成语春风送暖 体贴入微 无微不至 雪中送炭关怀备至嘘寒问暖
安徒生在1827年发表过《垂死... 安徒生在1827年发表过《垂死的小孩》这篇文章吗问一下、帮帮忙!《垂死的小孩》是一首诗,是安徒生18...
跆拳道比赛的进攻技术是怎样的? 跆拳道比赛的进攻技术是怎样的?跆拳道比赛的进攻技术跆拳道比赛的进攻技术包括拳攻和踢法进攻两类。现代竞...
本人书荒,求几本书 本人书荒,求几本书我最近在看紫玉钗街诡怪传说。我觉得还不错
情玫公寓和紫色蜜桃哪个更加好 ... 情玫公寓和紫色蜜桃哪个更加好 会不会有什么问题 里面的女的是不是都是莫须有的都是骗人的,想骗取你的钱...
求一早期的动画片名称,每集一个... 求一早期的动画片名称,每集一个单独故事,似乎是世界怪异故事集还有一组头发的女主人公为了买礼物的演员卖...
无双大蛇各武将的终极武器是什么... 无双大蛇各武将的终极武器是什么名字?正在收集终极武器,已经弄到赵云.周泰.织田信长的.其他武将的终极...
你觉得,你们遇到最无奈的时候,... 你觉得,你们遇到最无奈的时候,是什么时候?一个男人最无奈的时候就是在最没能力的时候遇到最想照顾的人,...
我们常把那些对事物只有一知半解... 我们常把那些对事物只有一知半解却喜欢在人前卖弄的人叫做什么哦,这种人我们这里叫半吊子,就是半瓶醋,一...
砸锅卖铁去上学谁是背后反派 砸锅卖铁去上学谁是背后反派 肖伊莱。《砸锅卖铁去上学》是由奇迹文学城作者红刺北写作的一篇女强爽文...
为什么让我漩涡中挣脱 为什么让我漩涡中挣脱这个还是你自己的心理的想法,想开,自然好了
苍山洱海的任务从哪儿开始做啊 苍山洱海的任务从哪儿开始做啊从地图的右上方莫雨少爷开始任务。地图北边路口
如果你可以选择自己的人生道路,... 如果你可以选择自己的人生道路,你会如何抉择?我会选择从初中就开始奋斗的一种人生道路,不过是那种见过世...
哪种五笔好? 哪种五笔好?用万能五笔啊功能更强大!五笔加加 搜狗呵呵,建议你使用极点五笔。。。。敲一下空格,能切换...
为什么和陈伟霆一样帅的人 总是... 为什么和陈伟霆一样帅的人 总是被女生盯着看?反而女生不敢和他说话爱美之心人皆有之啊和陈伟霆一样帅的人...
算命能不能改命 算命能不能改命算命的不能够改命,你没听说过有一句话吗,三分天注定,七分靠打拼,也就是说有三分就是靠天...
谁知道赛尔号怎么进入夜魔古堡 谁知道赛尔号怎么进入夜魔古堡登录赛尔号,打开左上角的航行日志,选择右侧栏第一个圣甲永夜,再点击图中间...
爱情公寓5里人人都爱吕小布是哪... 爱情公寓5里人人都爱吕小布是哪一集?爱情公寓5里人人都爱吕小布,是在第13集上。有好几集都有好像在3...
不败是什么意思? 不败是什么意思?包含成功和从未挑战两种意思
叔向见韩宣子中栾武子等人的事例... 叔向见韩宣子中栾武子等人的事例。分析刘禹锡和韩宣子为人的异同刘禹锡是一个洁身自好的人,韩宣子是一个清...