二、结构型模式(7个)
1、适配器模式
//针对的是已经存在的组件或者系统,而你也有自己的接口规范,你不想去依赖对方的接口,
//这时候用适配器模式比较合适,用自己接口的一个实现去依赖对方的接口并做兼容转换工作
//自定义log接口
public interface ILogger {
void debug(String msg);
void info(String msg);
void warn(String msg);
void error(String msg);
}
/**
* @Title log4j日志框架适配器
* @Description
* @Author lvaolin
* @Date 2022/1/9 16:20
**/
public class Log4jAdapter implements ILogger {
private Log4jLogger log4jLogger = new Log4jLogger();
@Override
public void debug(String msg) {
//参数转换
log4jLogger.debug(msg);
}
@Override
public void info(String msg) {
//参数转换
log4jLogger.info(msg);
}
@Override
public void warn(String msg) {
//参数转换
log4jLogger.warn(msg);
}
@Override
public void error(String msg) {
//参数转换
log4jLogger.error(msg);
}
public Log4jLogger getLog4jLogger() {
return log4jLogger;
}
public void setLog4jLogger(Log4jLogger log4jLogger) {
this.log4jLogger = log4jLogger;
}
/**
* @Title Log4jLogger
* @Description 模拟已存在的log4j Logger
* @Author lvaolin
* @Date 2022/1/9 16:23
**/
static public class Log4jLogger {
public void debug(String msg) {
System.out.println(msg);
}
public void info(String msg) {
System.out.println(msg);
}
public void warn(String msg) {
System.out.println(msg);
}
public void error(String msg) {
System.out.println(msg);
}
}
}
2、桥接模式
//电脑品牌和电脑配置是多个维度的变化
//如果不用桥接模式就会出现子类的爆炸
//组合优于继承
public class Client {
public static void main(String[] args) {
//品牌
AbstractComputer dell3 = new ComputerDell(new CpuI3(),new Memory4G(),new Disk1T());
System.out.println(dell3.showInfo());
AbstractComputer huawei3 = new ComputerHuawei(new CpuI3(),new Memory4G(),new Disk1T());
System.out.println(huawei3.showInfo());
//配置的变化不需要增加任何新的品牌子类,配置是在独立的变化
AbstractComputer dell5 = new ComputerDell(new CpuI5(),new Memory4G(),new Disk1T());
System.out.println(dell5.showInfo());
AbstractComputer huawei5 = new ComputerHuawei(new CpuI5(),new Memory4G(),new Disk1T());
System.out.println(huawei5.showInfo());
}
}
@Data
public abstract class AbstractComputer {
private ICpu cpu;
private IMemory memory;
private IDisk disk;
public AbstractComputer(ICpu cpu,IMemory memory,IDisk disk){
this.cpu = cpu;
this.memory = memory;
this.disk = disk;
}
public abstract String showInfo();
}
public class ComputerDell extends AbstractComputer{
public ComputerDell(ICpu cpu, IMemory memory, IDisk disk){
super(cpu,memory,disk);
}
@Override
public String showInfo() {
return "dell computer:"+getCpu().cpu()+getMemory().memory()+getDisk().disk();
}
}
public class ComputerHuawei extends AbstractComputer{
public ComputerHuawei(ICpu cpu, IMemory memory, IDisk disk){
super(cpu,memory,disk);
}
@Override
public String showInfo() {
return "huawei computer:"+getCpu().cpu()+getMemory().memory()+getDisk().disk();
}
}
public interface ICpu {
String cpu();
}
public class CpuI3 implements ICpu{
@Override
public String cpu() {
return "I3";
}
}
public class CpuI5 implements ICpu{
@Override
public String cpu() {
return "I5";
}
}
public interface IMemory {
String memory();
}
public class Memory4G implements IMemory{
@Override
public String memory() {
return "4G内存";
}
}
public interface IDisk {
String disk();
}
public class Disk1T implements IDisk{
@Override
public String disk() {
return "1T";
}
}
3、组合模式
//为处理树状结构而生
/**
* 打印贵司所有职员薪资信息
*/
public class Client {
public static void main(String[] args) {
Department company = new Department("大黄鸭科技有限公司");
Department yanfabu = new Department("研发部");
Department ceshibu = new Department("测试部");
Worker worker001 = new Worker("王总", 1);
Worker yan01 = new Worker("研发1",100);
Worker ce01 = new Worker("测试1",100);
Worker ce02 = new Worker("测试2",100);
company.add(worker001);
company.add(yanfabu);
company.add(ceshibu);
yanfabu.add(yan01);
ceshibu.add(ce01);
ceshibu.add(ce02);
//打印该组织的所有员工信息
company.print(1);
}
}
----部门名称:大黄鸭科技有限公司
--------姓名:王总,薪资:1
--------部门名称:研发部
------------姓名:研发1,薪资:100
--------部门名称:测试部
------------姓名:测试1,薪资:100
------------姓名:测试2,薪资:100
public interface IComponent {
void add(IComponent e);
void remove(IComponent e);
List<IComponent> getSubordinates();
void print(int depth);
}
@Data
public class Department implements IComponent{
private String departmentName;
private List<IComponent> subordinates;
//构造函数
public Department(String departmentName) {
this.departmentName = departmentName;
subordinates = new ArrayList<IComponent>();
}
@Override
public void add(IComponent e) {
subordinates.add(e);
}
@Override
public void remove(IComponent e) {
subordinates.remove(e);
}
@Override
public List<IComponent> getSubordinates(){
return subordinates;
}
@Override
public void print(int depth){
String pre = "";
for(int i=0; i<depth; i++) {
pre +="----";
}
System.out.println(pre+"部门名称:"+departmentName);
for (IComponent subordinate : getSubordinates()) {
subordinate.print(depth+1);
}
}
}
@Data
public class Worker implements IComponent{
private String name;
private int salary;
private List<IComponent> subordinates = new ArrayList<>(0);
public Worker(String name, int sal) {
this.name = name;
this.salary = sal;
}
@Override
public void add(IComponent e) {
}
@Override
public void remove(IComponent e) {
}
@Override
public List<IComponent> getSubordinates(){
return subordinates;
}
@Override
public void print(int depth){
String pre = "";
for(int i=0; i<depth; i++) {
pre +="----";
}
System.out.println(pre+"姓名:"+name+",薪资:"+salary);
for (IComponent subordinate : getSubordinates()) {
subordinate.print(depth+1);
}
}
}
4、装饰器模式
//客官,你需要什么样的灌饼?加鸡蛋?加肠?加鸡柳?加辣椒?加豆瓣酱?加咸菜?
/**
* @Project fighting-core
* @Description 监控告警
* @Author lvaolin
* @Date 2022/1/6 上午11:41
*/
public class Client {
public static void main(String[] args) {
//你想要一个只发邮件的告警器
System.out.println("----------只发邮件的告警器---------");
Notifier mailNotifier = new MailNotifier();
mailNotifier.send("cpu 99% 了");
//我想要一个同时发送邮件和短信的告警器
System.out.println("----------同时发送邮件和短信的告警器----------");
Notifier smsNotifier = new SmsNotifier(mailNotifier);
smsNotifier.send("内存爆了");
//他想要一个同时按短信、邮件、企业微信、个人微信、QQ 顺序依次报警的告警器
System.out.println("----------同时按短信、邮件、企业微信、个人微信、QQ 顺序依次报警的告警器----");
Notifier heQq = new QqNotifier();
Notifier heWcNotifier = new WeChartNotifier(heQq);
Notifier heWwNotifier = new WeWorkNotifier(heWcNotifier);
Notifier heMailNotifier = new MailNotifier(heWwNotifier);
Notifier heSmsNotifier = new SmsNotifier(heMailNotifier);
heSmsNotifier.send("硬盘爆了");
}
}
public interface Notifier {
void send(String msg);
}
public class MailNotifier implements Notifier{
private Notifier notifier;
public MailNotifier(){
}
public MailNotifier(Notifier notifier){
this.notifier = notifier;
}
@Override
public void send(String msg) {
System.out.println("邮件告警发送--"+msg);
if (notifier!=null) {
notifier.send(msg);
}
}
}
public class QqNotifier implements Notifier{
private Notifier notifier;
public QqNotifier(){
}
public QqNotifier(Notifier notifier){
this.notifier = notifier;
}
@Override
public void send(String msg) {
System.out.println("QQ告警发送--"+msg);
if (notifier!=null) {
notifier.send(msg);
}
}
}
public class SmsNotifier implements Notifier{
private Notifier notifier;
public SmsNotifier(){
}
public SmsNotifier(Notifier notifier){
this.notifier = notifier;
}
@Override
public void send(String msg) {
System.out.println("短信告警发送--"+msg);
if (notifier!=null) {
notifier.send(msg);
}
}
}
public class WeChartNotifier implements Notifier{
private Notifier notifier;
public WeChartNotifier(){
}
public WeChartNotifier(Notifier notifier){
this.notifier = notifier;
}
@Override
public void send(String msg) {
System.out.println("微信告警发送--"+msg);
if (notifier!=null) {
notifier.send(msg);
}
}
}
public class WeWorkNotifier implements Notifier{
private Notifier notifier;
public WeWorkNotifier(){
}
public WeWorkNotifier(Notifier notifier){
this.notifier = notifier;
}
@Override
public void send(String msg) {
System.out.println("企业微信告警发送--"+msg);
if (notifier!=null) {
notifier.send(msg);
}
}
}
5、门面模式
//该隐藏的隐藏,只暴露最少的接口
//计算机关机
class Client {
public static void main(String[] args) {
Computer computer = new Computer();
computer.shutDown(); //只调用一个方法即可,无需了解复杂的关机步骤
}
}
class Computer{
public void shutDown(){
this.saveData();
this.exitProcess();
this.powerOff();
}
private void saveData(){
System.out.println("保存数据");
}
private void exitProcess(){
System.out.println("退出进程");
}
private void powerOff(){
System.out.println("断电");
}
}
6、享元模式
//通过复用(Cache)来大量减少内存的消耗,不变可复用的成为“内在状态”,多变不可复用的称为“外在状态”
public class Client {
public static void main(String[] args) {
FlyweightFactory flyweightFactory = new FlyweightFactory();
List<MovingBullet> list = new ArrayList<>();
//某人发射大量子弹
for (int i = 0; i < 10; i++) {
MovingBullet movingBullet = new MovingBullet();
movingBullet.setBulletBase(flyweightFactory.getBulletBase("red"));
movingBullet.setX(ThreadLocalRandom.current().nextInt(100));
movingBullet.setY(ThreadLocalRandom.current().nextInt(100));
movingBullet.setZ(ThreadLocalRandom.current().nextInt(100));
list.add(movingBullet);
System.out.println(movingBullet.toString());
}
}
}
@Data
public class BulletBase {
public BulletBase(String size,String weight,String type,String color){
this.size = size;
this.weight = weight;
this.type = type;
this.color = color;
}
//内存状态
private String size;
private String weight;
private String type;
private String color;
}
@Data
public class MovingBullet {
//不变的属性称为"内在状态",封装到另一个对象中,便于复用
private BulletBase bulletBase;
//下面三个属性是外在状态
private int x;
private int y;
private int z;
}
public class FlyweightFactory {
private Map<String,BulletBase> bulletBaseMap = new ConcurrentHashMap<>();
public BulletBase getBulletBase(String color){
BulletBase bulletBase = bulletBaseMap.get(color);
if (bulletBase==null) {
synchronized (FlyweightFactory.class){
bulletBase = new BulletBase("2cm", "100g", "ak47", color);
bulletBaseMap.putIfAbsent(color,bulletBase);
}
}
return bulletBase;
}
}
7、代理模式
//强调了 代理对象对目标对象的控制,包括接口性能监控,接口权限,调用日志,限流,熔断,降级等
public class Client {
public static void main(String[] args) {
Proxy proxy = new Proxy(new ServiceImpl1());
String resullt = proxy.method1();
System.out.println("结果:"+resullt);
}
}
//代理对象
public class Proxy implements ServiceIF{
private ServiceIF targetService;//目标对象
public Proxy(ServiceIF serviceIF){
this.targetService = serviceIF;
}
@Override
public String method1() {
System.out.println(targetService.getClass().getCanonicalName()+"被调用");
long beginTime = System.currentTimeMillis();
String result = targetService.method1();
System.out.println("接口耗时:"+(System.currentTimeMillis() - beginTime));
return result;
}
}
public interface ServiceIF {
String method1();
}
public class ServiceImpl1 implements ServiceIF {
@Override
public String method1() {
return "ok";
}
}