JAVA----设计模式

本文深入探讨了JAVA设计模式的目的和七大原则,包括单一职责、接口隔离、依赖倒转、里氏替换、开闭原则、迪米特法则和合成复用原则。此外,介绍了UML类图的不同关系,如依赖、泛化、实现、关联、聚合和组合。文章还详细讲解了创建型模式中的单例和工厂模式,通过多种实现方式展示了其实现细节和应用场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、设计模式

  • 面向对象(OO)=> 功能模块【设计模式 + 算法(数据结构)】=>框架【 多种设计模式】===>架构【服务器集群】
    在这里插入图片描述

1.1 设计模式的目的

在这里插入图片描述
在这里插入图片描述

1.2 设计模式七大原则

在这里插入图片描述

1.2.1 单一职责原则

在这里插入图片描述

  • 单一职责原则注意事项和细节
    在这里插入图片描述
public class SingleResponsibllity {

	public static void main(String[] args) {
		Vehicle v = new Vehicle();
		v.run("摩托车");
		v.runAir("飞机");
	}
}

//交通工具类
//此案例虽然在类级别上没有遵循单一职责原则,要求方法数量有限,可以在方法级别上,遵循了单一职责,所谓单一职责:就是各司其职。
class Vehicle {
	public void run(String vehicle) {
		System.out.println(vehicle + " 在公路上运行。。。。");
	}
	public void runAir(String vehicle) {
		System.out.println(vehicle + "在天空中飞行。。。。");
	}
}

1.2.2 接口隔离原则(Interface Segregation Principle)

在这里插入图片描述
在这里插入图片描述

  • 改进的UML 图
    在这里插入图片描述
public class Segregation {
	public static void main(String[] args) {
		A a = new A();
		a.depend1(new B()); // A 类通过接口依赖B类
		a.depend2(new B()); // A 类通过接口依赖B类
		a.depend3(new B()); // A 类通过接口依赖B类
		
		C c = new C();
		c.depend1(new D()); // C 类通过接口依赖D类
		c.depend4(new D()); // C 类通过接口依赖D类
		c.depend5(new D()); // C 类通过接口依赖D类		
	}
}

//接口1
interface Interface1 {
	void operation1();
}

//接口2
interface Interface2 {
	void operation2();

	void operation3();
}

//接口3
interface Interface3 {
	void operation4();

	void operation5();
}

class A { // A 类通过接口Interface1,Interface2 依赖(使用)B类,会用1,2,3方法
	public void depend1(Interface1 i) {
		i.operation1();
	}

	public void depend2(Interface2 i) {
		i.operation2();
	}

	public void depend3(Interface2 i) {
		i.operation3();
	}
}

class C { // C 类通过接口Interface1,Interface3 依赖(使用)D类,会用1,4,5方法
	public void depend1(Interface1 i) {
		i.operation1();
	}
	
	public void depend4(Interface3 i) {
		i.operation4();
	}
	
	public void depend5(Interface3 i) {
		i.operation5();
	}
}

class B implements Interface1, Interface2 {
	@Override
	public void operation1() {
		System.out.println("B ... operation1");
	}

	@Override
	public void operation2() {
		System.out.println("B ... operation2");
	}

	@Override
	public void operation3() {
		System.out.println("B ... operation3");
	}
}

class D implements Interface1, Interface3 {
	@Override
	public void operation1() {
		System.out.println("B ... operation1");
	}

	@Override
	public void operation4() {
		System.out.println("B ... operation4");
	}

	@Override
	public void operation5() {
		System.out.println("B ... operation5");
	}
}

1.2.3 依赖倒转原则(Dependence Inversion Principle)

在这里插入图片描述
在这里插入图片描述

public class DependecyInversion {
	public static void main(String[] args) {
		Person person = new Person();
		person.receive(new Email());
		
		person.receive(new WeChat());
	}
}

// 方式一:
//class Email {
//	public String getInfo() {
//		return "电子邮件:hello,world";
//	}
//}
//
////完成 Person 接手消息的功能
///**
// * 	方式1:
// * 		1、简单,比较容易想到
// * 		2、如果获取的对象是微信、短息等,则要新增类,同时Person也要增加相应的接受方法
// * 		3、解决思路:引入一个抽象的接口IReceiver,表示接受者,这样Person类与接口IReceiver发生依赖关系
// * 					Email,微信等等属于接受的范围,各自实现IReceiver 接口就OK,这样就符合依赖倒置原则
// *
// */
//class Person {
//	public void receive(Email email) {
//		System.out.println(email.getInfo());
//	}
//}

