女娲采集黄土捏成人的形状,然后放到八卦炉中烧制,然后放到土地上生长,但是意外随时都会发生。
人类接口
/** * @atuhor sha1024 */ public interface Human { void getTalk(); void getColor(); } 复制代码
白人人类
/** * @atuhor sha1024 */ public class WhiteHuman implements Human{ @Override public void getTalk() { System.out.println("我是一个白人"); } @Override public void getColor() { System.out.println("我的皮肤是白色的"); } } 复制代码
黄色人种
/** * @atuhor sha1024 */ public class YellowHuman implements Human{ @Override public void getTalk() { System.out.println("黄种人说话最好听"); } @Override public void getColor() { System.out.println("我的皮肤是黄色的"); } } 复制代码
黑色人种
/** * @atuhor sha1024 */ public class BlackHuman implements Human{ @Override public void getTalk() { System.out.println("黑人说话听不懂"); } @Override public void getColor() { System.out.println("我的皮肤是黑色的"); } } 复制代码
定义一个抽象工厂,定义了一个泛型实现了Human
/** * @atuhor sha1024 */ public abstract class AbstarctHummanFactory { public abstract <T extends Human> T createHuman(Class<T> c); } 定义了一个人类工厂实现抽象人类工厂 public class HummanFactory extends AbstarctHummanFactory { @Override public <T extends Human> T createHuman(Class<T> c) { //定义一个人种 Human human = null; try{ human = (T)Class.forName(c.getName()).newInstance(); }catch (Exception e){ throw new RuntimeException("定义人种错误"); } return (T)human; } } 复制代码
女娲类,实现具体的场景
public static void main(String[] args) { AbstarctHummanFactory hummanFactory = new HummanFactory(); Human whiteHuman = hummanFactory.createHuman(WhiteHuman.class); whiteHuman.getColor(); whiteHuman.getTalk(); Human blackHuman = hummanFactory.createHuman(BlackHuman.class); blackHuman.getTalk(); blackHuman.getColor(); Human yellowHuman = hummanFactory.createHuman(YellowHuman.class); yellowHuman.getColor(); yellowHuman.getTalk(); SpringApplication.run(FactoryApplication.class, args); } 复制代码
执行结果
在工厂模式中,抽象产品类Product负责定义产品的共性,实现对事物最抽象的定义;Creator为抽象创建类,也就是抽象工厂,具体如何创建产品类是由具体的实现工厂ConcreateCreator完成的。 具体的产品类可以有多个,都继承抽象产品类
/** * 抽象产品类 * @atuhor sha1024 */ public abstract class Product { //产品类的公共方法 public void method1(){ System.out.println("我是抽象工厂方法1"); } /** * 抽象方法 */ public abstract void method2(); } 复制代码
产品类1
/** * @atuhor sha1024 */ public class ConcreateProduct1 extends Product { @Override public void method2() { /** * 具体业务逻辑 */ } } 复制代码
产品类2
/** * @atuhor sha1024 */ public class ConcreateProduct2 extends Product { @Override public void method2() { /** * 业务逻辑 */ } } 复制代码
抽象工厂
/** * @atuhor sha1024 */ public abstract class Creator { /** * 创建一个产品对象,其输入任何参数类型都可以自行设置 * 通常为String,Enum,Class,也可以为空 */ public abstract <T extends Product> T createProduct(Class<T> c); } 复制代码
具体如何产生一个产品对 对象是由具体的工厂实现类来决定的
/** * 通过发射获取到实例 * @atuhor sha1024 */ public class ConcreateCreator extends Creator{ @Override public <T extends Product> T createProduct(Class<T> c) { Product product = null; try{ product = (T)Class.forName(c.getName()).newInstance(); }catch (Exception e){ throw new RuntimeException(e.getMessage()); } return (T)product; } } 复制代码
场景类
/** * @atuhor sha1024 */ public class Client { public static void main(String[] args){ Creator creator = new ConcreateCreator(); Product product = creator.createProduct(ConcreateProduct1.class); /** * 业务逻辑 */ product.method2(); } } 复制代码
/** * @atuhor sha1024 */ public class NvWa { public static void main(String[] args){ Human human = HummanFactory2.createHuman(YellowHuman.class); Human human2 = HummanFactory2.createHuman(BlackHuman.class); } } 复制代码
运行结果没用发生变化,但是我们的类图变得更加简单了,因为简单所以我们称为简单工厂模式
定义一个抽象工厂
public abstract class AbstarctHummanFactory { public abstract Human createHuman(); } 复制代码
黑人人种创建工厂
public class BlackHummanFactory extends AbstarctHummanFactory { @Override public Human createHuman() { return new BlackHuman(); } } 复制代码
黄色人种创建工厂
public class YellowHummanFactory extends AbstarctHummanFactory { @Override public Human createHuman() { return new YellowHuman(); } } 复制代码
场景类
public static void main(String[] args){ Human yellowHuman = (new YellowHummanFactory()).createHuman(); yellowHuman.getTalk(); yellowHuman.getColor(); Human blackHuman = (new BlackHummanFactory()).createHuman(); blackHuman.getTalk(); blackHuman.getColor(); } 复制代码
运行结果还是相同的,每一个产品类都对应了一个创建类好处就是创建类职责清晰,而且结构简单,但是给可扩展性和维护性带来了一定的影响。
当然,在复杂的应用场景中一般采用多工厂模式,然后增加一个协调类,避免调用者和各个子工厂交流,对高层模块提供统一调用api。
public class Singleton { private Singleton(){} public void doSomeThing(){ //业务逻辑 } } 复制代码
单例类,Singleton保证不能通过正常情况下建立一个对象,只能通过反射方式创建
public class SingletonFactory { private static Singleton singleton; static { try{ Class c1 = Class.forName(Singleton.class.getName()); //获取无参构造函数 Constructor constructor = c1.getDeclaredConstructor(); //设置无参是可访问的 constructor.setAccessible(true); //产生一个实例对象 singleton = (Singleton) constructor.newInstance(); }catch(Exception e){ } } public static Singleton getSingleton(){ return singleton; } 复制代码
通过获得类构造器,然后设置访问权限,生成一个对象,然后提供外部访问,保证内部中的对象唯一。当然,其他的类也能通过反射的方式获得一个单例对象。
public class ProductFactory { private static final Map<String,Product> prMap = new HashMap<>(); public static synchronized Product createProduct(String type) throws Exception{ Product product = null; //判断缓存中是否有这个对象 if(prMap.containsKey(type)){ product = prMap.get(type); }else{ if(type.equals("Product1")){ product = new ConcreateProduct1(); }else{ product = new ConcreateProduct2(); } //同时缓存数据到prMap中 prMap.put(type,product); } return product; } } 复制代码
通过定义一个Map容器,容纳所有对象,如果Map容器中已经有的对象,则直接取出;如果没用,则根据需要的类型产生一个对象并放入到Map容器中。