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();
}
}
}