effecitve java 1 静态工厂

  1. 什么是静态工厂的作用类似构造器
    public static Boolean valueOf(boolean b){
        return b ? Boolean.TRUE : Boolean.FALSE;
    }

     

  2. 与构造器相比,使用静态工厂有以下好处
    1. 静态工厂可以有名字,但是构造器是没有自己的名字的,他的名字只能和类名相同,就像BigInteger.problePrime方法一样。方法签名和参数的个数,顺序都有关系,如果类提供了两个构造器的参数一样,仅仅是参数的顺序不一眼的话,那么会给用户带来麻烦。
      BigInteger.probablePrime(int bitLength, Random rnd)
      // 从方法名就可以看出来这是返回一个素数的方法
      new BigInter(int bitLength, Random rnd)
      // 如果是这这样子就看不出来了

       

    2. 因为构造器没有返回值,所以没有办法在构造器中实现单例模式,下边这样子的代码是会报错的,所以,使用静态工厂方法可以不用每次调用的时候都产生一个新对象
      public class ConstructorTest {
      
          ConstructorTest constructorTest;
      
          public ConstructorTest() {
              if(null == constructorTest){
                  constructorTest = new ConstructorTest();
              }
              return constructorTest;
          }
      }

       

    3. 书中原话是:使用静态工厂方法可以返回原类型的任何子类型。例子如下:由于接口中的成员变量的访问权限都是public的,java8之后接口中可以有静态方法,如果这些静态方法是工厂方法的话,那么久可以返回这个接口的实现类,对于用户来说,知道的只是这个接口,而不是这个具体哪个实现类
      1. 定义一个汽车接口,其中有一个getCar方法,可以返回一个Car实现类实例
      2. 定义一个Benz类实现Car接口
      3. 定义一个CarMaker类,这个类负责new Beanz对象,同时这个类是包级私有的,普通用户不知道这个类
      4. 接口的getCar方法中实际上是使用CarMaker类去创建Benz对象的,然后把Benz返回
        package staticpackagemethod.advantadge1;
        
        public class Benz implements Car {
        
            String  year;
        
            public Benz() {
        
            }
        
            public String getYear() {
                return year;
            }
        
            public void setYear(String year) {
                this.year = year;
            }
        
            @Override
            public void drive() {
                System.out.println("benz drive" + year);
            }
        
            @Override
            public void stop() {
                System.out.println("benz stop" + year);
            }
        }
        
        package staticpackagemethod.advantadge1;
        
        class CarMaker {
        
            static Benz car;
        
           static   Car makeCar(){
                if (null == car){
                  car =     new Benz();
                  car.setYear(String.valueOf(System.currentTimeMillis()));
                  return  car;
                }
                return car;
            }
        
        }
        
        package staticpackagemethod.advantadge1;
        
        public interface Car {
        
            void drive();
            void stop();
        
            static Car getCar(){
                return CarMaker.makeCar();
            }
        }
        
        public class TestCar {
            public static void main(String[] args) {
                // 接口Car的getCar方法普通用户不知道具体调用的是什么
                Car.getCar().drive();
                Car.getCar().drive();
            }
        }
        

         

      5. 静态工厂方法可以在调用的时候根据参数不一样返回不一样的具体事例,就像EnumSet的工厂方法就可以根据传入的参数不同,构建出不同的对象返回,上边这个例子也可以,根据价格不同返回奔驰或者奥拓
      6. 有个东西叫做服务提供者框架,也是基于静态工厂的。由以下三个部分组成
        1. 服务接口,服务提供者具体提供服务的一些接口和类
        2. 提供者注册API,服务提供者用来向框架注册自己的一些API
        3. 服务访问:客户端访问框架的API
        4. 网上借鉴的例子:
          1. SaltManager类维护一个map,提供注册方法,Provider类可以注册进来
          2. Provider接口,意思为“盐提供商”,不同的提供商提供不通过的盐,Provider的实现类在静态代码块向SaltManager类注册了相关信息。并且实现getSalt方法,将不同的Salt对象返回回去
          3. Salt类,“盐类”,就是普通的盐,不是什么加盐之类的东西
          4. 客户端在使用的时候将对应Provider的实现类加载进来,那么就会执行对应的静态代码块,将不同的Provider注册进去,然后调用Manager.getProvider方法,然后把比如“海盐”当作参数传进去,Manager就会找到对应的Provider,创建出对应的salt对象,返回回来
            package staticpackagemethod.salttest;
            
            public interface SaltProvider {
                Salt getSalt();
            }
            
            package staticpackagemethod.salttest;
            
            public class BaySaltProvider implements SaltProvider {
                static {
                        SaltManager.registerProvider("bay", new BaySaltProvider());
                }
            
                @Override
                public Salt getSalt() {
                    return new BaySalt();
                }
            }
            
            package staticpackagemethod.salttest;
            
            public class InlandSaltProvider implements SaltProvider {
                static {
                    SaltManager.registerProvider("inlandSalt", new InlandSaltProvider());
                }
            
                @Override
                public Salt getSalt() {
                    return new InlandSalt();
                }
            }
            
            package staticpackagemethod.salttest;
            
            public interface Salt {
                void addIodine();
            }
            
            package staticpackagemethod.salttest;
            
            public class BaySalt implements Salt {
                @Override
                public void addIodine() {
            
                }
            }
            
            package staticpackagemethod.salttest;
            
            public class InlandSalt implements Salt {
                @Override
                public void addIodine() {
            
                }
            }
            
            package staticpackagemethod.salttest;
            
            import java.util.HashMap;
            import java.util.Map;
            
            public class SaltManager {
                private static final Map<String, SaltProvider> providers = new HashMap<>();
                public static void registerProvider(String name, SaltProvider p){
                    providers.put(name, p);
                }
            
                public static  Salt getSalt(String name){
                    return providers.get(name).getSalt();
                }
            
            }
            
            package staticpackagemethod.user;
            
            import staticpackagemethod.salttest.Salt;
            import staticpackagemethod.salttest.SaltManager;
            
            public class TestSalt {
                public static void main(String[] args) throws ClassNotFoundException {
                    Class.forName("staticpackagemethod.salttest.InlandSaltProvider");
                    Salt salt =  SaltManager.getSalt("inlandSalt");
                    salt.addIodine();
                }
            }
            

             

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值