// 方式二:遵循依赖倒置原则

// 定义接口
interface IReceiver {
	public String getInfo();
}

class Email implements IReceiver {
	public String getInfo() {
		return "电子邮件:hello,world!";
	}
}

// 增加微信
class WeChat implements IReceiver {
	@Override
	public String getInfo() {
		return "微信:hello,world!";
	}
}
class Person {
	// 只与接口发生依赖
	public void receive(IReceiver receiver) {
		System.out.println(receiver.getInfo());
	}
}
1.2.3.1 接口传递

在这里插入图片描述

1.2.3.2 构造方法传递

在这里插入图片描述

1.2.3.3 setter方法传递

在这里插入图片描述

public class DependecyInversion {
	public static void main(String[] args) {
		// 通过接口传递实现依赖
//		ChangHong changHong = new ChangHong();
//		OpenAndClose openAndClose = new OpenAndClose();
//		openAndClose.open(changHong);
		
		// 通过构造方法传递实现依赖
//		ChangHong changHong = new ChangHong();
//		OpenAndClose openAndClose = new OpenAndClose(changHong);
//		openAndClose.open();
		
		// 通过setter方法传递实现依赖
		ChangHong changHong = new ChangHong();
		OpenAndClose openAndClose = new OpenAndClose();
		openAndClose.setTv(changHong);
		openAndClose.open();
	}
}

// 通过接口传递实现依赖
//interface IOpenAndClose {
//	public void open(ITV tv); // 抽象方法,接受接口
//}
//
//interface ITV { // ITV 接口
//	public void play();
//}
//
//class OpenAndClose implements IOpenAndClose {
//	@Override
//	public void open(ITV tv) {
//		tv.play();
//	}
//}
//
//class ChangHong implements ITV {
//	@Override
//	public void play() {
//		System.out.println("长虹电视机,打开");
//	}
//}

// 通过构造方法依赖传递

//interface IOpenAndClose {
//	public void open(); //抽象方法
//}
//
//interface ITV {
//	public void play();
//}
//
//class OpenAndClose implements IOpenAndClose {
//	public ITV tv; //成员变量
//	public OpenAndClose(ITV tv) { //构造器
//		this.tv = tv;
//	}
//	
//	public void open() {
//		this.tv.play();
//	}
//}
//
//class ChangHong implements ITV {
//	@Override
//	public void play() {
//		System.out.println("长虹电视机,打开");
//	}
//}

// 通过setter方法传递
interface IOpenAndClose {
	public void open(); // 抽象方法
	public void setTv(ITV tv);
}

interface ITV { //ITV 接口
	public void play();
}

class OpenAndClose implements IOpenAndClose {
	private ITV tv;
	
	public void setTv(ITV tv) {
		this.tv = tv;
	}
	
	@Override
	public void open() {
		this.tv.play();
	}
}

class ChangHong implements ITV {
	@Override
	public void play() {
		System.out.println("长虹电视机,打开");
	}
}

1.2.4 里氏替换原则

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • UML图

在这里插入图片描述

// 里氏替换原则
public class Liskov {
	public static void main(String[] args) {
		A a = new A();
		System.out.println("11-3 = " + a.func1(11, 3)); // 8
		System.out.println("1-8 = " + a.func1(1, 8)); // -7

		System.out.println("------------------------------");
		B b = new B();
//		System.out.println("11-3 = " + b.func1(11, 3)); // 14
//		System.out.println("1-8 = " + b.func1(1, 8)); // 9
//		System.out.println("11+3+9 = " + b.func2(11, 3)); // 23

		// 因为B类不再继承A类,因此调用者,不会再调用func1求减法
		System.out.println("11+3 = " + b.func1(11, 3)); // 14
		System.out.println("1+8 = " + b.func1(1, 8)); // 9
		System.out.println("11+3+9 = " + b.func2(11, 3)); // 23
		
		// 使用组合仍然可以使用到A类相关方法
		System.out.println("11-3 = " + b.func3(11, 3)); // 8
	}
}

// 创建一个更加基础的基类
class Base {
	// 基础方法和成员写到Base类中
}

// A 类
class A extends Base {
	public int func1(int num1, int num2) {
		return num1 - num2;
	}
}

