设计模式(4)-- 工厂方法 和 抽象工厂

时间:2022-05-29 07:27:19

用工厂方法创建对象

简单工厂 :一定程度上简化了工厂方法(Factory Method)与抽象工厂(Abstract Factory)的模式

简单工厂 可以根据类型 返回不同的对象。如: pizz1 pizz2 pizz3 如果 要返回不同地方的pizz呢 如 nyPizz1  nyPizz2  jzPizz1  jzPizz2 这里就需要工厂方法了。

工厂方法 每一个子类都是一个工厂 可以 nyPizz 工厂  jzPizz工厂。 而简单工厂只有一个工厂。 所以工厂方法扩展性强一些。

pull wool over my own eyes (蒙着眼睛骗自己)。 工厂方法的优点:

对象的创建是现实的,如果不创建对象,就无法创建任何Java程序。然而,工厂方法 ,可将这些创建对象的代码用栅栏围起来,


今天是比较闲的一天。 解决了一个密码强度验证问题就无所事事了。。

1. 问题: 看完抽象工厂觉得和策略模式有点像,但还是有区别的。。

策略模式依赖的OO原则是: 针对接口编程,不针对具体实现

抽象工厂依赖的OO原则是: 依赖抽象,不要依赖具体实现 

区别: 策略模式之重点是算法(行为)的封装(如:鸟 的fly()行为)。 抽象工厂 重点是产品的依赖抽象(如 鸟的 名字。颜色。等。。)


关键词:解耦

工厂方法和抽象工厂。这两种设计模式都是将对象创建的过程封装起来。以便将代码从具体类解耦。

OO原则: (1)多用组合,少用继承 (2)针对接口编程,不针对实现编程 (3)为交互对象之间的松耦合设计而努力 (4)类该对扩展开放,对修改关闭。(5)依赖抽象 ,不

要依赖具体类

OO模式:抽象工厂模式---提供一个接口,用于创建相关或依赖对象的家族,而不需要明确指定具体类。

OO模式:工厂方法模式---定义了一个创建对象的接口,但由子类决定要实例化的类是哪一个。工厂方法让类把实例化推迟到子类。


简单工厂 , 工厂方法 , 抽象工厂  及区别

1.简单工厂: (静态工厂)

(1)简单工厂其实不是一个设计模式,反而比较像是一种编程习惯

(2)虽然不是真正的设计模式,但仍不失为一个简单的方法,可以将客户程序从具体类解耦。

(3) 利用静态方法定义一个简单的工厂,这是很常见的技巧,常被称为静态工厂。 缺 点 不能通过继承来改变创建方法的行为。

代码: 把创建对象行为从代码中抽取出来

public class SimplePizzaFactory{                             //这个类只做一件事,帮它的客户创建比萨

       public Pizza  createPizza(String type){             //所有客户用这个方法来实例化对象

            Pizza  pizza = null;

            if(type.equals("cheese")){

                 pizza = new CheesePizza();

            } else if (type.equals("pepperoni")){

                pizza = new PepperoniPizza();

            }

                 return pizza;

      }

}

// 利用工厂来为我们创建比萨,

public class PizzaStore{

     SimplePizzaFactory   factory;

     public PizzaStore(SimplePizzaFactory  factory){        //构造器需要一个工厂作为参数

            this.factory = factory;

     }

     public Pizza orderPizza(String type){      //通过简单传入订单类型来使用工厂创建比萨

          Pizza pizza;

          pizza = factory.createPizza(type);  // 我们把new 操作符替换成工厂对象的创建方法,这里不再使用具体实例化。

      }

}

2.工厂方法: // 先看模式介绍

// 原本由一个对象负责所有具体类的实例化, 现在变成一群子类来负责实例化。

public  abstract class PizzaStore{

public Pizza orderPizza(String type){     

    Pizza pizza;

    pizza = createPizza(type);        // orderPizza()方法和一个工厂方法联合起来,就可以成为一个框架。

    return pizza;

}

        protected abstract Pizza createPizza(String type); //实例化比萨的责任被移到一个”方法“中,此方法就如同一个”工厂“

}

工厂方法用来处理对象的创建,并将这样行为封装在子类中。这样,客户程序中关于超类的代码就和子类对象创建代码解耦了

