工厂模式

2020-06-21  本文已影响0人  笔记本一号

一、简单工厂

定义:

简单工厂又称静态工厂方法模式是创建型模式,但是它不属于23种设计模式,其定义是由工厂对象决定创建哪一种产品类的实例,工厂可以根据参数的不同返回不同类的实例,被创建的实例通常都具有共同的父类

适用场景:

负责创建的对象较少,客户端不关心其创建的具体实现,只需要知道传入的参数类型

优点:

1、客户端不需要知道其中创建对象的细节,只需要传入正确的参数即可得到需要的对象
2、工厂具有一定的判断逻辑,决定在什么时候创建什么对象,客户免除了创建对象的责任,简单工厂模式通过这种做法实现了对责任的分割,它提供了专门的工厂类用于创建对象。
3、客户端不需要知道需要的产品的类名是什么,只需要知道对应创建产品所需要的参数是什么即可

缺点:

1、职责过重,增加新的产品时需要修改判断逻辑,违背了开闭原则
2、无法形成基于继承的等级结构

简单工厂1

public  class PhoneFactory {
    public static  Phone createPhone(String name){
        if (name.equalsIgnoreCase("huawei")){
            return new HuaWei();
        }else if (name.equalsIgnoreCase("iphone")){
            return new IPhone();
        }
        return null;
    }
}

简单工厂2

public  class PhoneFactory {
    public static  <T>T createPhone(Class<T> t){
        T obj=null;
        try {
            obj = t.newInstance();
        }catch (Exception e) {
            e.printStackTrace();
        }
        return obj;
    }
}

各个手机品牌的抽象类

public interface Phone {
    public void net();
    public void telephone();
}

还有一个HuaWei一样是实现了Phone 接口

public class IPhone implements Phone {
    @Override
    public void net() {
    }
    @Override
    public void telephone() {
    }
}

工厂的调用

public class Test {
    public static void main(String[] args) {
        IPhone iphone = PhoneFactory.createPhone(IPhone.class);
        HuaWei huaWei = PhoneFactory.createPhone(HuaWei.class);
        if ((iphone != null && iphone instanceof IPhone)) {
            System.out.println("iphone创建成功");
        } else {
            System.out.println("iphone创建失败");
        }
        if ((huaWei != null && huaWei instanceof HuaWei)){
            System.out.println("HuaWei创建成功");
        }else {
            System.out.println("HuaWei创建失败");
        }
    }
}
image.png

我们可以看到所有的手机,无论苹果还是华为都是它来生产,相当于富士康一样,要是有一天富士康出现罢工,所有的手机都得凉凉,任务沉重

image.png

前置知识

产品族与产品等级结构

产品族:属于同一主题的不同产品,抽象工厂主要针对产品族
产品等级:属于同一产品的不同主题,工厂方法主要针对产品等级
打比方:苹果既有苹果手机又有智能手表,同时小米和华为也是一样也有手机和智能手表,苹果的苹果手机和苹果智能手表是一个产品族,而小米的小米手机和小米智能手表属于一个产品族,华为的华为手机和华为智能手表属于一个产品族,而苹果手机、小米手机、华为手机是属于一个产品等级,苹果智能手表、小米智能手表、华为智能手表属于一个产品等级

image.png

二、工厂方法

定义:

工厂方法是创建型模式,属于23种设计模式,定义一个创建工厂的接口,让实现这个接口的子类决定创建哪些实例,工厂方法让类的实例化延迟到子类中进行

适用场景:

1、创建对象需要大量重复的代码
2、客户端不关心不依赖其创建的细节和实现

优点:

1、符合开闭原则,增强了可扩展性
2、客户端不关心其创建的细节,只需关心产品对应的工厂。

缺点:

1、类过多,增加系统的复杂性
2、抽象类过多,增加了系统的理解难度

创建一个手机工厂,手机工厂有抽象方法是分配给子类去做的事情,当然抽象类中可以有非抽象方法,非抽象方法是已经明确的具体业务,工厂可以自己做

public abstract class PhoneFactory {
    public abstract  Phone createPhone();
    public void say(){
        System.out.println("这是我能自己干的活,已经明确具体的事情");
    }
}

创建手机工厂的子类苹果手机工厂,手机工厂把创建苹果手机的职责分配给了苹果手机工厂,实现了责任的分割,所以苹果手机工厂符合单一原则

public class IPhoneFactory extends PhoneFactory {
    @Override
    public Phone createPhone() {
        return new IPhone();
    }
}

小米手机工厂是和苹果手机工厂同理的

