美文网首页
设计模式之工厂模式

设计模式之工厂模式

作者: 不怕天黑_0819 | 来源:发表于2020-06-22 11:12 被阅读0次

    什么是工厂模式

    工厂模式(Factory Pattern)是 Java 中最常用的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。
    在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。

    按细的分一共有三种,一种是简单工厂,一种是工厂方法还有就是抽象工厂。在《设计模式》一书中将工厂模式分为两类:
    工厂方法模式(Factory Method)与抽象工厂模式(Abstract Factory)。
    将简单工厂模式(Simple Factory)看为工厂方法模式的一种特例,两者归为一类。

    什么是简单工厂模式

    简单工厂模式又叫静态工厂方法模式,就是建立一个工厂类,对实现了同一接口的一些类进行实例的创建。比如,一台咖啡机就可以理解为一个工厂模式,你只需要按下想喝的咖啡品类的按钮(摩卡或拿铁),它就会给你生产一杯相应的咖啡,你不需要管它内部的具体实现,只要告诉它你的需求即可。

    • 优点:

    工厂类含有必要的判断逻辑,可以决定在什么时候创建哪一个产品类的实例,客户端可以免除直接创建产品对象的责任,而仅仅“消费”产品;简单工厂模式通过这种做法实现了对责任的分割,它提供了专门的工厂类用于创建对象;
    客户端无须知道所创建的具体产品类的类名,只需要知道具体产品类所对应的参数即可,对于一些复杂的类名,通过简单工厂模式可以减少使用者的记忆量;
    通过引入配置文件,可以在不修改任何客户端代码的情况下更换和增加新的具体产品类,在一定程度上提高了系统的灵活性。

    • 缺点:
      不易拓展,一旦添加新的产品类型,就不得不修改工厂的创建逻辑;
      产品类型较多时,工厂的创建逻辑可能过于复杂,一旦出错可能造成所有产品的创建失败,不利于系统的维护。

    简单工厂模式

    建立一个工厂类,对实现同一个接口的一些类进行实例化。

    //创建二者共同的接口
    public interface Sender { 
     public void Send(); 
    }
    //创建实例类
    public class MailSender implements Sender { 
     @Override 
     public void Send() { 
     System.out.println("this is mailsender!"); 
     } 
    } 
    public class SmsSender implements Sender { 
     @Override 
     public void Send() { 
     System.out.println("this is sms sender!"); 
     } 
    }
    //工厂类
    public class SendFactory { 
     public Sender produce(String type) { 
     if ("mail".equals(type)) { 
     return new MailSender(); 
     } else if ("sms".equals(type)) { 
     return new SmsSender(); 
     } else { 
     System.out.println("请输入正确的类型!"); 
     return null; 
     } 
     } 
    }
    //测试类
    public class FactoryTest { 
     public static void main(String[] args) { 
     SendFactory factory = new SendFactory(); 
     Sender sender = factory.produce("sms"); 
     sender.Send(); 
     } 
    }
    

    工厂方法模式

    是对普通工厂方法模式的改进,在普通工厂方法模式中,如果传递的字符串出错,则不能正确创建对象,而工厂方法模式是提供多个工厂方法,分别创建对象。
    只需要对工厂类进行简单的修改:

    // 工厂方法模式 避免字符串有误创建不了实例 以及不需要实例化工厂 可以直接调用创建实例
    
    public class SendFactory { 
     public static Sender produceMail(){ 
     return new MailSender(); 
     } 
     public static Sender produceSms(){ 
     return new SmsSender(); 
     } 
    }
    

    工厂方法和简单工厂的一些区别就是 使用static以及不需要使用字符串来判断创建类型,避免创建null实例和可以不需要生成工厂对象直接调用生成具体产品实例的好处。

    工厂方法模式存在的问题

    工厂方法模式有一个问题就是,类的创建依赖工厂类,也就是说,如果想要拓展程序,必须对工厂类进行修改,这违背了闭包原则,所以,从设计角度考虑,有一定的问题,如何解决?就用到抽象工厂模式,创建多个工厂类,这样一旦需要增加新的功能,直接增加新的工厂类就可以了,不需要修改之前的代码。

    什么是抽象工厂模式

    抽象工厂模式是在简单工厂的基础上将未来可能需要修改的代码抽象出来,通过继承的方式让子类去做决定。

    //创建二者共同的接口
    public interface Sender { 
     public void Send(); 
    }
    //实现类
    public class MailSender implements Sender { 
     @Override 
     public void Send() { 
     System.out.println("this is mailsender!"); 
     } 
    } 
     
    public class SmsSender implements Sender { 
     
     @Override 
     public void Send() { 
     System.out.println("this is sms sender!"); 
     } 
    }
    //在提供一个接口
    public interface Provider { 
    public Sender produce(); 
    }
    //两个工厂类的实现
    public class SendMailFactory implements Provider { 
    
    @Override 
    public Sender produce(){ 
    return new MailSender(); 
    } 
    } 
    public class SendSmsFactory implements Provider{ 
    
    @Override 
    public Sender produce() { 
    return new SmsSender(); 
    } 
    }
    //测试类
    public class Test { 
    
    public static void main(String[] args) { 
    Provider provider = new SendMailFactory(); 
    Sender sender = provider.produce(); 
    sender.Send(); 
    } 
    }
    
    
    

    抽象工厂模式的好处:如果你现在想增加一个功能:发及时信息,则只需做一个实现类,实现Sender接口,同时 做一个工厂类,实现Provider接口,就OK了,无需去改动现成的代码。这样做,拓展性较好! 便于扩展。

    参考另一个抽象工厂方法模式

    
    // 抽象产品角色 动词用接口,名词用抽象
    public interface Moveable {
        void run();
    }
     
    // 具体产品角色
    public class Plane implements Moveable {
        @Override
        public void run() {
            System.out.println("plane....");
        }
    }
     
    public class Broom implements Moveable {
        @Override
        public void run() {
            System.out.println("broom.....");
        }
    }
     
    // 抽象工厂 名词用抽象
    public abstract class VehicleFactory {
        abstract Moveable create();
    }
     
    // 具体工厂
    public class PlaneFactory extends VehicleFactory {
        public Moveable create() {
            return new Plane();
        }
    }
     
    public class BroomFactory extends VehicleFactory {
        public Moveable create() {
            return new Broom();
        }
    }
     
    // 测试类
    public class Test {
        public static void main(String[] args) {
            VehicleFactory factory = new BroomFactory();
            Moveable m = factory.create();
            m.run();
        }
    }
    1
    

    同时,工厂方法模式中的工厂只生产单一的产品,而抽象工厂模式中的工厂生产多个产品,看如下示例:

    /抽象工厂类
    public abstract class AbstractFactory {
        public abstract Vehicle createVehicle();
        public abstract Weapon createWeapon();
        public abstract Food createFood();
    }
    //具体工厂类1,其中Food,Vehicle,Weapon是抽象类,
    public class DefaultFactory extends AbstractFactory{
        @Override
        public Food createFood() {
            return new Apple();
        }
        @Override
        public Vehicle createVehicle() {
            return new Car();
        }
        @Override
        public Weapon createWeapon() {
            return new AK47();
        }
    }
    
    //具体工厂类2,其中Food,Vehicle,Weapon是抽象类,
    public class FireFactory extends AbstractFactory{
        @Override
        public Food createFood() {
            return new Oil();
        }
        @Override
        public Vehicle createVehicle() {
            return new Star();
        }
        @Override
        public Weapon createWeapon() {
            return new Fire();
        }
    }
    //测试类
    public class Test {
        public static void main(String[] args) {
            AbstractFactory f = new DefaultFactory();
            Vehicle v = f.createVehicle();
            v.run();
            Weapon w = f.createWeapon();
            w.shoot();
            Food a = f.createFood();
            a.printName();
        }
    }
    
    
    

    相关文章

      网友评论

          本文标题:设计模式之工厂模式

          本文链接:https://www.haomeiwen.com/subject/jidaxktx.html