abstract   Product  factoryMethod(String type)

(1)工厂方法是抽象的,所以依赖子类来处理对象的创建。

(2)工厂方法必须返回一个产品。超类中定义的方法,通常使用到工厂方法的返回值 。

3.抽象工厂:  // 先看模式介绍

public interface PizzaIngredientFactory{   //Ingredient 材料   提供一个接口

    public Dough   createDough();          // 在接口中,每个原料都有一个对应的方法创建该原料

    public Sauce    createSauce();

    public Cheese  createCheese();        //每个原料都将是一个类。

}

// 实现 工厂接口    对应 纽约原料  还可以有多个  如 北京原料, 上海原料

public class NYPizzaIngredientFactory implements PizzaIngredidntFactory{

    //实现其方法   如:

    public Dough createDough(){

return new ThinCrustDough();   //  对于原料家族内的每一种原料,我们都提供了纽约的版本。

                     // 这子类中 创建对象 , 这里利用到了工厂方法。

   }


}

//创建纽约风味比萨    // 芝加哥风味  等。 

public class CheesePizza extends Pizza{

       PizzaIngredientFactory  ingredientFactory  ; //  抽象工厂  这是区别工厂方法的一个地方, 抽象工厂以组合的方式 进入类。 工厂方法是以继承

        public CheesePizza(PizzaIngredientFactory ingredientFactory){

                 this.ingredientFactory = ingredientFactory; // 要制作比萨,需要工厂提供原烤料,所以每个比萨都要从构造器中得到一个比萨,并保存到实例变量中。

        }

        void prepare(){

             dough = ingredientFactory.createDough();

             sauce = ingredientFactory.createSauce();  //每当需要原料时,就跟工厂要。

        }

}

// 加盟店  

public class NYPizzaStore extends PizzaStore{

     

public Pizza  createPizza(String type){           

            Pizza  pizza = null;

            PizzaIngredientFactory ing = new NYPizzaIngredientFacotry();

            if(type.equals("cheese")){

            //      pizza = new CheesePizza();

pizza = new CheesePizza(ing);   //把工厂传递给每一个比萨,以便比萨从工厂中得到原料


            } else if (type.equals("veggie")){

            //      pizza = new VeggiePizza();

pizza = new VeggiePizza(ing);

            }

                 return pizza;

      }

}

// 

(1) 抽象工厂的方法,经常以 工厂方法的方式实现。

(2)抽像工厂的任务是定义一个负责创建一组产品的接口。这个接口内的每个方法都负责创建一个具体产品,同时我们利用实现抽象工厂的子类来提供这些具体的做法。所以,在

抽象工厂中利用工厂方法实现生产方法是相当自然的做法。

三者区别:

  (1)。简单工厂相比工厂方法: 简单工厂不具备工厂方法的弹性,因为简单工厂不能变更正在创建的产品。

  (2)。抽象工厂相比工厂方法:

1、工厂方法创建对象是依赖于继承 。 抽象工厂依赖组合

                1.1、利用工厂方法创建对象时,需要扩展一个类,并覆盖它的工厂方法。 通常子类来创建对象

                1.2、抽象工厂 必须先实例化,然后将它传入一些针对抽象类型所写的代码中。

                1.3、抽象工厂的一个优点: 把一群相关的产品集合起来。


要点:

(1)。所有的工厂都是用来封装对象的创建

(2)。简单工厂,虽然不是真正的设计模式,但仍不失为一个简单的方法,可以将客户程序从具体解耦

(3)。工厂方法使用继承:把对象的创建委托给子类,子类实现工厂方法来创建对象。

(4)。抽象工厂使用对象组合,对象的创建被实现在工厂接口所暴露出来的方法中。

(5)。所有工厂模式都通过减少应用程序和具体类之间的依赖促进松耦合。

(6)。工厂方法允许类将实例化延迟到子类进行。

(7)。抽象工厂创建相关的对象家族,而不需要依赖它们的具体类。

(8)。依赖倒置原则,指导我们避免依赖具体类型,而要尽量依赖抽象

(9)。工厂是很威力的技巧,帮助我们针对抽象编程,而不要针对具体编程。


抽象工厂经常使用工厂方法来实现具体工厂。 抽象工厂接口中的方法,每个方法就是一个工厂。