public class XiaoMiFactory extends PhoneFactory{
    @Override
    public Phone createPhone() {
        return new XiaoMi();
    }
}

创建一个手机的抽象,对象可以共同继承一个父类,以父类作为声明,这个依赖倒置的思想

public interface Phone {
    public void net();
    public void telephone();
}

这个我们需要生产的产品、

public class IPhone implements Phone {
    @Override
    public void net() {
        System.out.println("苹果手机能上网");
    }
    @Override
    public void telephone() {

    }
}
public class XiaoMi implements Phone {
    @Override
    public void net() {
        System.out.println("小米手机能上网");
    }
    @Override
    public void telephone() {
    }
}

实践

public class Test {
    @org.junit.Test
    public void test1(){
        PhoneFactory iphoneFactory=new IPhoneFactory();
        Phone iphone =iphoneFactory.createPhone();
        iphone.net();
        PhoneFactory xiaomiFactory=new XiaoMiFactory();
        Phone xiaoMi =xiaomiFactory.createPhone();
        xiaoMi.net();
    }
}
image.png

责任分明的结构,把生产对应手机的责任分配给了其对应的子类,对比前面的简单工厂,手机工厂的担子轻松了很多

image.png

三、抽象工厂

定义:

抽象工厂是创建型模式,属于23种设计模式,定义一个创建工厂是一个可以提供一系列相关或者相互依赖的对象的接口,抽象工厂将具有同一主题的单独的工厂封装起来,在生产产品时可以生产一系列套餐的产品,也就是一个抽象工厂可以生产同一产品族的产品,客户端不需要知道工厂的生产的对象的具体类型,客户端仅仅只是使用这些具体对象的抽象类型表示

适用场景:

1、强调一系列相关产品属于一个配套,也就是这些对象属于一个产品族。创建这些相关产品套餐时需要大量重复代码
2、客户端不关心不依赖其创建的细节和实现
3、提供产品库,这些产品库以同一个接口出现,客户端不依赖其具体的实现

优点:

1、将一个属于一个套餐的产品一起生产,也就是统一一起生产属于同一个产品族的产品
2、客户端不关心其创建的细节。
3、职责分明,一个产品族工厂只生产自己的产品族的产品。

缺点:

1、抽象工厂规定了一个产品的套餐(产品族),所以工厂扩展困难,套餐要新加入新的产品时需要修改抽象工厂的接口
2、抽象类过多,增加了系统的抽象性和理解难度

创建一个产品工厂

public abstract class ProductFactory  {
    public abstract Phone createPhone();
    public abstract Watch createWatch();
    public void say(){
        System.out.println("这是我能自己干的活,已经明确具体的事情," +
                "我做我自己的事情,制造电子产品的任务交给子类就好了");
    }
}

苹果产品的工厂

public class AppleFactory extends ProductFactory {
    @Override
    public Phone createPhone() {
        return new IPhone();
    }
    @Override
    public Watch createWatch() {
        return new Iwatch();
    }
}

小米产品的工厂

public class XiaoMiFactory extends ProductFactory {
    @Override
    public Phone createPhone() {
        return new XiaoMiPhone();
    }
    @Override
    public Watch createWatch() {
        return new XiaoMiWatch();
    }
}

产品的抽象

public interface Phone {
     void telephone();
}
public interface Watch {
    void LookTime();
}

苹果手机

public class IPhone implements Phone {
    @Override
    public void telephone() {
        System.out.println("苹果手机可以打电话");
    }
}

苹果手环

public class Iwatch implements Watch {
    @Override
    public void LookTime() {
        System.out.println("苹果手环可以看时间");
    }
}

小米手机和小米手环

public class XiaoMiPhone implements Phone{
    @Override
    public void telephone() {
        System.out.println("小米手机可以打电话");
    }
}
public class XiaoMiWatch implements Watch {
    @Override
    public void LookTime() {
        System.out.println("小米手环可以看时间");
    }
}

实践

public class Test {
    @org.junit.Test
    public void test1(){
        //专门生产苹果产品的工厂
        ProductFactory apple=new AppleFactory();
        Phone iphone = apple.createPhone();
        Watch iwatch = apple.createWatch();
        iphone.telephone();
        iwatch.LookTime();
        //专门生产小米产品的工厂
        ProductFactory xiaomi=new XiaoMiFactory();
        Phone xiaomiPhone = xiaomi.createPhone();
        Watch xiaomiWatch = xiaomi.createWatch();
        xiaomiPhone.telephone();
        xiaomiWatch.LookTime();

    }
}
上一篇下一篇

猜你喜欢

热点阅读