创建型——工厂系列(Factory)day04

  • 任何可以产生对象的方法或类,都可以称为工厂
  • 单例也是一种工厂
  • 为什么有了new以后,还要有工厂?
    1、灵活控制生产过程
    2、权限、修饰、日志……

接口模式

在这里插入图片描述

package cn.xhl.interfacemodel;

public interface IFruit {
	public void plant();
	public void harvest();
	public void grow();
}
package cn.xhl.interfacemodel;

public class Apple implements IFruit {
	int treeAge = 5;
	public void plant() {
		// TODO Auto-generated method stub
		log("苹果种植ֲ********");
	}

	public void harvest() {
		// TODO Auto-generated method stub
		log("苹果收获******");
	}
	public void grow() {
		// TODO Auto-generated method stub
		log("苹果增长****");
	}
	public static void log(String msg) {
		System.out.println(msg);
	}

}
package cn.xhl.interfacemodel;

public class Grape implements IFruit {
	boolean seedful=false;
	public void plant() {
		// TODO Auto-generated method stub
		log("葡萄种植ֲ********");
	}

	public void harvest() {
		// TODO Auto-generated method stub
		log("葡萄收获******");
	}
	public void grow() {
		// TODO Auto-generated method stub
		log("葡萄生长****");
	}
	public static void log(String msg) {
		System.out.println(msg);
	}

}
package cn.xhl.interfacemodel;

public class Strawberry implements IFruit {

	public void plant() {
		// TODO Auto-generated method stub
		log("草莓种植********");
	}

	public void harvest() {
		// TODO Auto-generated method stub
		log("草莓收获******");
	}
	public void grow() {
		// TODO Auto-generated method stub
		log("草莓生长****");
	}
	public static void log(String msg) {
		System.out.println(msg);
	}

}
package cn.xhl.interfacemodel;

public class Client1 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		IFruit[] fruits = {new Grape(),new Strawberry(),new Apple()};
		for(IFruit fruit : fruits) {
			fruit .plant();
			fruit.grow();
			fruit .harvest();
		}
	}

}

简单工厂模式

在这里插入图片描述
一般情况下我们可以用一个FruitFactory去创建不同的Fruit

public class FruitFactory{
	public IFruit creatApple(){
		//进行一些前置操作,例如设置权限、进行修饰、打印日志……
		return new Apple();
	}
	public IFruit creatGrape(){return new Grape();}
	public IFruit creatStrawberry(){return new Strawberry();}
}

但是这不符合开闭原则,每次新增一个品种的IFruit都需要对Factory进行改动。

我们可以对简单工厂模式进行改进,让它符合开闭原则。

package cn.xhl.simpleFactory;

public class FruitGardent {
	public static IFruit factory(String which) throws InstantiationException, IllegalAccessException, ClassNotFoundException {
		IFruit fruit = null;
		String pn = FruitGardent.class.getPackage().getName();
		StringBuilder sb = new StringBuilder();
		sb.append(pn);
		sb.append(".");
		sb.append(Character.toUpperCase(which.charAt(0)));
		sb.append(which.substring(1).toLowerCase());
		fruit = (IFruit) Class.forName(sb.toString()).newInstance();
		return fruit;
	}
}

package cn.xhl.simpleFactory;

