JavaSE之面向对象编程—抽象类与接口—— 4(工厂设计模式)

                                                                                        工厂设计模式
在java基础部分要求掌握三种重点设计模式:工厂设计模式、代理设计模式、单例设计模式。
一、工厂设计模式
我们下面先来看看一般情况下的设计:
对于这样的场景:刘同学准备去买笔记本电脑,她到商场去买衣服,发现有两个牌子她都特别喜欢,一款是A,一款是B。
根据上面的情景,我们可以将它抽象出来为一个接口进行实现:

//1.工厂设计模式(重点)
//没有模式的情况:
//一般是这样,对于一个共同有的行为就定义为一个接口中的抽象方法;对于含有这种方法的不同种类
//就定义为一个类,这个类去实现接口中的方法,这样就可以达到我们的效果。
// interface Clothes{
	// void printClothes();
// }
// class A implements Clothes{
	// public void printClothes(){
		// System.out.println("这是A款衣服");
	// }
// }
// class B implements Clothes{
	// public void printClothes(){
		// System.out.println("这是B款衣服");
	// }
// }
// public class Client{
	// public void buyClothes(Clothes clothes){
		// clothes.printClothes();//实现买衣服
	// }
	// public static void main(String[] args){
		// Client client=new Client();
		// client.buyClose(new A());//这样就表示创建了A款衣服的实例,但是我们必须得知道创建对象的过程
	// }
//那么问题来了;如果刘同学这时候又看上了另外一款衣服,我们就不得不返回客户端进行修改了。所以下面我们采用简单工厂模式进行实现。

//1.简单工厂模式:专门定义一个类,用来创建其他类的实例,被创建的实例通常都具有共同的父类。
//买一件衣服的例子
// import java.util.Scanner;
// interface Clothes{
	// public void print();
// }
// class A implements Clothes{
	// public void print(){
		// System.out.println("这是A款衣服");
	// }
// }
// class B implements Clothes{
	// public void print(){
		// System.out.println("这是B款衣服");
	// }
// }
// //定义一个类来创建对象——》工厂类
// class ClothesFactory{//这个就是生产衣服的工厂,生产衣服由它实现,即是创建对象由它实现,
// //我们的客户不用知道我们衣服的对象怎么实例化。
	// public static Clothes getInstance(String type){
		// Clothes clothes=null;//初始化对象
		// if(type.equals("A")){//创建对象,开辟空间,返回具体的对象
			// return new A();
		// }else{
			// return new B();
		// }
	// }
// }

// public class Client {
	// public void buyClothes(Clothes clothes){
		// clothes.print();//可以起到创建对象的作用:最后对应的衣服去调用对应的print()
	// }
	// public static void main(String[] args){
		// Client client=new Client();
		// Scanner scanner = new Scanner(System.in);
		// System.out.println("请输入您想要的衣服款式:");
		// String type=scanner.nextLine();
		// Clothes clothes=ClothesFactory.getInstance(type);//通过传入的类型判断是否是在所给范围内的类型
		// client.buyClothes(clothes);//这儿传入的clothes是创建好之后的对象,即是传入以后得到相应的那个款式的衣服
	// }
// }
//我们来实现一个买电脑的例子
//电脑的类型分为:HP、Lenvoe
//电脑的接口
// import java.util.Scanner;
// interface Computer{
	// public void print();//对于每一个类它的功能是不同的
// }
// //HP的电脑
// class HP implements Computer{
	// public void print(){
		// System.out.println("这是一台HP电脑");
	// }
// }
// //联想的电脑
// class Lenvoe implements Computer{
	// public void print(){
		// System.out.println("这是一台联想电脑");
	// }
// }
// //定义一个生产电脑的工厂:根据客户传入的类型专门用来创建对象
// class ComputerFactory{
	// //定义一个生产对象的方法
	// public static Computer printComputer(String type){ 
	// /*error	如果采用以下这种方法就会出现错误,因为这样就没有了返回语句,所以我们需要用它下面的这种方法
	// if(type.equals("HP")){
		// return new HP();
	// }else if(type.equals("Lenvoe")){
		// return new Lenvoe();
	// }	
	// */
	// Computer computer=null;//初始化了一个对象
	// if(type.equals("HP")){
		// computer=new HP();
	// }else if(type.equals("Lenvoe")){
		// computer=new Lenvoe();
	// }
	// return computer;//这样函数才有返回值
// }
// }
// public class Client{
	// public void buyComputer(Computer computer){
		// computer.print();
	// }
	// public static void main(String[] args){
		// Client client = new Client();
		// Scanner scanner=new Scanner(System.in);
		// System.out.println("请输入你想要的类型:");
		// String type=scanner.nextLine();
		// Computer computer = ComputerFactory.printComputer(type);//静态方法通过类名调用,不用知道具体的工厂类
		// client.buyComputer(computer);
	// }
// }
在工厂模式中我们最需要注意的就是,它的思想,通过创建一个类(这个类叫生产工厂)来专门创建我们需要对象,并且在主函数中我们需要 创建一个方法,来对应的调用我们创建对象以后这个对象对应的方法。
二、工厂方法模式
工厂方法模式:定义一个用来创建对象的接口,让子类决定实例化哪个类,让子类决定实例化延迟到子类。
工厂方法模式是针对每个产品提供一个工厂类,在客户端中判断使用哪个工厂类去创建对象。我们将之前的ComputerFactory抽象成一个接口,那么创建相应具体的工厂类去实现该接口的方法。