//B 类
class B extends Base {
	// 如果B类需要使用A类的方法,使用组合关系
	private A a = new A();
	
	// 重写了A类的方法,原本的意思是用A类的方法,却无意中不满足了里氏替换原则,导致使用自身的重写方法
	public int func1(int a, int b) {
		return a + b;
	}

	public int func2(int a, int b) {
		return func1(a, b) + 9;
	}
	
	// 仍需使用A类的方法
	public int func3(int a, int b) {
		return this.a.func1(a, b);
	}
}

// A 类
//class A {
//	public int func1(int num1, int num2) {
//		return num1 - num2;
//	}
//}

// B 类
//class B extends A {
//
//	// 重写了A类的方法,原本的意思是用A类的方法,却无意中不满足了里氏替换原则,导致使用自身的重写方法
//	public int func1(int a, int b) {
//		return a + b;
//	}
//
//	public int func2(int a, int b) {
//		return func1(a, b) + 9;
//	}
//}

1.2.5 开闭原则

在这里插入图片描述

// 方式一:
public class Ocp {
	public static void main(String[] args) {
		GraphicEditor graphicEditor = new GraphicEditor();
		graphicEditor.drawShape(new Rectangle());
		graphicEditor.drawShape(new Circle());
		graphicEditor.drawShape(new Triangle());
	}
}


// 这是一个用于绘图的类 【使用方】
class GraphicEditor {
	// 接收Shape对象,然后根据type,来绘制不同的图形
	public void drawShape(Shape s) {
		if (s.m_type == 1) {
			drawRectangle(s);
		} else if (s.m_type == 2) {
			drawCircle(s);
		} else if (s.m_type == 3) {
			drawTriangle(s);
		}
	}
	
	// 绘制矩形
	public void drawRectangle(Shape r) {
		System.out.println("绘制矩形");
	}
	
	// 绘制圆形
	public void drawCircle(Shape r) {
		System.out.println("绘制圆形");
	}
	
	// 绘制三角形
	public void drawTriangle(Shape r) {
		System.out.println("绘制三角形");
	}
}

// Shape类,基类
class Shape {
	int m_type;
}

class Rectangle extends Shape {
	Rectangle() {
		super.m_type = 1;
	}
}

class Circle extends Shape {
	Circle() {
		super.m_type = 2;
	}
}

// 新增画三角形
class Triangle extends Shape {
	Triangle() {
		super.m_type = 3;
	}
}

在这里插入图片描述
在这里插入图片描述

// 遵循开闭原则
public class Ocp {
	public static void main(String[] args) {
		GraphicEditor graphicEditor = new GraphicEditor();
		graphicEditor.drawShape(new Rectangle());
		graphicEditor.drawShape(new Circle());
		graphicEditor.drawShape(new Triangle());
		graphicEditor.drawShape(new OtherGraphic());
	}
}


// 这是一个用于绘图的类 【使用方】
class GraphicEditor {
	// 接收Shape对象,然后根据type,来绘制不同的图形
	public void drawShape(Shape s) {
		s.draw();
	}
}

// Shape类,基类
abstract class Shape {
	int m_type;
	public abstract void draw(); // 抽象方法
}

class Rectangle extends Shape {
	Rectangle() {
		super.m_type = 1;
	}
	
	@Override
	public void draw() {
		System.out.println("绘制矩形");
	}
}

class Circle extends Shape {
	Circle() {
		super.m_type = 2;
	}
	
	@Override
	public void draw() {
		System.out.println("绘制圆形");
	}
}

// 新增画三角形
class Triangle extends Shape {
	Triangle() {
		super.m_type = 3;
	}
	
	@Override
	public void draw() {
		System.out.println("绘制三角形");
	}
}

// 新增一个图形
class OtherGraphic extends Shape {
	OtherGraphic() {
		super.m_type = 4;
	}
	
	@Override
	public void draw() {
		System.out.println("绘制其它图形");
	}
}

1.2.6 迪米特法则

在这里插入图片描述
在这里插入图片描述

import java.util.ArrayList;
import java.util.List;

// 客户端
public class Demeter {
	public static void main(String[] args) {
		// 创建SchoolManager对象
		SchoolManager schoolManager = new SchoolManager();
		// 输出学院的员工id 和 学校总部的员工信息
		schoolManager.printAllEmployee(new CollegeManger());
	}
}

