Bootstrap

设计模式之工厂模式

1、什么是工厂模式?

        工厂模式就是将创建对象的具体过程屏蔽隔离起来,从而达到更高的灵活性,工厂模式可以分为三类:

  •  简单工厂模式
  •  工厂方法模式
  •   抽象工厂模式                    

 2、简单工厂模式

                简单工厂模式的核心是定义一个创建对象的接口,将对象的创建和本身的业务逻辑分离,降低系统的耦合度,使得两个修改起来相对容易些,当以后实现改变时,只需要修改工厂类即可

public abstract class Phone {
    //打电话
    public abstract void call();
}



public class ViVoPhone extends Phone{
    @Override
    public void call() {
        System.out.println("使用vivo手机打电话");
    }
}



public class MiPhone extends Phone{
    @Override
    public void call() {
        System.out.println("使用小米打电话");
    }
}



//工厂
public class  PhoneFactory {
    private static Phone phone;
    public static Phone createPhone(String name){
        if(name.equals("vivo")){
            phone=new ViVoPhone();
        }else if(name.equals("xiaomi")){
            phone=new MiPhone();
        }
        return phone;
    }
}



public class Test {
    public static void main(String[] args) {
        //使用简单工厂创建对象
        Phone xiaomi = PhoneFactory.createPhone("vivo");
        xiaomi.call();
    }
}


 2.1简单工厂模式的有缺点

      单工厂模式提供专门的工厂类用于创建对象,实现了对象创建和使用的职责分离,客户端不需知道所创建的具体产品类的类名以及创建过程,只需知道具体产品类所对应的参数即可,通过引入配置文件,可以在不修改任何客户端代码的情况下更换和增加新的具体产品类,在一定程度上提高了系统的灵活性。

       但缺点在于不符合“开闭原则”,每次添加新产品就需要修改工厂类。在产品类型较多时,有可能造成工厂逻辑过于复杂,不利于系统的扩展维护,并且工厂类集中了所有产品创建逻辑,一旦不能正常工作,整个系统都要受到影响。

              为了解决简单工厂模式的问题,出现了工厂方法模式  

3.工厂方法模式

       工厂方法模式将工厂抽象化,并定义一个创建对象的接口。每增加新产品,只需增加该产品以及对应的具体实现工厂类,由具体工厂类决定要实例化的产品是哪个,将对象的创建与实例化延迟到子类,这样工厂的设计就符合“开闭原则”了,扩展时不必去修改原来的代码。在使用时,用于只需知道产品对应的具体工厂,关注具体的创建过程,甚至不需要知道具体产品类的类名,当我们选择哪个具体工厂时,就已经决定了实际创建的产品是哪个了。

        ​ 但缺点在于,每增加一个产品都需要增加一个具体产品类和实现工厂类,使得系统中类的个数成倍增加,在一定程度上增加了系统的复杂度,同时也增加了系统具体类的依赖。

//手机抽象类
public abstract class Phone {
    //打电话
    public abstract void call();
}


//小米手机
public class MiPhone extends Phone{
    @Override
    public void call() {
        System.out.println("使用小米打电话");
    }
}


//vivo手机
public class ViVoPhone extends Phone{
    @Override
    public void call() {
        System.out.println("使用vivo手机打电话");
    }
}

//工厂抽象类【定义成接口也可以】
public abstract class AbstractPhoneFactory {
    public abstract Phone createPhone();
}


//小米手机厂
public class MiPhoneFactory extends AbstractPhoneFactory{
    @Override
    public Phone createPhone() {
        return new MiPhone();
    }
}


//vivo手机厂
public class ViVoFactory extends AbstractPhoneFactory{
    @Override
    public Phone createPhone() {
        return new ViVoPhone();
    }
}

 4.抽象工厂模式

      抽象工厂模式主要用于创建相关对象的家族。当一个产品族中需要被设计在一起工作时,通过抽象工厂模式,能够保证客户端始终只使用同一个产品族中的对象;并且通过隔离具体类的生成,使得客户端不需要明确指定具体生成类;所有的具体工厂都实现了抽象工厂中定义的公共接口,因此只需要改变具体工厂的实例,就可以在某种程度上改变整个软件系统的行为。

     但该模式的缺点在于添加新的行为时比较麻烦,如果需要添加一个新产品族对象时,需要更改接口及其下所有子类,这必然会带来很大的麻烦。

  

//发动机以及型号  
public interface Engine {}  

 
public class EngineA implements Engine{  
    public EngineA(){  
        System.out.println("制造-->EngineA");  
    }  
}  

public class EngineB implements Engine{  
    public EngineB(){  
        System.out.println("制造-->EngineB");  
    }  
}  
 
 
//空调以及型号  
public interface Aircondition {} 
 
public class AirconditionA implements Aircondition{  
    public AirconditionA(){  
        System.out.println("制造-->AirconditionA");  
    }  
}  


public class AirconditionB implements Aircondition{  
    public AirconditionB(){  
        System.out.println("制造-->AirconditionB");  
    }  
} 



//创建工厂的接口  
public interface AbstractFactory {  
    //制造发动机
    public Engine createEngine();
    //制造空调 
    public Aircondition createAircondition(); 
}  
 
//为宝马320系列生产配件  
public class FactoryBMW320 implements AbstractFactory{     
    @Override  
    public Engine createEngine() {    
        return new EngineA();  
    }  
    @Override  
    public Aircondition createAircondition() {  
        return new AirconditionA();  
    }  
}  
//宝马523系列
public class FactoryBMW523 implements AbstractFactory {  
     @Override  
    public Engine createEngine() {    
        return new EngineB();  
    }  
    @Override  
    public Aircondition createAircondition() {  
        return new AirconditionB();  
    }  
} 

 5. 工厂方法模式与抽象工厂模式的区别在于

(1)工厂方法只有一个抽象产品类和一个抽象工厂类,但可以派生出多个具体产品类和具体工厂类,每个具体工厂类只能创建一个具体产品类的实例。

(2)抽象工厂模式拥有多个抽象产品类(产品族)和一个抽象工厂类,每个抽象产品类可以派生出多个具体产品类;抽象工厂类也可以派生出多个具体工厂类,同时每个具体工厂类可以创建多个具体产品类的实例

;