public class Client1 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		String[] strs = {"grape","apple","strawberry"};
		for(String str : strs) {
			IFruit fruit;
			try {
				fruit = FruitGardent.factory(str);
				fruit.plant();
				fruit.harvest();
			} catch (InstantiationException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IllegalAccessException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (ClassNotFoundException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}

}

但是这有产生了新的问题,如果对不同的产品对应需要给到不同的权限,也就是在new之前需要进行一些前置操作,且不同的IFruit操作不一样,这样就需要在前面加上判断的语句,判断这是什么IFruit,再进行一些权限设置,最后再创建对象,但这又不符合开闭原则了。

于是我们可以对每一个产品,也就是每一个IFruit都用一个Factory,这样就引出了工厂方法模式。

工厂方法模式

工厂方法方便产品的扩展
在这里插入图片描述

package factory1;

public class Client1 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		String[] strs = {"ConcreateCreator1","ConcreateCreator2"};
		for (String str : strs) {
			try {
				Creator creator = CreatFactory.factory(str);
				creator.factory().show();
			} catch (InstantiationException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IllegalAccessException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (ClassNotFoundException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			
		}
	}
package factory1;

public class CreatFactory {
	public static Creator factory(String which) throws InstantiationException, IllegalAccessException, ClassNotFoundException {
		Creator creator = null;
		
		
		StringBuilder sb = new StringBuilder();
		sb.append(CreatFactory.class.getPackageName());
		sb.append(".");
		sb.append(which);
		creator = (Creator) Class.forName(sb.toString()).newInstance();
		return creator;
	}
}
package factory1;

public interface Creator {
	public Product factory();
}
package factory1;

public class ConcreateCreator1 implements Creator {

	@Override
	public Product factory() {
		// 可以进行一些前置操作,例如设置权限、进行修饰、打印日志……
		return new ConcreateProduct1();
	}

}

package factory1;

public class ConcreateCreator2 implements Creator {

	@Override
	public Product factory() {
		// TODO Auto-generated method stub
		return new ConcreateProduct2();
	}

}

package factory1;

public interface Product {
	public void show();

}
package factory1;

public class ConcreateProduct1 implements Product {

	@Override
	public void show() {
		// TODO Auto-generated method stub
		System.out.println("This is Product1111 show");
	}

}
package factory1;

public class ConcreateProduct2 implements Product {

	@Override
	public void show() {
		// TODO Auto-generated method stub
		System.out.println("This is Product2222 show");
	}

}

抽象工厂模式

抽象工厂在于产品族的扩展
工厂方法是只有一种产品族的抽象工厂
在这里插入图片描述

package abstractFactory;

public interface Shape {
	public void draw();
}
package abstractFactory;

public class Circle implements Shape {

	@Override
	public void draw() {
		// TODO Auto-generated method stub
		System.out.println("画一个圆");
	}

}
package abstractFactory;

public class Rectangle implements Shape {

	@Override
	public void draw() {
		// TODO Auto-generated method stub
		System.out.println("画一个矩形");
	}

}

package abstractFactory;

public class Square implements Shape {

	@Override
	public void draw() {
		// TODO Auto-generated method stub
		System.out.println("画一个正方形");
	}

}
package abstractFactory;

public interface Color {
	public void draw();
}

package abstractFactory;

public class Bule implements Color {

	@Override
	public void draw() {
		// TODO Auto-generated method stub
		System.out.println("涂蓝色");
	}

}
package abstractFactory;

public class Green implements Color {

	@Override
	public void draw() {
		// TODO Auto-generated method stub
		System.out.println("涂绿色");
	}

}

package abstractFactory;

public class Red implements Color {

	@Override
	public void draw() {
		// TODO Auto-generated method stub
		System.out.println("涂红色");
	}

}
package abstractFactory;

public class ShapeFactory implements AbstractFactory {

	@Override
	public Color getColor(String color) {
		// TODO Auto-generated method stub
		return null;
	}


	@Override
	public Shape getShape(String shape) {
		// TODO Auto-generated method stub
		Shape sh=null;
		String pn = ShapeFactory.class.getPackageName();
		StringBuilder sb = new StringBuilder();
		sb.append(pn);
		sb.append(".");
		sb.append(Character.toUpperCase(shape.charAt(0)));
		sb.append(shape.substring(1).toLowerCase());
		try {
			sh=(Shape) Class.forName(sb.toString()).newInstance();
		} catch (InstantiationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		return sh;
	}
}

package abstractFactory;

public class ColorFactory implements AbstractFactory {
	public Color getColor(String color) {
		Color cl=null;
		String pn = ColorFactory.class.getPackageName();
		StringBuilder sb = new StringBuilder();
		sb.append(pn);
		sb.append(".");
		sb.append(Character.toUpperCase(color.charAt(0)));
		sb.append(color.substring(1).toLowerCase());
		try {
			cl=(Color) Class.forName(sb.toString()).newInstance();
		} catch (InstantiationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		return cl;
	}

	@Override
	public Shape getShape(String shape) {
		// TODO Auto-generated method stub
		return null;
	}
}

package abstractFactory;

public interface AbstractFactory {
	public Shape getShape(String shape);
	public Color getColor(String color);
}

package abstractFactory;

public class FactoryProducer {
	public static AbstractFactory getFactory(String which) {
		AbstractFactory af=null;
		String pn = FactoryProducer.class.getPackageName();
		StringBuilder sb = new StringBuilder();
		sb.append(pn);
		sb.append(".");
		sb.append(which);
		try {
			af = (AbstractFactory) Class.forName(sb.toString()).newInstance();
		} catch (InstantiationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return af;
	}
}

package abstractFactory;

public class Client {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		String[] shapes = {"circle","square","RECTANGLE"};
		String[] colors = {"bule","red","GREEN"};
		String[] factory = {"ShapeFactory","ColorFactory"};
		for(String f : factory) {
			AbstractFactory af = FactoryProducer.getFactory(f);
			for(String c : colors) {
				if(af.getColor(c)!=null) {
					af.getColor(c).draw();
				}
			}
			for(String s : shapes) {
				if(af.getShape(s)!=null) {
					af.getShape(s).draw();
				}
			}
		}
	}

}

总结

  • 简单工厂:把对象的创建放到一个工厂类中,通过参数来创建不同的对象。这个缺点是每添一个对象,就需要对简单工厂进行修改(尽管不是删代码,仅仅是添一个switch case,但仍然违背了“开闭”原则。
  • 工厂方法:每种产品由一种工厂来创建,是将创建对象的逻辑与任务交给工厂类,如果增加一个具体的产品,不用像简单工厂方法那样修改里面的代码,可以直接扩展,遵循 “开闭”原则
  • 抽象工厂:是工厂方法模式的进一步推广化和抽象化,扩充和升级,在抽象工厂模式中抽象产品可能是一个或者多个,从而构成了一个或多个产品族,只有一个产品族的抽象工厂模式就是工厂方法模式,一般是大项目用。
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值