`

设计模式------工厂模式

阅读更多
工厂模式是一种创建型模式。。。其中创建型模式包括:单例,工厂,建造者,原型四种
  /* 为什么要工厂方法:
1.因为我想控制产生交通工具的生产过程
2.工厂模式符合OCP原则,也就是开闭原则,
3。抽象工厂还有个最大优点,高内聚,低耦合,内聚都高到new的地方都转移到了一个类中来维护

工厂的共性是: 能生产多种产品,所以要具体产品类和抽象产品类,当然有一个具体工厂哈


工厂模式分为三种:
简单工厂模式(有些人又把简单工厂模式看成是工厂方法模式的一种特例),
工厂方法模式,
抽象工厂模式。

*/
-------------------------没有工厂的时候-------------------------------------------------
//当你控制了他的生产过程之后,像这样的代码就可以解耦了
UserDao userDao = new UserDaoImpl(); //这个代码是依赖于UserDaoImpl的实现的,如果想要换个类,那么这个地方时需要改动的,也就是说用到的地方要改,被用到的地方也要改。。
---------------------------工厂来了-----------------------------------------------


 简单工厂模式:优点:工厂类中包含了必要的逻辑判断(switch或者if/else),根据客户端的选择条件动态实例化相关的类,对客户端来说,去除了与具体产品的依赖。。。问题:因为需求变更后,我们需要修改原有的工厂类(至少要加case条件吧),这样违背了开放-封闭原则。

还有优点,他们转移了new,使得更换对象不需要大幅度修改。。。


它具有三个角色: 抽象产品角色,具体产品角色, 工厂类角色(new 的管理者)

一个工厂生产一种类别的产品。。。。。。。。

暴发户只要在车里面说一句:"开车"就可以了
//抽象产品角色
public interface Car{

  public void drive();
}

具体产品角色
public class Benz implements Car{
   public void drive(){
        System.out.println("Driving Benz");
   }
}

public class BMW implements Car{
   public void drive(){
       System.out.println("Driving BMW");
   }
  
}
//工厂类角色
public class Driver{

  public static Car driverCar(String s){
      if(s.equals("Benz"))return new Benz();
      if(s.equals("BMW"))return new BMW();
  }
}

//例子二
public class SimplePizzaFactory{
    public Pizza createPizza(String type){
       Pizza p = null;  //抽象产品类
       if(type.equals("cheese")){
            p = new CheesePizza();//具体产品类
       }else if(type.equals("pepperoni")){
            p = new PepperoniPizza();
       }else if(type.equals("veggie")){
           p = new VeggiePizza();
       }
        return p;    
     }
}


---------------------------忧郁的分割线----------------------------------------------

下面是工厂方法:
工厂方法模式就是为了去除简单工厂中的if/else或者switch/case来做的,他定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。
但是但是但是:工厂方法模式实现时,客户端需要决定实例化哪一个工厂,也就是说,工厂方法把简单工厂的内部逻辑判断已到了客户端代码来进行。。。。

我们想想他存在的意义,如果制造一辆汽车的过程只是一个new xxxCar();那么不要使用工厂,如果制造汽车的过程是  xxxxx;xxxxxx;xxxxx;.....; new xxxCar();xxxxx; 那么使用工厂方法模式,他可以使得知道汽车的这一系列的过程被封在起来,因为制造工厂的过程简单。。。


组成: 抽象工厂角色(工厂就开始抽象了哈),具体工厂角色,抽象产品角色,具体产品角色


//抽象工厂角色
public interface Driver{
   public Car driverCar();
}
//具体工厂角色
public class BenzDriver implements Driver{
   public Car driverCar(){
      return new Benz();
   }

}
 //具体工厂角色
public class BMWDriver implements Driver{
   public Car driverCar(){
     return new BMW();
   }
}

...产品类省略

使用:

Driver driver = new BenzDriver();
Car car = driver.driverCar();

对比简单工厂模式: Car car = Driver.driverCar("benz");

-----------------抽象工厂---------------------------------------------------------

/*
因为我们想让一个工厂生产不同的产品,
比如说我们想产生不同的交通工具,那么就要有不同的交通工具工厂的实现,每一个具体的工厂负责他对应的产品的控制
*/
public abstract class Factory{
    public abstract Vihecle create(); 
//这里使得所有工厂产生的产品有一个共性,他们还只能产生Vihecle的子类,或者让他们产生有Moveable接口的东西也可以
}

public class CarFactory extends Factory{
    public Vihecle create(){
     
    }
}
  

/**
 如果一个工厂里面不是产生一个产品,而是产生一系列的产品
*/

public class DefaultFactory{
     public void createCar(){}
     public void createAK47(){}
     public void createApple(){}
}

/*
如果要扩展的话,上面的写法不好。。。
所以创建一个他们的父亲工厂,其实实质和工厂方法是一样的,只不过多了几个工厂而已
嘿嘿。。。换皮肤的软件就是这么搞的
*/

public abstract class Factory{
     public abstract void createVehicle();
     public abstract void createWeapon();
     public abstract void createFood(){};
}
/*
工厂和抽象工厂最大的区别:工厂利于扩展产品,但要扩展产品系列的话则会导致工厂泛滥,
抽象工厂利于产生产品系列,但对于扩展产品来说(比如要加一个Flower,则不但要改Factory而且要改所有Factory的子类)
*/



-----------------配置文件与工厂的配合----------------------------------------------------------


//下面是利用配置文件来指定类的工厂。。。。模拟Spring的Bean工厂
//我们把要new 的东西放入配置文件中,这里配置文件里是这样  aakey=com.zhe.Car
public class Test{
     public Car create(){
         Properties p = new Properties();
         p.load(Test.class.getClassLoader()
           .getResourceAsStream("com/zhe/a.properties"));
         String classString = p.getProperty("aakey");
         Object o =  Class.forName(classString ).getInstance();
         //注意会调用空的构造函数
           Car car = (Car)o;
         car.run();
     }
}

//下面采用Spring自己的Bean工厂
//这时的配置文件是:applicationContext.xml
 //里面 <bean id="aakey" value="com.zhe.Car" />哈哈,这就是所谓的Ioc依赖注入

public class Test{
     public Car create(){
          BeanFactory f = 
  new ClassPathXmlApplicationContext("applicationContext.xml");
       Object o = f.getBean("aaKey");
           Car car = (Car)o;
         car.run();
     }
}

//-----------------------------------------------------------------
<<设计模式之禅>>-----抽象工厂

为什么要有抽象工厂? 所有设计模式都是为了使得代码重用,那么具体的工厂在生产过程中一定会有某些地方是一样的,那么就应该把他们提取出来,所以抽象工厂里面放的东西就是所有工厂的共性而已。。

//这个接口规定了每个具体工厂的能力,规定了每个具体工厂要做什么事情
public interface HumanFactory{
   public Human createYellowHuman();
   
   public Human createWhiteHuman();

   public Human createBlackHuman();
}

//下面是抽象工厂登场
public abstract class AbstractHumanFactory implements HumanFactory{
     
     protected Human createHuman(HumanEnum human){ //定义了所有工厂制造人类的统一过程,他的目的其实就是为了减少代码量
            Human h = null;
           if(!human.getValue().equals("")){
               try{
                   h = (Human)Class.forName(human.getValue()).newInstance();
               }catch(Exception e){
               }
           }
        return h;
     }   
}

public class MaleHumanFactory extends AbstractHumanFactory{
       public Human createBlackHuman(){
            return super.createHuman(HumanEnum.BlackMaleHuman);
       }
       public Human createWhiteHuman(){
            return super.createHuman(HumanEnum.WhiteMaleHuman);
       }
       public Human createYellowHuman(){
            return super.createHuman(HumanEnum.YellowMaleHuman);
       }
}

注意:我们把枚举看成是定义的static变量也可以,只不过他的好处是 不用判断输入参数是否为空,长度为0等边界条件

public enum HumanEnum{
   YellowMaleHuman("com.zhe.yellowHuman.YellowMaleHuman");
   YellowFemaleHuman("com.zhe.yellowHuman.YellowFemaleHuman");

   WhiteMaleHuman("com.zhe.whiteHuman.WhitewMaleHuman");
   WhiteFemaleHuman("com.zhe.whiteHuman.WhiteFemaleHuman");
   
   private String value = "";
   private HumanEnum(String value){
      this.value = value;
   }
   public String getValue(){
       return this.value;
   }
}

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics