工厂模式

简单工厂模式

工厂模式就是通过工厂类来帮助我们new新的对象,然后我们就不用自己去new对象了。比如我们想要鱼肉直接new Fish() 就好了,工厂模式就是弄个厨房(工厂类),然后有工厂类来new Fish(),这样我们要通过调用工厂的 cook 烹饪方法来 new Fish();简单的说就是多用了一个类绕了一圈才得到我们想要的对象。

这个是 食物Class 里面 有食物的名字和 say 方法。


public abstract class Food {
	public String name;
	
	public void say() {
	}
}

然后我们提供了两种食物原料 牛 和 鱼

public class Beef extends Food{
	public Beef(String name) {
		this.name = name;
	}
	
	@Override
	public void say() {
		System.out.println("我是牛肉!");
	}
}

public class Fish extends Food{
	public Fish(String name) {
		this.name = name;
	}
	
	@Override
	public void say() {
		System.out.println("我是鱼肉!");
	}
}

现在我们要吃牛肉或者鱼肉 都需要一个厨房,这个厨房也就是工厂模式中的工厂。

public class CookRoom {
	public Food cook(String name) {
		Food food = null;
		switch (name) {
		case "牛":
			food =  new Beef("麻辣牛肉");
			break;
		case "鱼":
			food =  new Fish("麻辣小鱼");
			break;
		default:
			break;
		}
		return food;
	}
}

现在我们想吃什么,就只需要传递原料到厨房就好了。

public class Test {
	public static void main(String[] args) {
		Food food1  =  new CookRoom().cook("牛");
		food1.say();
		
		Food food2  =  new CookRoom().cook("鱼");
		food2.say();
		
	}
}

厨房就相当于工厂,只需要将原料传递进去 ,出来的就是成品。(感觉就是不用 我们自己new了,工厂就可以帮我们new了)


============================(这个可以不着急看,有点难以理解,看不懂的直接跳过)=========================================

简单工厂模式的反射应用


之前看完了简单工厂模式,不知道有啥用,感觉是多此一举,接下来我们看看结合反射的应用。

我的厨房(工厂)能做牛肉也能做鱼肉,如果现在想吃狗肉呢,是不是要改代码?太麻烦了,然后我们来个不用改代码的。


public class CookRoom {
	public Food cook(String name) {
		Food food = null;
		try {
			Class cl = Class.forName(name);
			Constructor constructor =  cl.getConstructor(String.class);
			food = (Food) constructor.newInstance("食物");
			
		} catch (Exception e) {
			e.printStackTrace();
		}
		return food;
	}
}


对厨房进行升级完毕。我们不用在提供食物原料给厨房了,只需要告诉厨房,我们要吃的原料在哪就好了,它会自己找的。

public class Test {
	public static void main(String[] args) {
		Food food1  =  new CookRoom().cook("com.sun.factory.Beef");
		food1.say();
		
		Food food2  =  new CookRoom().cook("com.sun.factory.Fish");
		food2.say();
		
		Food food3  =  new CookRoom().cook("com.sun.factory.Dog");
		food3.say();
		
	}
}

厨房知道食物的原料在哪就可以做饭了,是不是更简单了。这样我们想是狗肉,也不用改代码了,只需要改下配置就好了。(实体类我统统放在了com.sun.factory包下面)。

对了狗肉的代码,也贴出来。

public class Dog extends Food{
	public Dog(String name) {
		this.name = name;
	}
	
	@Override
	public void say() {
		System.out.println("我是狗肉!");
	}
}


==============================================END===================================================


工厂方法模式

鱼肉 牛肉 还是不变,现在呢 要用两个工厂来生产了。一个厨房做不出来了。

public class beefFactory {
	public Food cook() {
		return new Beef("麻辣牛肉");
	}
}


public class FishFactory {
	public Food cook() {
		return new Fish("麻辣小鱼");
	}
}

public class Test {
	public static void main(String[] args) {
		
		Food beefFood =	new beefFactory().cook();
		beefFood.say();
		
		Food fishFood = new FishFactory().cook();
		fishFood.say();
		
	}
}

