java常用的设计模式
![在这里插入图片描述](https://img-blog.csdnimg.cn/be418116d3354cdcaf537ef5809e2c42.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5Y6a5a2m,size_20,color_FFFFFF,t_70,g_se,x_16)
1、类图
类图:类与其他类之间的关系
一个简单的类图就可以这么画
1、类与类的关联关系表示方式
1、关联关系
2、聚合关系
3、组合关系
4、依赖关系
5、继承关系
6、实现关系
2、软件设计原则
2.1、开闭原则
类图:
一个抽象皮肤类,子类为默认的皮肤和黑马皮肤。搜狗输入法引用抽象皮肤类
AbstractSkin
package org.example.demo;
/**
* 抽象皮肤类
*/
public abstract class AbstractSkin {
/**
* 显示皮肤
*/
public abstract void display();
}
DefaultSkin
package org.example.demo;
/**
* 默认皮肤类
*/
public class DefaultSkin extends AbstractSkin{
@Override
public void display() {
System.out.println("默认皮肤");
}
}
HeimaSkin
package org.example.demo;
public class HeimaSkin extends AbstractSkin{
@Override
public void display() {
System.out.println("黑马皮肤");
}
}
SougouInput
package org.example.demo;
/**
* 搜狗输入法
*/
public class SougouInput {
/**
* 聚合
*/
private AbstractSkin skin;
/**
* 提供setter方法
*/
public void setSkin(AbstractSkin skin) {
this.skin = skin;
}
/**
* 调用皮肤的显示方法
*/
public void display(){
skin.display();
}
}
Client
package org.example.demo;
/**
* 测试类
*/
public class Client {
public static void main(String[] args) {
// 1、创建搜狗输入法对象
SougouInput input = new SougouInput();
// 2、创建皮肤对象
HeimaSkin skin = new HeimaSkin();
// 3、设值
input.setSkin(skin);
// 4、调用display方法
input.display();
}
}
每次只需修改第二步就能实现对扩展开放,对修改关闭
2.2、里氏替换原则
子类扩展父类的功能,但不重写父类的方法
Rectangle
package org.spring.designer.demo2;
/**
* 长方形类
*/
public class Rectangle {
private double length;
private double width;
public double getLength() {
return length;
}
public void setLength(double length) {
this.length = length;
}
public double getWidth() {
return width;
}
public void setWidth(double width) {
this.width = width;
}
}
Square
package org.spring.designer.demo2;
/**
* 正方体类
*/
public class Square extends Rectangle {
@Override
public void setLength(double length) {
super.setLength(length);
super.setWidth(length);
}
@Override
public void setWidth(double width) {
super.setWidth(width);
super.setLength(width);
}
}
RectangleDemo
package org.spring.designer.demo2;
public class RectangleDemo {
public static void main(String[] args) {
Rectangle rectangle = new Rectangle();
rectangle.setWidth(10);
rectangle.setLength(20);
resize(rectangle);
printLengthAndWidth(rectangle);
System.out.println("==============================================");
Square square = new Square();
square.setLength(10);
square.setWidth(10);
resize(square);
printLengthAndWidth(square);
}
// 扩宽方法
public static void resize(Rectangle rectangle){
while (rectangle.getWidth() <= rectangle.getLength()){
rectangle.setWidth(rectangle.getWidth()+1);
}
}
// 打印长宽方法
public static void printLengthAndWidth(Rectangle rectangle){
System.out.println(rectangle.getLength());
System.out.println(rectangle.getWidth());
}
}
执行以后发现长方形满足这段代码,正方形不满足。会死循环
则正方形不是长方形
改进后代码:
Quadrilateral
package org.spring.designer.demo2.after;
/**
* 四边形接口
*/
public interface Quadrilateral {
// 获取长
double getLength();
// 获取宽
double getWidth();
}
Square
package org.spring.designer.demo2.after;
public class Square implements Quadrilateral {
private double size;
public void setSize(double size) {
this.size = size;
}
@Override
public double getLength() {
return size;
}
@Override
public double getWidth() {
return size;
}
}
Rectangle
package org.spring.designer.demo2.after;
public class Rectangle implements Quadrilateral {
private double length;
private double width;
public void setLength(double length) {
this.length = length;
}
public void setWidth(double width) {
this.width = width;
}
@Override
public double getLength() {
return length;
}
@Override
public double getWidth() {
return width;
}
}
RectangleDemo
package org.spring.designer.demo2.after;
public class RectangleDemo {
public static void main(String[] args) {
Rectangle rectangle = new Rectangle();
rectangle.setWidth(10);
rectangle.setLength(20);
resize(rectangle);
printLengthAndWidth(rectangle);
System.out.println("==============================================");
}
// 扩宽方法
public static void resize(Rectangle rectangle){
while (rectangle.getWidth() <= rectangle.getLength()){
rectangle.setWidth(rectangle.getWidth()+1);
}
}
// 打印长宽方法
public static void printLengthAndWidth(Rectangle rectangle){
System.out.println(rectangle.getLength());
System.out.println(rectangle.getWidth());
}
}
2.3、依赖翻转原则
XiJieHardDisk
package org.spring.designer.demo3.before;
/**
* 希捷硬盘类
*/
public class XiJieHardDisk {
public void save(String data){
System.out.println("使用希捷硬盘保存数据:"+data);
}
public String get(){
System.out.println("使用希捷硬盘读取数据");
return "数据";
}
}
InterCpu
package org.spring.designer.demo3.before;
public class InterCpu {
public void run(){
System.out.println("使用inter处理器");
}
}
KingstonMemory
package org.spring.designer.demo3.before;
public class KingstonMemory {
public void save(){
System.out.println("使用金士顿内存条");
}
}
Computer
package org.spring.designer.demo3.before;
public class Computer {
private XiJieHardDisk hardDisk;
private InterCpu cpu;
private KingstonMemory memory;
public XiJieHardDisk getHardDisk() {
return hardDisk;
}
public void setHardDisk(XiJieHardDisk hardDisk) {
this.hardDisk = hardDisk;
}
public InterCpu getCpu() {
return cpu;
}
public void setCpu(InterCpu cpu) {
this.cpu = cpu;
}
public KingstonMemory getMemory() {
return memory;
}
public void setMemory(KingstonMemory memory) {
this.memory = memory;
}
public void run(){
System.out.println("开始计算机");
String data = hardDisk.get();
System.out.println("从硬盘上获取的是:"+data);
cpu.run();
memory.save();
}
}
ComputerDemo
package org.spring.designer.demo3.before;
public class ComputerDemo {
public static void main(String[] args) {
// 创建组件对象
InterCpu cpu = new InterCpu();
KingstonMemory memory = new KingstonMemory();
XiJieHardDisk hardDisk = new XiJieHardDisk();
Computer computer = new Computer();
// 组装电脑
computer.setHardDisk(hardDisk);
computer.setMemory(memory);
computer.setCpu(cpu);
computer.run();
}
}
优化后的,使用依赖翻转原则:
HardDisk
package org.spring.designer.demo3.after;
public interface HardDisk {
// 保存数据
public void save(String data);
// 获取数据
public String get();
}
Cpu
package org.spring.designer.demo3.after;
public interface Cpu {
public void run();
}
Memory
package org.spring.designer.demo3.after;
public interface Memory {
public void save();
}
XiJieHardDisk
package org.spring.designer.demo3.after;
/**
* 希捷硬盘类
*/
public class XiJieHardDisk implements HardDisk {
public void save(String data){
System.out.println("使用希捷硬盘保存数据:"+data);
}
public String get(){
System.out.println("使用希捷硬盘读取数据");
return "数据";
}
}
InterCpu
package org.spring.designer.demo3.after;
public class InterCpu implements Cpu{
public void run(){
System.out.println("使用inter处理器");
}
}
KingstonMemory
package org.spring.designer.demo3.after;
public class KingstonMemory implements Memory {
public void save(){
System.out.println("使用金士顿内存条");
}
}
Computer
package org.spring.designer.demo3.after;
public class Computer {
private HardDisk hardDisk;
private Cpu cpu;
private Memory memory;
public HardDisk getHardDisk() {
return hardDisk;
}
public void setHardDisk(HardDisk hardDisk) {
this.hardDisk = hardDisk;
}
public Cpu getCpu() {
return cpu;
}
public void setCpu(Cpu cpu) {
this.cpu = cpu;
}
public Memory getMemory() {
return memory;
}
public void setMemory(Memory memory) {
this.memory = memory;
}
public void run(){
System.out.println("开始计算机");
String data = hardDisk.get();
System.out.println("从硬盘上获取的是:"+data);
cpu.run();
memory.save();
}
}
ComputerDemo
package org.spring.designer.demo3.after;
public class ComputerDemo {
public static void main(String[] args) {
// 创建组件对象
Cpu cpu = new InterCpu();
Memory memory = new KingstonMemory();
HardDisk hardDisk = new XiJieHardDisk();
Computer computer = new Computer();
// 组装电脑
computer.setHardDisk(hardDisk);
computer.setMemory(memory);
computer.setCpu(cpu);
computer.run();
}
}
2.4、单一职责原则
单一职责:一个类不要承担多个职责。
1、类依赖过多的其他类。
导致修改一个类,其他类跟着受影响。不符合高内聚低耦合思想
2、类的名称和实际功能关联不大:
像用户和短信类。不是一回事可以不用放在一个类
3、类的代码行数过多,方法较大,应该拆分
比如需求如下:
后端需求:列表查询
前端需求
一个类有一个接口:通过参数的不同来区分前端查询接口,后端查询接口。(违背了单一职责原则)
怎么改变? 拆分接口(2个api)是最简单的改变方式
2.5、接口隔离原则
当用户类既可以删除和发送短信的时候,如果有两个团队同时开发。那很容易误操作
重构方式:
1、将user里的短信发送方法提取出来
2、单独写一个接口和实现类
3、下层注入MsgSender而不是注入User。User只负责注册。删除。不负责发送短信。
3、设计模式
3.1、单例模式(懒汉/饿汉模式)
懒汉模式:
package org.spring.designer.single;
/**
* 懒汉模式
*/
public class LazySingletonTest {
public static void main(String[] args) {
}
}
class LazySingleton {
private static LazySingleton lazySingleton;
// 1、私有化类构造方法(避免直接创建该类实例)
private LazySingleton() {
}
// 2、初始化实例方法
public static LazySingleton getInstance() {
return lazySingleton;
}
}
直接返回实例不合理进行改进
package org.spring.designer.single;
/**
* 懒汉模式
*/
public class LazySingletonTest {
public static void main(String[] args) {
}
}
class LazySingleton {
private static LazySingleton lazySingleton;
// 1、私有化类构造方法(避免直接创建该类实例)
private LazySingleton() {
}
// 2、初始化实例方法
public static LazySingleton getInstance() {
if (null == lazySingleton){
lazySingleton = new LazySingleton();
}
return lazySingleton;
}
}
此时会出现线程不安全问题,改进方式:double check(双重加锁)
package org.spring.designer.single;
/**
* 懒汉模式
*/
public class LazySingletonTest {
public static void main(String[] args) {
}
}
class LazySingleton {
private static LazySingleton lazySingleton;
// 1、私有化类构造方法(避免直接创建该类实例)
private LazySingleton() {
}
// 2、初始化实例方法
public static LazySingleton getInstance() {
// 当实例为空时加锁
if (null == lazySingleton){
synchronized (LazySingleton.class){
// 当多个线程执行到这里时再次判断。双重加锁优化
if (null == lazySingleton){
lazySingleton = new LazySingleton();
}
}
}
return lazySingleton;
}
}
但是此时线程安全问题虽然解决,但是存在空指针问题
new对象在jvm中会做以下操作:
1、开辟空间
2、初始化空间
3、给引用类型赋值
它不一定按着这个既定顺序执行
可能是这个顺序:
1、开辟空间
3、给引用类型赋值
2、初始化空间
###当t1线程执行到第三步,t2线程进来。发现实例并不为空,直接返回实例(此实例尚初始化空间),则导致空指针异常。如何避免?加关键字volatile
package org.spring.designer.single;
/**
* 懒汉模式
*/
public class LazySingletonTest {
public static void main(String[] args) {
}
}
class LazySingleton {
private volatile static LazySingleton lazySingleton;
// 1、私有化类构造方法(避免直接创建该类实例)
private LazySingleton() {
}
// 2、初始化实例方法
public static LazySingleton getInstance() {
// 当实例为空时加锁
if (null == lazySingleton){
synchronized (LazySingleton.class){
// 当多个线程执行到这里时再次判断。双重加锁优化
if (null == lazySingleton){
lazySingleton = new LazySingleton();
}
}
}
return lazySingleton;
}
}
饿汉模式:
package org.spring.designer.single;
/**
* 饿汉模式
*/
public class HungrySingletonTest {
public static void main(String[] args) {
}
}
class HungrySingleton{
private static HungrySingleton hungrySingleton = new HungrySingleton();
private HungrySingleton(){}
public static HungrySingleton getInstance(){
return hungrySingleton;
}
}
package org.spring.designer.single;
/**
* 饿汉模式
*/
public class HungrySingletonTest {
public static void main(String[] args) {
HungrySingleton hungrySingleton = HungrySingleton.getInstance();
}
}
class HungrySingleton{
static {
System.out.println("HungrySingleton class init");
}
private static HungrySingleton hungrySingleton = new HungrySingleton();
private HungrySingleton(){}
public static HungrySingleton getInstance(){
return hungrySingleton;
}
}
package org.spring.designer.single;
/**
* 饿汉模式
*/
public class HungrySingletonTest {
public static void main(String[] args) {
System.out.println("name:"+HungrySingleton.name);
// HungrySingleton hungrySingleton = HungrySingleton.getInstance();
}
}
class HungrySingleton{
public static String name = "ljs";
static {
System.out.println("HungrySingleton class init");
}
private static HungrySingleton hungrySingleton = new HungrySingleton();
private HungrySingleton(){}
public static HungrySingleton getInstance(){
return hungrySingleton;
}
}
当我们访问类的属性或方法时也会导致类的初始化
如何实现饿汉模式,在我们需要初始化类实例的时候,再初始化呢?
1、只初始化了外部的类
package org.spring.designer.single;
/**
* 饿汉模式-匿名内部类(优化结构)
*/
public class InnerSingletonTest {
public static void main(String[] args) {
System.out.println(InnerSingleton.name);
// System.out.println(InnerSingleton.getInstance());
}
}
class InnerSingleton{
public static String name = "ljs";
static {
System.out.println("init InnerSingleton");
}
private static class SingleHolder {
static {
System.out.println("init SingleHolder");
}
private static InnerSingleton instance = new InnerSingleton();
}
private InnerSingleton(){
}
public static InnerSingleton getInstance(){
return SingleHolder.instance;
}
}
2、两个类都被初始化了
package org.spring.designer.single;
/**
* 饿汉模式-匿名内部类(优化结构)
*/
public class InnerSingletonTest {
public static void main(String[] args) {
//System.out.println(InnerSingleton.name);
System.out.println(InnerSingleton.getInstance());
}
}
class InnerSingleton{
public static String name = "ljs";
static {
System.out.println("init InnerSingleton");
}
private static class SingleHolder {
static {
System.out.println("init SingleHolder");
}
private static InnerSingleton instance = new InnerSingleton();
}
private InnerSingleton(){
}
public static InnerSingleton getInstance(){
return SingleHolder.instance;
}
}
3、使用反射机制创建多实例。反射机制创建的实例与自己调用方法的实例不是同一个对象
package org.spring.designer.single;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
/**
* 饿汉模式
*/
public class HungrySingletonTest {
public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
System.out.println("name:"+HungrySingleton.name);
// HungrySingleton hungrySingleton = HungrySingleton.getInstance();
// 反射机制创建多实例
Constructor<HungrySingleton> declaredConstructor = HungrySingleton.class.getDeclaredConstructor();
declaredConstructor.setAccessible(true);
HungrySingleton hungrySingleton = declaredConstructor.newInstance();
HungrySingleton instance = HungrySingleton.getInstance();
System.out.println(hungrySingleton == instance);
}
}
class HungrySingleton{
public static String name = "ljs";
static {
System.out.println("HungrySingleton class init");
}
private static HungrySingleton hungrySingleton = new HungrySingleton();
private HungrySingleton(){}
public static HungrySingleton getInstance(){
return hungrySingleton;
}
}
如何避免?在构造函数中进行判断
package org.spring.designer.single;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
/**
* 饿汉模式
*/
public class HungrySingletonTest {
public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
System.out.println("name:"+HungrySingleton.name);
// HungrySingleton hungrySingleton = HungrySingleton.getInstance();
// 反射机制创建多实例
Constructor<HungrySingleton> declaredConstructor = HungrySingleton.class.getDeclaredConstructor();
declaredConstructor.setAccessible(true);
HungrySingleton hungrySingleton = declaredConstructor.newInstance();
HungrySingleton instance = HungrySingleton.getInstance();
System.out.println(hungrySingleton == instance);
}
}
class HungrySingleton{
public static String name = "ljs";
static {
System.out.println("HungrySingleton class init");
}
private static HungrySingleton hungrySingleton = new HungrySingleton();
private HungrySingleton(){
if (hungrySingleton != null){
throw new RuntimeException("不允许多实例");
}
}
public static HungrySingleton getInstance(){
return hungrySingleton;
}
}
4、枚举类型
package org.spring.designer.single;
/**
* 枚举类型单例模式测试
*/
public class EnumSingletonTest {
public static void main(String[] args) {
EnumSingleton instance1 = EnumSingleton.INSTANCE;
EnumSingleton instance2 = EnumSingleton.INSTANCE;
instance1.print();
System.out.println(instance1 == instance2);
}
}
enum EnumSingleton{
INSTANCE;
public void print(){
System.out.println("xxxx");
}
}
##类加载的双亲委派机制:
一个类加载器加载一个类时,首先会把加载动作委派给他的父加载器,如果父加载器无法完成这个加载动作时才由该类加载器进行加载。由于类加载器会向上传递加载请求,所以一个类加载时,首先尝试加载它的肯定是启动类加载器(逐级向上传递请求,直到启动类加载器,它没有父加载器),之后根据是否能加载的结果逐级让子类加载器尝试加载,直到加载成功。
###jdk1.8的Runtime类源码就是用的饿汉模式
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//
package java.lang;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.StringTokenizer;
import sun.reflect.CallerSensitive;
import sun.reflect.Reflection;
public class Runtime {
private static Runtime currentRuntime = new Runtime();
public static Runtime getRuntime() {
return currentRuntime;
}
private Runtime() {
}
}
###jvm的序列化,反序列化
序列化
package org.spring.designer.single;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.Serializable;
/**
* 懒汉模式
*/
public class LazySingletonTest {
public static void main(String[] args) {
// 序列化
LazySingleton instance = LazySingleton.getInstance();
try {
ObjectOutputStream oos = new ObjectOutputStream( new FileOutputStream("test"));
oos.writeObject(instance);
} catch (IOException e) {
e.printStackTrace();
}
}
}
class LazySingleton implements Serializable {
private volatile static LazySingleton lazySingleton;
// 1、私有化类构造方法(避免直接创建该类实例)
private LazySingleton() {
}
// 2、初始化实例方法
public static LazySingleton getInstance() {
// 当实例为空时加锁
if (null == lazySingleton){
synchronized (LazySingleton.class){
// 当多个线程执行到这里时再次判断。双重加锁优化
if (null == lazySingleton){
lazySingleton = new LazySingleton();
}
}
}
return lazySingleton;
}
}
反序列化
package org.spring.designer.single;
import java.io.*;
/**
* 懒汉模式
*/
public class LazySingletonTest {
public static void main(String[] args) {
// 序列化
LazySingleton instance = LazySingleton.getInstance();
/*try {
ObjectOutputStream oos = new ObjectOutputStream( new FileOutputStream("test"));
oos.writeObject(instance);
} catch (IOException e) {
e.printStackTrace();
}*/
// 反序列化
try(ObjectInputStream ois = new ObjectInputStream( new FileInputStream("test"))) {
LazySingleton lazySingleton = (LazySingleton) ois.readObject();
System.out.println(instance == lazySingleton);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
class LazySingleton implements Serializable {
private volatile static LazySingleton lazySingleton;
// 1、私有化类构造方法(避免直接创建该类实例)
private LazySingleton() {
}
// 2、初始化实例方法
public static LazySingleton getInstance() {
// 当实例为空时加锁
if (null == lazySingleton){
synchronized (LazySingleton.class){
// 当多个线程执行到这里时再次判断。双重加锁优化
if (null == lazySingleton){
lazySingleton = new LazySingleton();
}
}
}
return lazySingleton;
}
}
答案是false。这种反序列化方式是破坏了单例模式
如何解决呢?
需要在后面加一个方法
package org.spring.designer.single;
import java.io.*;
/**
* 懒汉模式
*/
public class LazySingletonTest {
public static void main(String[] args) {
// 序列化
LazySingleton instance = LazySingleton.getInstance();
/*try {
ObjectOutputStream oos = new ObjectOutputStream( new FileOutputStream("test"));
oos.writeObject(instance);
} catch (IOException e) {
e.printStackTrace();
}*/
// 反序列化
try(ObjectInputStream ois = new ObjectInputStream( new FileInputStream("test"))) {
LazySingleton lazySingleton = (LazySingleton) ois.readObject();
System.out.println(instance == lazySingleton);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
class LazySingleton implements Serializable {
private volatile static LazySingleton lazySingleton;
// 1、私有化类构造方法(避免直接创建该类实例)
private LazySingleton() {
}
// 2、初始化实例方法
public static LazySingleton getInstance() {
// 当实例为空时加锁
if (null == lazySingleton){
synchronized (LazySingleton.class){
// 当多个线程执行到这里时再次判断。双重加锁优化
if (null == lazySingleton){
lazySingleton = new LazySingleton();
}
}
}
return lazySingleton;
}
// 新增的方法
Object readResolve() throws ObjectStreamException {
return getInstance();
}
}
但是出现了报错
这时候需定义一个常量
// 避免反序列化报错
private static final long serialVersionUID = 1577594553870516987L;
3.2、工厂模式
工厂模式定义:
定义一个用于创建对象的接口,让子类决定实例化哪一个类
类图
1、简单工厂形式:
package org.spring.designer.factory;
public class FactoryMethod{
public static void main(String[] args) {
Application application = new Application();
Product product = application.getObject("0");
product.createProduct();
}
}
class SimpleFactory {
public static Product createProdcut(String type) {
if (type.equals("0")) {
return new ProductB();
} else if (type.equals("1")) {
return new ProductB1();
} else {
return null;
}
}
}
interface Product{
public void createProduct();
}
class ProductB implements Product{
@Override
public void createProduct() {
System.out.println("product B createProduct");
}
}
class ProductB1 implements Product{
@Override
public void createProduct() {
System.out.println("product B1 createProduct");
}
}
class Application{
private Product createProduct(String type){
return SimpleFactory.createProdcut(type);
}
Product getObject(String type){
Product product = createProduct(type);
return product;
}
}
2、工厂方法模式:
package org.spring.designer.factory1;
public class FactoryMethod {
public static void main(String[] args) {
Application1 application1 = new ConcreteProductA1();
Product1 object = application1.getObject();
object.method1();
}
}
// 稳定接口
interface Product1{
public void method1();
}
// 具体实现
class ProductA implements Product1 {
public void method1() {
System.out.println("ProductA.method1 executed. ");
}
}
class ProductA1 implements Product1 {
public void method1() {
System.out.println("ProductA1.method1 executed. ");
}
}
abstract class Application1{
abstract Product1 createProduct();
Product1 getObject(){
Product1 product = createProduct();
return product;
}
}
// 工厂方法具体实现类
class ConcreteProductA extends Application1 {
@Override
Product1 createProduct() {
// ....
return new ProductA();
}
}
class ConcreteProductA1 extends Application1 {
@Override
Product1 createProduct() {
//...
return new ProductA1();
}
}
应用场景
- 当你不知道改使用对象的确切类型的时候
- 当你希望为库或框架提供扩展其内部组件的方法时
主要优点:
-
将具体产品和创建者解耦
-
符合单一职责原则
-
符合开闭原则
3.3、抽象工厂模式
定义:提供一个创建一系列对象的接口,无需指定它们具体的类。
package org.spring.designer.abstractFactory;
public class AbstractFactoryTest {
public static void main(String[] args) {
IDatabaseUtils databaseUtils = new MysqlDataBaseUtil();
IConnection connection = databaseUtils.getConnection();
connection.connection();
ICommand command = databaseUtils.getCommand();
command.command();
}
}
/**
* 定义数据库连接
*/
interface IConnection{
void connection();
}
class MysqlConnection implements IConnection{
@Override
public void connection() {
System.out.println("mysql connected");
}
}
/**
* 定义发送
*/
interface ICommand{
void command();
}
class MysqlCommand implements ICommand{
@Override
public void command() {
System.out.println("mysql command");
}
}
interface IDatabaseUtils{
IConnection getConnection();
ICommand getCommand();
}
class MysqlDataBaseUtil implements IDatabaseUtils{
@Override
public IConnection getConnection() {
return new MysqlConnection();
}
@Override
public ICommand getCommand() {
return new MysqlCommand();
}
}
如果要进行oracle的实现:
package org.spring.designer.abstractFactory;
public class AbstractFactoryTest {
public static void main(String[] args) {
IDatabaseUtils databaseUtils = new OracleDataBaseUtil();
IConnection connection = databaseUtils.getConnection();
connection.connection();
ICommand command = databaseUtils.getCommand();
command.command();
}
}
/**
* 定义数据库连接
*/
interface IConnection{
void connection();
}
class MysqlConnection implements IConnection{
@Override
public void connection() {
System.out.println("mysql connected");
}
}
class OracleConnection implements IConnection{
@Override
public void connection() {
System.out.println("oracle connected");
}
}
/**
* 定义发送
*/
interface ICommand{
void command();
}
class MysqlCommand implements ICommand{
@Override
public void command() {
System.out.println("mysql command");
}
}
class OracleCommand implements ICommand{
@Override
public void command() {
System.out.println("oracle command");
}
}
interface IDatabaseUtils{
IConnection getConnection();
ICommand getCommand();
}
class MysqlDataBaseUtil implements IDatabaseUtils{
@Override
public IConnection getConnection() {
return new MysqlConnection();
}
@Override
public ICommand getCommand() {
return new MysqlCommand();
}
}
class OracleDataBaseUtil implements IDatabaseUtils{
@Override
public IConnection getConnection() {
return new OracleConnection();
}
@Override
public ICommand getCommand() {
return new OracleCommand();
}
}