// 学校总部员工
class Employee {
	private String id;

	public String getId() {
		return id;
	}

	public void setId(String id) {
		this.id = id;
	}
	
	
}


// 学院员工
class CollegeEmployee {
	private String id;

	public String getId() {
		return id;
	}

	public void setId(String id) {
		this.id = id;
	}	
}

// 管理学院员工
class CollegeManger {
	// 返回学院的所有员工
	public List<CollegeEmployee> getAllEmployee() {
		List<CollegeEmployee> list = new ArrayList<>();
		for (int i = 0; i < 10; i++) {
			CollegeEmployee emp = new CollegeEmployee();
			emp.setId("学院员工id= " + i);
			list.add(emp);
		}
		return list;
	}
}

// 学校管理类
// 分析SchoolManager类的直接朋友有哪些:Employee、CollegeManager、
// 而CollegeEmployee 不是直接朋友,而是陌生类,这样就违背了迪米特法则
class SchoolManager {
	// 返回学校总部的员工
	public List<Employee> getAllEmployee() {
		List<Employee> list = new ArrayList<>();
		
		for (int i = 0; i < 5; i++) {
			Employee emp = new Employee();
			emp.setId("学校总部员工id= " + i);
			list.add(emp);
		}
		return list;
	}
	
	// 输出学校总部和学院员工信息(id)
	void printAllEmployee(CollegeManger sub) {
		// CollegeEmployee 不是 SchoolManager的直接朋友,而是以局部变量方式出现在SchoolManager,,违反了迪米特法则
		// 获取到学院员工
		List<CollegeEmployee> list1 = sub.getAllEmployee();
		System.out.println("-------------学院员工--------------");
		for (CollegeEmployee e : list1) {
			System.out.println(e.getId());
		}
		// 获取学校总部员工
		List<Employee> list2 = this.getAllEmployee();
		System.out.println("----------------学校总部员工----------------");
		for (Employee e : list2) {
			System.out.println(e.getId());
		}
	}
}

在这里插入图片描述

import java.util.ArrayList;
import java.util.List;

// 客户端
public class Demeter {
	public static void main(String[] args) {
		// 创建SchoolManager对象
		SchoolManager schoolManager = new SchoolManager();
		// 输出学院的员工id 和 学校总部的员工信息
		schoolManager.printAllEmployee(new CollegeManger());
	}
}

// 学校总部员工
class Employee {
	private String id;

	public String getId() {
		return id;
	}

	public void setId(String id) {
		this.id = id;
	}

}

// 学院员工
class CollegeEmployee {
	private String id;

	public String getId() {
		return id;
	}

	public void setId(String id) {
		this.id = id;
	}
}

// 管理学院员工
class CollegeManger {
	// 返回学院的所有员工
	public List<CollegeEmployee> getAllEmployee() {
		List<CollegeEmployee> list = new ArrayList<>();
		for (int i = 0; i < 10; i++) {
			CollegeEmployee emp = new CollegeEmployee();
			emp.setId("学院员工id= " + i);
			list.add(emp);
		}
		return list;
	}

	// 输出员工的信息
	public void printEmployee() {
		// 获取到学院员工
		List<CollegeEmployee> list1 = this.getAllEmployee();
		System.out.println("-------------学院员工--------------");
		for (CollegeEmployee e : list1) {
			System.out.println(e.getId());
		}
	}
}

// 学校管理类
class SchoolManager {
	// 返回学校总部的员工
	public List<Employee> getAllEmployee() {
		List<Employee> list = new ArrayList<>();

		for (int i = 0; i < 5; i++) {
			Employee emp = new Employee();
			emp.setId("学校总部员工id= " + i);
			list.add(emp);
		}
		return list;
	}

	// 输出学校总部和学院员工信息(id)
	void printAllEmployee(CollegeManger sub) {
		// 解决了违反了迪米特法则的问题
		sub.printEmployee();
		// 获取学校总部员工
		List<Employee> list2 = this.getAllEmployee();
		System.out.println("----------------学校总部员工----------------");
		for (Employee e : list2) {
			System.out.println(e.getId());
		}
	}
}

1.2.6 合成复用原则(Composite Reuse Principle)

  • 尽量使用合成/聚合的方式,而不是继承
    在这里插入图片描述

1.3 设计原则核心思想

在这里插入图片描述

2、UML

在这里插入图片描述
在这里插入图片描述