原本在一个厨房(工厂)里可以生产的牛肉和鱼肉 现在要在两个工厂里生产了。也就是 牛肉工厂 和 鱼肉工厂。现在我们需要什么食物直接找工厂就好。


抽象工厂模式

这个模式比较有意思,之前吃肉 找 工厂,现在工厂都找不到了。(现在我们给工厂在整一个创造者,也就是说我们不用再new工厂了)。

我们要找工厂,那就先找某工厂的创造者,然后让工厂的创造者来帮我们new某工厂。(听起来很熟悉啊!你懂的。)

之前我们要找某个工厂就需要new一下,如果要喝果汁,那就需要在new 一个果汁工厂。现在让工厂创造者帮我们new 个果汁工厂就好了。

先写一个抽象工厂(也就是工厂抽象方法)。里面放了 cook 烹饪,和 juicing榨汁两个方法。

public abstract class AbstractFactory {
	public Food cook() {
		return null;
	}
	
	public Juice juicing() {
		return null;
	}
}

在来看看果汁的抽象类

public abstract class Juice {
	public String name;
	
	public void say() {
	}
}


苹果汁

public class AppleJuice extends Juice{
	public AppleJuice(String name) {
		this.name = name;
	}
	
	@Override
	public void say() {
		System.out.println("我是苹果汁");
	}
}

果汁的工厂

public class JuiceFactory extends AbstractFactory{
	@Override
	public Juice juicing() {
		return new AppleJuice("鲜榨苹果汁");
	}
}


工厂的生产者(有了它,我们就不用自己去建立工厂了,想要啥工厂给他说就好了)

//工厂的生产者(相当于工厂的工厂)
public class FactoryProducer {
	public AbstractFactory getFactory(String factoryName) {
		AbstractFactory factory = null;
		switch (factoryName) {
		case "牛肉工厂":
			factory = new beefFactory();
			break;
		case "鱼肉工厂":
			factory = new FishFactory();
			break;
		case "果汁工厂":
			factory = new JuiceFactory();
			break;

		default:
			break;
		}
		return factory;
	}
}


有了工厂创造者,我们想要啥工厂就有啥工厂了。

public class Test {
	public static void main(String[] args) {
		//声明抽象工厂
		AbstractFactory factory  =  null;
		//new一个工厂的创造者
		FactoryProducer factoryProducer = new FactoryProducer();
		
		
		//去工厂的创造者那 获取工厂
		factory = factoryProducer.getFactory("牛肉工厂");
		//去工厂里 获取食物
		Food  food = factory.cook();
		food.say();

                factory = factoryProducer.getFactory("鱼肉工厂");
		food = factory.cook();
		food.say();
		
		
		factory = factoryProducer.getFactory("果汁工厂");
		Juice juice = factory.juicing();
		juice.say();
		
	}
}


==============================(老规矩,这部分还是反射加工厂)==================================================

抽象工厂反射应用

改造创造者类


public class FactoryProducer {
	public AbstractFactory getFactory(String factoryName) {
		AbstractFactory factory = null;
                try {
			Class cl = Class.forName(factoryName);
			factory =  (AbstractFactory) cl.newInstance();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return factory;
	}
}


看下实现方法。这样我们是不是又可以不用改代码直接修改我们要获取的工厂了。

public class Test {
	public static void main(String[] args) {
		//声明抽象工厂
		AbstractFactory factory  =  null;
		//new一个工厂的创造者
		FactoryProducer factoryProducer = new FactoryProducer();
		
		factory = factoryProducer.getFactory("com.sun.factory.beefFactory");
		Food  food = factory.cook();
		food.say();
		
		factory = factoryProducer.getFactory("com.sun.factory.JuiceFactory");
		//去工厂里 获取食物
		Juice juice = factory.juicing();
		juice.say();
	}
}

======================================================END=====================================================================


至此我们所有的内容基本完成。还剩下几个问题。

1、会不会有工厂创造者的工厂呢?

2、工厂模式有什么具体用途吗?(有人说是为了解耦和,解耦和一直不懂,也不知道解耦和有啥用?)

3、大家看完以后,会不会感觉工厂模式是多此一举呢?(反正我是这样认为的)


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值