//工厂方法模式
// interface Computer{
// void printCOmputer();
// }
// class HP implements Computer{
// public void printCOmputer(){
// System.out.println(“这是HP电脑”);
// }
// }
// class Lenvoe implements Computer(){
// public void printCOmputer(){
// System.out.println(“这是联想电脑”);
// }
// }
// //定义一个接口的工厂
// interface ComputerFactory{
// Computer createComputer();
// }
// //创建工厂类去实现接口的方法
// //属于HP的工厂类
// class Ms1Factory implements ComputerFactory{
// public Computer createComputer(){
// return new HP();
// }
// }
// //属于Lenvoe的工厂类
// class Ms2Factory implements ComputerFactory{
// public Computer createComputer(){
// return new Lenvoe();
// }
// }
// //不同的工厂类创建自己的对象
// public class Client{
// public void buyComputer(Computer computer){
// computer.printComputer();
// }
// public static void main(String[] args){
// Client client=new Client();
// ComputerFactory factory=new Ms2Factory();//实现向上转型——》父类接口(在这里就必须得知道具体的工厂类)
// //虽然接口是用来创建对象的,但是我们最后是通过对应的工厂类来创建对象的。
// client.buyComputer(factory.createComputer());
// }
// }

对于简单工厂模式和工厂方法模式的对比:
(1)对于简单工厂模式,创建对象的逻辑判断放在了工厂类中,客户不知道具体的类,不知道具体创建对象的方式,但是违背了开闭原则,如果需要新增加具体的类,就必须修改工厂类。
(2)对于工厂方法模式而言,是通过扩展来新增加具体类的,复合开闭原则,但是客户端就必须知道具体的工厂类,也就是将逻辑判断由简单工厂的工厂类挪到了客户端。
(3)工厂方法横向扩展很方便,加入新增加了一种产品,那么只需要新增加一个相应的工厂类和产品类去实现抽象工厂接口和抽象产品接口即可,不用修改原代码。
优点:
降低了代码的耦合度,对象的生成交给子类完成;
实现了开闭原则,每次增加子产品不需要修改原代码
缺点:
增加了代码量,每个具体的产品都需要一个具体的工厂方法。
当增加一个抽象产品的时候就需要修改工厂了。
三、抽象工厂模式
概要:
(1)多个抽象产品
(2)具体产品类
(3)抽象工厂类 —声明(一组)返回抽象产品的方法
(4)具体工厂类 —生成(一组)具体产品
抽象工厂模式:提供一个创建一系列相关或相互依赖对象的接口,不需要具体指定它们的类。
抽象工厂模式与工厂方法模式基本相似,工厂方法模式是抽象工厂模式的一种特殊情况,当工厂只生产一个产品的时候,就为工厂方法模式;而工厂生产两个或者两个以上的产品时就为抽象工厂模式。

//抽象工厂模式
interface Computer {
void printComputer();
}
class AComputer implements Computer{
public void printComputer(){
System.out.println(“这是A类电脑”);
}
}
class BComputer implements Computer{
public void printComputer(){
System.out.println(“这是B类电脑”);
}
}
//定义一个接口来创建不同类型电脑的操作系统
interface OperatingSystem{
void printSystem();
}
//对于两类不同的电脑都有各自的操作系统的类
class ASystem implements OperatingSystem{
public void printSystem(){
System.out.println(“这是A类操作系统”);
}
}
class BSystem implements OperatingSystem{
public void printSystem(){
System.out.println(“这是B类操作系统”);
}
}
//定义一个生产工厂的接口
interface ProductionFactory{
//抽象工厂模式,就是在这个地方与工厂模式有区别,它的这个创建类的接口中有多个抽象方法
//去创建不同种类的对象。
Computer createComputer();//这个抽象方法是为了创建不同的对象的
OperatingSystem createSystem();//这个抽象方法是为了创建不同的操作系统的
}
//还是和工厂模式一样的,每个种类都有自己的生产工厂
class AFactory implements ProductionFactory{
public Computer createComputer(){
return new AComputer();
}
public OperatingSystem createSystem(){
return new ASystem();
}
}

class BFactory implements ProductionFactory{
public Computer createComputer(){
return new BComputer();
}
public OperatingSystem createSystem(){
return new BSystem();
}
}
//客户
public class Client{
//这个是具体创建电脑对象的
public void buyComputer(Computer computer){
computer.printComputer();
}
//这个是具体创建操作系统的对象的
public void use(OperatingSystem s){
s.printSystem();
}
public static void main(String[] args){
Client client=new Client();
//先开辟一个生产工厂
ProductionFactory factory=new AFactory();
Computer computer=factory.createComputer();
OperatingSystem system=factory.createSystem();
client.buyComputer(computer);
client.use(system);
}
}

对于以上三种模式总结:
简单工厂模式最大的优点就是:在工厂类中公有具体的逻辑去判断生产什么产品,将类的实例化交给了工厂,客户不需要知道具体的实例化。
工厂方法模式最大的优点在于:在工厂方法模式中我们遵循了开闭原则,当我们需要新增加一种产品的时候我们不需要修改之前的类,只需要增加一个类去实现接口就可以了,但是它将之前简单工厂模式中在类中判断的逻辑思想交给了客户,需要我们的客户去判断。
抽象工厂模式进一步扩展了我们的工厂方法模式,在抽象方法模式里面我们可以添加一类新产品,它遵循了OCP原则。







































猜你喜欢

转载自blog.csdn.net/ZhuiZhuDream5/article/details/84311459