2.1 类图

在这里插入图片描述

2.1.1 依赖关系(Dependence)

在这里插入图片描述
在这里插入图片描述

2.1.2 泛化关系(Generalization)

在这里插入图片描述
在这里插入图片描述

2.1.3 实现关系(Realization)

在这里插入图片描述
在这里插入图片描述

2.1.4 关联关系(Association)

在这里插入图片描述

2.1.4 聚合关系(Aggregation)

在这里插入图片描述
在这里插入图片描述

2.1.5 组合关系(Composition)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2.2 类图小结

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3、设计模式类型

在这里插入图片描述

3.1 创建型模式

3.1.1 单例模式

  • 单例(Singleton):只允许创建一个该类的对象
    在这里插入图片描述
3.1.1.1 ★饿汉式(静态常量----类加载时创建,天生线程安全)

在这里插入图片描述

  • 优点:线程安全
  • 缺点:声明周期太长,浪费空间
    在这里插入图片描述
    在这里插入图片描述
/**
 * 饿汉式
 *  1)首先创建一个常量
 *  2)构造方法改成私有的,类外部不能创建对象
 *  3)通过一个公开的方法,返回这个对象
 */
public class SingleTon {
	// 本类内部创建对象实例
    private static final SingleTon instance = new SingleTon();
    // 构造器私有化,外部不能new
    private SingleTon(){}
	// 提供一个公有的静态方法,返回实例对象
    public static SingleTon getInstance(){
        return instance;
    }
}

class TestSingleTon{
    public static void main(String[] args) {
        for (int i = 0; i < 3; i++) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    System.out.println(SingleTon.getInstance().hashCode());
                }
            }).start();
        }
    }
}
3.1.1.2 ★饿汉式(静态代码块)

在这里插入图片描述

public class Singleton {
    private static Singleton instance;

    // 静态代码块执行时,创建单例对象
    static {
        instance = new Singleton();
    }

    // 构造器私有化,外部不能new
    private Singleton() {}

    public static Singleton getInstance() {
        return instance;
    }
}

class TestSingleton {
    public static void main(String[] args) {
        for (int i = 0; i < 3; i++) {
            new Thread(new Runnable() {

                @Override
                public void run() {
                    System.out.println(Singleton.getInstance().hashCode());
                }
            }).start();
        }
    }
}
3.1.1.3 懒汉式(使用时创建,线程不安全)

在这里插入图片描述

public class Singleton {
    private static Singleton instance;

    private Singleton(){}

    // 静态的公有方法,当使用该方法时,才创建instance,即懒汉式
    public static Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }
}

class TestSingleton {
    public static void main(String[] args) {
        for (int i = 0; i < 3; i++) {
            new Thread(new Runnable() {

                @Override
                public void run() {
                    System.out.println(Singleton.getInstance().hashCode());
                }
            }).start();
        }
    }
}
3.1.1.4 懒汉式(线程安全,加同步方法)

在这里插入图片描述

public class Singleton {
    private static Singleton instance;

    private Singleton(){}

    // 提供一个静态的公有方法,加入同步方法。解决线程安全问题
    public static synchronized Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }
}

class TestSingleton {
    public static void main(String[] args) {
        for (int i = 0; i < 3; i++) {
            new Thread(new Runnable() {

                @Override
                public void run() {
                    System.out.println(Singleton.getInstance().hashCode());
                }
            }).start();
        }
    }
}
3.1.1.5 懒汉式(线程安全,加同步代码块)

在这里插入图片描述

public class Singleton {
    private static Singleton instance;

    private Singleton(){}

    // 提供一个静态的公有方法,加入同步代码块。本意解决线程不安全问题
    public static Singleton getInstance() {
        if (instance == null) {
            // getInstance的方法已经进来,然后对创建对象加上同步代码块没有实际意义,依然会存在线程安全问题
            synchronized (Singleton.class) {
                instance = new Singleton();
            }
        }
        return instance;
    }
}

class TestSingleton {
    public static void main(String[] args) {
        for (int i = 0; i < 3; i++) {
            new Thread(new Runnable() {

                @Override
                public void run() {
                    System.out.println(Singleton.getInstance().hashCode());
                }
            }).start();
        }
    }
}
3.1.1.6 ★双重检查

在这里插入图片描述

public class Singleton {
    // volatile 是轻量级线程安全
    private static volatile Singleton instance;

