Java设计模式-工厂模式笔记

工厂模式之所以叫工厂,就是因为工厂里面会new产品

1 简单工厂模式

1.1 不好的实现方法(无工厂)
1.1.1角色组成
  1. 抽象产品角色,为具体产品提供接口
  2. 具体产品角色,继承抽象产品的接口并覆写方法
  3. 使用类,分别创建具体产品角色,调用它的方法
1.1.2 具体实现

开餐厅,首先定义什么是食物

//1抽象产品角色 
package com.Food;

public interface Food {
	public void cook();
}

准备几个食物的做法

//2具体产品角色
package com.menu;
import com.Food.Food;

public class Meat implements Food{
@Override
	public void cook() {     //覆写继承来的cook方法
		system.out.println("炒一盘小炒肉!")}
}

public class Fish implements Food{
	@Override
	public void cook() {     //覆写继承来的cook方法
		system.out.println("炒一盘鱼香肉丝!")}
}

public class Duck implements Food{
	@Override
	public void cook() {     //覆写继承来的cook方法
		system.out.println("炒一盘鸭鸭!")}
}

客人到店后开始点餐。

//3使用类
package com;
import com.Food.Food;
import com.menu.Duck;
import com.menu.Meat;
import com.menu.Fish;

public class Customer{

	public static void main(String[] args) {
		Food food= new Meat();//new其中一个具体产品
		food.cook();//调用具体覆写的cook方法
		Food food2= new Duck();
		Food2.cook();
	}
}
1.1.3 方法解读
  1. 定义一个接口Food为所有食物总类,所有事物都内有一个cook方法,3种食物继承了总食物接口并覆写具体的cook方法
  2. 客人到店,创建(new)3种食物class中的一种,并调用它的cook方法(相当于客人直接炒菜)
1.1.4 缺点

三个实现类和接口紧密的绑定到了一起,代码耦合出现严重问题,不利于以后的维护

1.2 进化版实现方法【简单模式里面最经典的】
1.2.1 角色组成
  1. 抽象产品角色:由接口或者抽象类来实现,为3提供接口。
  2. 具体产品角色:由一个具体类实现,等着1工厂类来创建的我。
  3. 工厂类角色:往往由一个具体类实现,创建2具体产品角色。【新增】
  4. 使用类:创建工厂类,由工厂类创建某个具体产品,再调用具体产品的具体方法
1.2.2 具体实现
//2抽象产品角色 
public interface Car{ 
	public void drive(); 
} 
//3具体产品角色 
public class Benz implements Car{ 
	public void drive() { 
		System.out.println("Driving Benz "); 
	} 
} 
public class Bmw implements Car{ 
	public void drive() { 
		System.out.println("Driving Bmw "); 
	} 
} 
public class AD implements Car{ 
	public void drive() { 
		System.out.println("Driving AD "); 
	} 
} 
//1工厂类角色 ——相当于简单工厂模式上菜增加服务员,告诉后厨客人要什么菜
public class Driver{ 
	//工厂方法 
	//注意 返回类型为抽象产品角色 
	public static Car driverCar(String s) throws Exception { 
		
		//判断逻辑,返回具体的产品角色给Client 
		if(s.equalsIgnoreCase("Benz")) return new Benz(); 
		
		else if(s.equalsIgnoreCase("Bmw")) return new Bmw(); 
		
		else if(s.equalsIgnoreCase("AD")) return new AD();
		
		else throw new Exception(); 
	}
}
//老板,是使用类
public class Magnate{ 
	public static void main(String[] args) { 
	Try { 
		//告诉司机(工厂类)我今天坐奔驰 
		Car car = Driver.driverCar("benz"); 
		
		//下命令:开车 
		//这里不同的车,但是写法一样,调用他们覆写的drive方法
		car.drive(); 
		
	}catch(){}
}
1.2.3 方法解读
  1. 首先定义一个接口car,内有一个drive方法(1抽象产品角色)
  2. 定义几种不同类型的车,他们都继承接口并覆写drive方法(2具体产品角色)
  3. 定义一个司机,他通过字符串接收老板的信号,知道老板今天想开什么车,如果是想开奔驰则new一台奔驰给老板(3工厂类角色)
  4. 老板创建一个Car类的变量car,通过上一步创建的司机的方法得到返回的new benz(),现在老板创建的变量car就对应了一个new出来的新车,再调用该车的drive方法
1.2.4 优缺点

优点:客户端免除了直接创建产品对象的责任,而仅仅负责"消费"产品
缺点:

  1. 每增加一辆车,都要在工厂类中增加相应的逻辑
  2. 只有一个工厂类
  3. 不支持不同产品需要不同参数,而且传错参数的容错率不高
1.3 多方法静态工厂(增加参数)

该方法为不同产品提供不同的生产方法,使用时需要哪种产品就调用该种产品的方法,使用方便、容错率高。

该方法仅是用于改进1.2的第三个缺点。
具体实现如下:

//抽象类
package com.hdnav;
	public interface Food{
		public void cook();
}
//实现类
package com.hdnav;

public class Meat implements Food{
	String param;
	public Meat(String param) {
		this.param = param;
	}
	
	@Override
	public void cook() {
		system.out.println("来盘小炒肉!"+param);
	}
}


public class Fish implements Food{

	@Override
	public void cook() {     //覆写继承来的cook方法
		system.out.println("炒一盘鱼香肉丝!")}
}

public class Duck implements Food{

	@Override
	public void cook() {     //覆写继承来的cook方法
		system.out.println("炒一盘鸭鸭")}
}
//工厂类
package com.hdnav;
public class CookFactory {
	public static Food createMeet(String param) {
		return new Meet(param);
	}
	
	public static Food createFish() {
		return new Fish();
	}
	
	pubiic static Food createDuck() {
		return new Duck();
	}
}
//使用类
package com.hdnav;
public class Test {
	public static void main(string[ ] args) {
	
	Food meetCooker = CookFactory.createMeet("三分熟")﹔
	meatCooker.cook();
	
	Food duckCooker = CookFactory.createDuck();
	duckCooker.cook();
	
	Food fishCooker = CookFactory.createFish();
	fishCooker.cook();
	
	}
}

分析:
相当于静态的改写某一个方法,增加了一个参数

2 工厂方法模式

2.1 角色组成
  1. 抽象产品角色:由抽象类或者接口来实现,为具体产品提供接口。
  2. 具体产品角色:由具体类实现,继承抽象产品的接口,实现具体产品独特的使用方法
  3. 抽象工厂角色:由抽象类或者接口来实现,为具体工厂提供接口。
  4. 具体工厂角色:由具体的类来实现,生产2具体产品。【新增】——相当于给原来的司机增加小弟,不是一个司机创造所有车而是不同司机创造不同的车(原来的司机成为一个抽象大工厂,小弟成为具体小工厂)
  5. 使用类:创建具体工厂,由该具体工厂创建对应的具体产品,调用具体产品的使用方法
2.2 具体实现
//1抽象产品角色 
public interface Car{ 
	public void drive(); 
} 
//2具体产品角色 
public class Benz implements Car{ 
	public void drive() { 
		System.out.println("Driving Benz "); 
	} 
} 
public class Bmw implements Car{ 
	public void drive() { 
		System.out.println("Driving Bmw "); 
	} 
} 
public class AD implements Car{ 
	public void drive() { 
		System.out.println("Driving AD "); 
	} 
} 
//3抽象工厂角色 
public interface Driver{ 
	public Car driverCar(); 
} 
//4具体工厂角色
public class BenzDriver implements Driver{ 
	public Car driverCar(){ 
		return new Benz(); 
	} 
} 
public class BmwDriver implements Driver{ 
	public Car driverCar() { 
		return new Bmw(); 
	} 
} 
public class ADDriver implements Driver{ 
	public Car driverCar() { 
		return new AD(); 
	} 
} 
//5 使用类
public class Magnate 
{ 
	public static void main(String[] args) 
	{ 
		Try { 
		
		Driver driver = new BenzDriver(); 
		Car car = driver.driverCar(); 
		car.drive(); 
		
		} catch(Exception e) 
		{} 
	} 
}
2.3 解读
  1. 定义抽象产品角色Car类,定义一个方法drive。(每个车都有被开的方法)
  2. 定义具体产品角色Benz/BMW等,覆写drive方法。(具体描述每个车是怎么开的)
  3. 定义抽象工厂角色Driver类,定义一个Car类的drivecar方法(会造各种车的司机大类)
  4. 定义具体工厂角色,覆写Car类的drivecar方法(即new一个Benz并返回)(具体创造某个车的小司机)
  5. 使用类,先创造一个小司机(具体工厂)(new一个奔驰司机,用一个Driver类的变量driver来接),再让刚刚创造的小司机(具体工厂)造车(具体产品)(调用小司机的driverCar方法,new一台车),再开这个车(调用车的drive方法)

3 抽象工厂模式

3.1 与工厂方法的区别

原来工厂方法要增加新产品(增加飞机而不是新类别的车)的话,就要重新增加一个抽象工厂,然后再增加具体工厂,类别多了抽象工厂数量会大增。而抽象工厂模式把不同产品放到一个抽象工厂里面,比如A厂=A车+A飞机,而不是A车厂=A车,A机场=A机。

工厂方法模式提供的所有产品都是衍生自同一个接口或抽象类
而抽象工厂模式所提供的产品则是衍生自不同的接口或抽象类

3.2 角色组成

与工厂方法一样,只是抽象工厂的内部多了东西。