    private Singleton(){}

    // 提供一个静态的公有方法,加入双重检查代码,解决线程安全问题,同时解决懒加载问题,同时保证效率,推荐使用
    public static Singleton getInstance() {
        if (instance == null) {
            synchronized (Singleton.class) {
                if (instance == null) {
                    instance = new Singleton();
                }
            }
        }
        return instance;
    }
}

class TestSingleton {
    public static void main(String[] args) {
        for (int i = 0; i < 3; i++) {
            new Thread(new Runnable() {

                @Override
                public void run() {
                    System.out.println(Singleton.getInstance().hashCode());
                }
            }).start();
        }
    }
}
3.1.1.7 ★静态内部类

加粗样式
在这里插入图片描述

/**
 * 静态内部类的写法:
 * 懒汉式
 *  1)构造方法改成私有的,类外部不能创建对象
 *  2)创建静态内部类
 *  3)通过一个公开的方法,返回这个对象
 */
public class SingleTon {
    private SingleTon(){}

    //静态内部类在不使用的时候,是不执行的,所有属于懒汉式
    /**
     * 静态内部类 1): 外部类加载,内部类不会加载;
     *          2):静态内部类调用getInstance时才加载,而且只加载一次,因此保证了线程安全
     */
    private static class SingletonInstance {
        private static final Singleton INSTANCE = new Singleton();
    }

    // 静态公有方法
    public static Singleton getInstance() {
        return SingletonInstance.INSTANCE;
    }
}

class TestSingleTon{
    public static void main(String[] args) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 3; i++) {
                    System.out.println(SingleTon.getInstance().hashCode());
                }
            }
        }).start();
    }
}
3.1.1.8 ★枚举

在这里插入图片描述

// 使用枚举,可以实现单例
public enum Singleton {
    INSTANCE;
    public void method() {
        System.out.println("ok~~~");
    }
}

class TestSingleton {
    public static void main(String[] args) {
        for (int i = 0; i < 3; i++) {
            new Thread(new Runnable() {

                @Override
                public void run() {
                    System.out.println(Singleton.INSTANCE.hashCode());
                }
            }).start();
        }
    }
}
3.1.1.9 单例模式在源码中的使用

在这里插入图片描述

3.1.1.10 单例模式注意事项和细节

在这里插入图片描述

3.1.2 工厂模式

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3.1.2.1 传统方式实现

在这里插入图片描述
在这里插入图片描述

  • Pizza类
public abstract class Pizza {
    protected String name; // 披萨的名字

    public abstract void prepare(); // 原材料的准备

    // 烘焙
    public void bake() {
        System.out.println(name + " baking;");
    }

    // 切割
    public void cut() {
        System.out.println(name + " cutting;");
    }

    // 打包
    public void box() {
        System.out.println(name + " boxing;");
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}
  • CheesePizza类
public class CheesePizza extends Pizza {
    @Override
    public void prepare() {
        System.out.println("制作奶酪披萨,准备原材料");
    }
}
  • GreekPizza类
public class GreekPizza extends Pizza {
    @Override
    public void prepare() {
        System.out.println("希腊披萨 原材料准备");
    }
}
  • OrderPizza类
import java.io.BufferedReader;
import java.io.InputStreamReader;

public class OrderPizza {
    // 构造器
    public OrderPizza() {
        Pizza pizza = null;
        String orderType; // 订购披萨的类型
        do {
            orderType = getType();
            switch (orderType) {
                case "greek":
                  pizza = new GreekPizza();
                  pizza.setName("希腊披萨");
                  break;
                case "cheese":
                    pizza = new CheesePizza();
                    pizza.setName("奶酪披萨");
                    break;
                default:
                    break;
            }
            // 输出pizza 制作过程
            pizza.prepare();
            pizza.bake();
            pizza.cut();
            pizza.box();
        } while (true);
    }

    // 获取客户订购披萨的方法
    private String getType() {
        try {
            BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
            System.out.println("input pizza type: ");
            String message = reader.readLine();
            return message;
        } catch (Exception e) {
            e.printStackTrace();
            return "";
        }
    }
}
  • PizzaStore类
// 相当一个客户端
public class PizzaStore {
    public static void main(String[] args) {
        new OrderPizza();
    }
}
3.1.2.2 简单工厂模式实现

在这里插入图片描述
在这里插入图片描述

  • Pizza类
public abstract class Pizza {
    protected String name; // 披萨的名字

    public abstract void prepare(); // 原材料的准备

    // 烘焙
    public void bake() {
        System.out.println(name + " baking;");
    }

    // 切割
    public void cut() {
        System.out.println(name + " cutting;");
    }

    // 打包
    public void box() {
        System.out.println(name + " boxing;");
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}
  • CheesePizza类
public class CheesePizza extends Pizza {
    @Override
    public void prepare() {
        System.out.println("制作奶酪披萨,准备原材料");
    }
}
  • GreekPizza类
public class GreekPizza extends Pizza {
    @Override
    public void prepare() {
        System.out.println("希腊披萨 原材料准备");
    }
}
  • ★OrderPizza类
import java.io.BufferedReader;
import java.io.InputStreamReader;

public class OrderPizza {
    Pizza pizza = null;
    String orderType = "";
    public OrderPizza() {
        do {
            orderType = getType();
            pizza = SimpleFactory.createPizza(orderType);

            // 输出pizza
            if (pizza != null) { // 订购成功
                pizza.prepare();
                pizza.bake();
                pizza.cut();
                pizza.box();
            } else {
                System.out.println("披萨订购失败");
            }
        } while (true);
    }

    // 获取客户订购披萨的方法
    private String getType() {
        try {
            BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
            System.out.println("input pizza type: ");
            String message = reader.readLine();
            return message;
        } catch (Exception e) {
            e.printStackTrace();
            return "";
        }
    }
}
  • ★PizzaStore类
// 相当一个客户端
public class PizzaStore {
    public static void main(String[] args) {
        new OrderPizza();
    }
}
  • ★SimpleFactory类(静态方法)
// 简单工厂类
public class SimpleFactory {
    public static Pizza createPizza(String orderType) {
        Pizza pizza = null;
        System.out.println("使用简单工厂模式");
        switch (orderType) {
            case "greek":
                pizza = new GreekPizza();
                pizza.setName("希腊披萨");
                break;
            case "cheese":
                pizza = new CheesePizza();
                pizza.setName("奶酪披萨");
                break;
            default:
                break;
        }
        return pizza;
    }
}

  • Pizza类
public abstract class Pizza {
    protected String name; // 披萨的名字

    public abstract void prepare(); // 原材料的准备

    // 烘焙
    public void bake() {
        System.out.println(name + " baking;");
    }

    // 切割
    public void cut() {
        System.out.println(name + " cutting;");
    }