  1. 抽象工厂角色:为具体工厂提供接口,提供所有抽象产品。
  2. 具体工厂角色:由具体的类来实现,继承抽象工厂的接口。生产具体产品。
  3. 抽象产品角色:由抽象类或者接口来实现,等具体产品继承。
  4. 具体产品角色:具体的类来实现,继承抽象产品接口。
  5. 使用类:创建具体工厂,由该具体工厂创建对应的具体产品,调用具体产品的使用方法
3.3 具体实现
//抽象产品
package com.long88.ad.test;
 
interface  Car {
    public void getCar();
}
interface  Plane{
    public void getPlane();
}
interface Boat{
	Public void getBoat();
}
//Car的具体产品 
public class BMW implements Car{
 
    @Override
    public void getCar() {
        System.out.printf("来一辆BMW!");
    }
}
public class BYD implements Car {
    @Override
    public void getCar() {
        System.out.printf("来一辆BYD!");
    }
}
-----------------------------------
//Plane的具体产品
public class AirPlane implements Plane{
 
    @Override
    public void getPlane() {
        System.out.printf("来一架客机!");
    }
}
public class BattlePlane implements Plane{
    @Override
    public void getPlane() {
        System.out.printf("来一架战斗机!");
    }
}
-----------------------------------
//Boat的具体产品 
public class ABoad implements Boat{
 
    @Override
    public void getBoat() {
        System.out.printf("来一个A船!");-
    }
}
public class Aboad implements Boat{
    @Override
    public void getBoat() {
        System.out.printf("来一架B船!");
    }
}
//抽象工厂
interface Factory{
    public Car getCarByFactory();
    public Plane getPlaneByFactory();
    public Boat getBoatByFactory();
}
// 具体工厂类1
class FactoryOne implements Factory{//车2+飞机1
 
    @Override
    public Car getCarByFactory() {
        return new BYD();
    }
 
    @Override
    public Plane getPlaneByFactory() {
        return new AirPlane();
    }
}
-----------------------------------
// 具体工厂类2
class FactoryTwo implements Factory{//车2+船1
 
    @Override
    public Car getCarByFactory() {
        return new BYD();
    }
 
    @Override
    public Plane getBoatByFactory() {
        return new ABoat ();
    }
}
//使用类
public class TestFactory {
    public static void main(String[] args) {
        Car byd = new FactoryTwo().getCarByFactory();
        byd.getCar();
        Plane airPlane = new FactoryOne().getPlaneByFactory();
        airPlane.getPlane();
	}
}
3.4 方法解读

原来工厂造的东西都是不同类别的车,而现在抽象工厂造的是不仅是车,而是车+飞机+船,也就是可以造不同抽象产品,而具体工厂选择抽象工厂提供的产品进行制造,比如A厂选了车+飞机,那他可以制造某种(而非各种)车和某种飞机。

抽象产品=车,飞机,船,具体产品=宝马/奔驰/比亚迪车,战斗机/客机等等。

使用类首先创建一个新的2号抽象工厂,并调用他的生产车函数创建一辆BYD,并用byd接住,再调用byd车的驾驶方法。

4 参考资料

https://blog.csdn.net/qq564425/article/details/81082242
https://www.cnblogs.com/long88-club/p/11055555.html
https://www.jb51.net/article/85699.htm
https://www.cnblogs.com/carryjack/p/7709861.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值