    // 打包
    public void box() {
        System.out.println(name + " boxing;");
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}
  • CheesePizza类
public class CheesePizza extends Pizza {
    @Override
    public void prepare() {
        System.out.println("制作奶酪披萨,准备原材料");
    }
}
  • GreekPizza类
public class GreekPizza extends Pizza {
    @Override
    public void prepare() {
        System.out.println("希腊披萨 原材料准备");
    }
}
  • OrderPizza类
import java.io.BufferedReader;
import java.io.InputStreamReader;

public class OrderPizza {
    // 定义简单工厂对象
    SimpleFactory simpleFactory = null;
    Pizza pizza = null;
    public OrderPizza(SimpleFactory simpleFactory) {
        setFactory(simpleFactory);
    }
    public void setFactory(SimpleFactory simpleFactory) {
        String orderType = ""; // 用户输入的披萨类型
        this.simpleFactory = simpleFactory;
        do {
            orderType = getType();
            pizza = this.simpleFactory.createPizza(orderType);

            // 输出pizza
            if (pizza != null) { // 订购成功
                pizza.prepare();
                pizza.bake();
                pizza.cut();
                pizza.box();
            } else {
                System.out.println("披萨订购失败");
            }
        } while (true);
    }
    // 获取客户订购披萨的方法
    private String getType() {
        try {
            BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
            System.out.println("input pizza type: ");
            String message = reader.readLine();
            return message;
        } catch (Exception e) {
            e.printStackTrace();
            return "";
        }
    }
}
  • PizzaStore类
// 相当一个客户端
public class PizzaStore {
    public static void main(String[] args) {
        new OrderPizza(new SimpleFactory());
    }
}
  • SimpleFactory类
// 简单工厂类
public class SimpleFactory {
    public Pizza createPizza(String orderType) {
        Pizza pizza = null;
        System.out.println("使用简单工厂模式");
        switch (orderType) {
            case "greek":
                pizza = new GreekPizza();
                pizza.setName("希腊披萨");
                break;
            case "cheese":
                pizza = new CheesePizza();
                pizza.setName("奶酪披萨");
                break;
            default:
                break;
        }
        return pizza;
    }
}
  • use.properties配置文件
1=com.io.test.Mouse
2=com.io.test.Fan
3=com.io.test.Upan
  • Usb接口
public interface Usb {
    void service();
}
  • Mouse实现类
public class Mouse implements Usb{
    @Override
    public void service() {
        System.out.println("鼠标开始工作了。。。");
    }
}
  • Fan实现类
public class Fan implements Usb{
    @Override
    public void service() {
        System.out.println("风扇也开始工作了。。。");
    }
}
  • Upan实现类
public class Upan implements Usb{
    @Override
    public void service() {
        System.out.println("U盘也开始工作了。。。");
    }
}
  • UsbFactory工厂类
public class UsbFactory {
    public static Usb createUsb(String type){
        Usb usb = null;
        Class<?> class1 = null;
        try {
            class1 = Class.forName(type);
            usb = (Usb)class1.newInstance();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return usb;
    }
}
  • Demo测试类
import java.io.FileInputStream;
import java.util.Properties;
import java.util.Scanner;

public class Demo {
    public static void main(String[] args) throws Exception{
        System.out.println("=====请选择 1 鼠标 2 风扇 3 U盘====");
        Scanner input = new Scanner(System.in);

        String choice = input.next();

        Properties properties = new Properties();
        FileInputStream fis = new FileInputStream("src\\usb.properties");
        properties.load(fis);

        Usb usb = UsbFactory.createUsb(properties.getProperty(choice));

        if(usb != null){
            System.out.println("购买成功");
            usb.service();
        }else{
            System.out.println("购买失败,您要购买的产品不存在");
        }
    }
}
3.1.2.3 工厂方法模式

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • Pizza类
public abstract class Pizza {
    protected String name; // 披萨的名字

    public abstract void prepare(); // 原材料的准备

    // 烘焙
    public void bake() {
        System.out.println(name + " baking;");
    }

    // 切割
    public void cut() {
        System.out.println(name + " cutting;");
    }

    // 打包
    public void box() {
        System.out.println(name + " boxing;");
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}
  • BJCheesePizza类
public class BJCheesePizza extends Pizza{
    @Override
    public void prepare() {
        setName("北京的奶酪pizza");
        System.out.println("北京的奶酪披萨 准备材料");
    }
}
  • LDGreekPizza类
public class LDGreekPizza extends Pizza{
    @Override
    public void prepare() {
        setName("伦敦的希腊披萨");
        System.out.println("希腊披萨 原材料准备");
    }
}
  • OrderPizza类
import java.io.BufferedReader;
import java.io.InputStreamReader;

public abstract class OrderPizza {
    // 定义一个抽象方法
    abstract Pizza createPizza (String orderType);

    public OrderPizza() {
        Pizza pizza = null;
        String orderType; // 订购披萨的类型
        do {
            orderType = getType();
            pizza = createPizza(orderType); // 抽象方法,由工厂子类完成
            pizza.prepare();
            pizza.bake();
            pizza.cut();
            pizza.box();
        } while (true);
    }
    // 获取客户订购披萨的方法
    private String getType() {
        try {
            BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
            System.out.println("input pizza type: ");
            String message = reader.readLine();
            return message;
        } catch (Exception e) {
            e.printStackTrace();
            return "";
        }
    }
}
  • BJOrderPizza类
public class BJOrderPizza extends OrderPizza{
    @Override
    Pizza createPizza(String orderType) {
        Pizza pizza = null;
        if (orderType.equals("cheese")) {
            pizza = new BJCheesePizza();
        }
        return pizza;
    }
}
  • LDOrderPizza类
public class LDOrderPizza extends OrderPizza{
    @Override
    Pizza createPizza(String orderType) {
        Pizza pizza = null;
        if(orderType.equals("greek")) {
            pizza = new LDGreekPizza();
        }
        return pizza;
    }
}
  • PizzaStore类
public class PizzaStore {
    public static void main(String[] args) {
        String location = "bj";
        if (location.equals("bj")) {
            new BJOrderPizza();
        } else {
            new LDOrderPizza();
        }
    }
}

3.2 结构型模式

3.3 行为型模式

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值