创建型模式:用于描述怎样创建对象,它的主要特点是将对象的创建与使用分离。
有单例、原型、工厂方法、抽象工厂、创建者等5种
结构型模式:用于描述如何将类或对象按某种布局组成更大的结构。
有代理、适配器、桥接、装饰、外观、享元、组合等7种
行为型模式:用于描述类或对象之间怎样相互协作共同完成单个对象无法单独完成的任务,
以及怎样分配职责。有模板方法、策略命令、职责链、状态、观察者、中介者、
迭代器、访问者、备忘录、解释器等11种
包含 类名 属性 方法
+ :表示public
- :表示private
# :表示protected
是对象之间的一种引用关系,用于表示一类对象与另一类对象之间的联系
单向关联
双向关联
自关联
是关联关系的一种,是强关联关系,是整体和部分之间的关系
表示类之间的整体与部分关系,它是一种更强烈的聚合关系。整体对象可以控制部分对象的生命周期,
一旦整体对象不存在,部分对象也将不存在
是一种使用关系,它是对象之间耦合度最弱的一种关联关系,是临时性的关联
在代码中,某个类的方法通过局部变量、方法的参数或者静态方法的调用来访问另一个类中的某些方法来
完成一些职责
继承关系是对象之间耦合度最大的一种关系,表示一般与特殊的关系,是父类与子类之间的关系
,是一种继承关系
实现关系是接口与实现类之间的关系
对扩展开放,对修改关闭
对程序需要进行拓展的时候,不能去修改原来的代码,要想做到这样需要使用接口和抽象类
/**
* 抽象皮肤类
*/
public abstract class AbstractSkin {
//显示使用哪个皮肤
public abstract void display();
}
/**
* 默认皮肤类
*/
public class DefaultSkin extends AbstractSkin{
@Override
public void display() {
System.out.println("默认皮肤");
}
}
/**
* 布布皮肤
*/
public class BuBuSkin extends AbstractSkin{
@Override
public void display() {
System.out.println("这是布布的皮肤");
}
}
/**
* 输入法
*/
public class YiErInput {
private AbstractSkin skin;
public void setSkin(AbstractSkin skin) {
this.skin = skin;
}
public void display(){
skin.display();
}
}
public class Client {
public static void main(String[] args) {
YiErInput input = new YiErInput();
//AbstractSkin skin = new DefaultSkin();
AbstractSkin skin = new BuBuSkin();
input.setSkin(skin);
input.display();
}
}
任何基类可以出现的地方,子类一定可以出现
子类可以扩展父类的功能,但不能改变父类原有的功能。也就是说子类继承父类时,
除添加新的方法完成新增功能外,尽量不要重写父类的方法
不复合里氏代换原则
/**
* 长方形类
*/
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;
}
}
/**
* 正方形类
*/
public class Square extends Rectangle{
@Override
public void setLength(double length) {
super.setLength(length);
super.setWidth(length);
}
@Override
public void setWidth(double width) {
super.setLength(width);
super.setWidth(width);
}
}
public class RectangleDemo {
public static void main(String[] args) {
//创建长方形对象
Rectangle r = new Rectangle();
r.setLength(10);
r.setWidth(5);
resize(r);
printLengthAndWidth(r);
System.out.println("===============");
//创建正方形对象
Rectangle s = new Square();
s.setLength(10);//设置长和宽
resize(s);
printLengthAndWidth(s);
}
//扩宽方法
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());
}
}
符合里氏代换原则
public interface Quadrilateral {
double getLength();//获取长
double getWidth();//获取宽
}
/**
* 正方形
*/
public class Square implements Quadrilateral{
private double side;
public double getSide() {
return side;
}
public void setSide(double side) {
this.side = side;
}
@Override
public double getLength() {
return side;
}
@Override
public double getWidth() {
return side;
}
}
/**
* 长方形类
*/
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;
}
}
public class RectangleDemo {
public static void main(String[] args) {
//创建长方形对象
Rectangle r = new Rectangle();
r.setLength(10);
r.setWidth(5);
resize(r);
printLengthAndWidth(r);
System.out.println("===============");
//创建正方形对象
Square s = new Square();
s.setSide(10);//设置长和宽
printLengthAndWidth(s);
}
//扩宽方法
public static void resize(Rectangle rectangle){
//判断宽是否小于等于长,就进行扩宽
while (rectangle.getWidth() <= rectangle.getLength()){
rectangle.setWidth(rectangle.getWidth() + 1);
}
}
//打印长和宽
public static void printLengthAndWidth(Quadrilateral quadrilateral){
System.out.println("长 : " + quadrilateral.getLength());
System.out.println("宽 : " + quadrilateral.getWidth());
}
}
高层模块不应该依赖于底层模块,两者都应该依赖其抽象;抽象不应该依赖于细节,细节应该依赖于抽象。
简单来说就是要求对抽象进行编程,不要对实现进行编程,这样就降低了客户与实现模块间的耦合
/**
* 硬盘接口
*/
public interface HardDisk {
//存储数据
public void save(String data);
//获取数据
public String getData();
}
public class XiJieHardDisk implements HardDisk{
@Override
public void save(String data) {
System.out.println("使用希捷硬盘存储数据为 : " + data);
}
@Override
public String getData() {
System.out.println("使用希捷硬盘获取数据");
return "data";
}
}
/**
* cpu接口
*/
public interface Cpu {
public void run();//运行
}
public class IntelCpu implements Cpu{
@Override
public void run() {
System.out.println("使用intel处理器");
}
}
/**
* 内存条接口
*/
public interface Memory {
public void save();
}
public class KingstonMemory implements Memory{
@Override
public void save() {
System.out.println("使用金士顿内存条");
}
}
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.getData();
System.out.println("从硬盘上获取的数据是 : " + data);
cpu.run();
memory.save();
}
}
public class ComputerDemo {
public static void main(String[] args) {
//创建计算机对象
Computer computer = new Computer();
//创建计算机的组件
HardDisk hardDisk = new XiJieHardDisk();//硬盘
Cpu cpu = new IntelCpu();//cpu
Memory memory = new KingstonMemory();//内存条
//组装
computer.setHardDisk(hardDisk);
computer.setCpu(cpu);
computer.setMemory(memory);
//运行
computer.run();
}
}
客户端不应该被迫依赖于它不使用的方法,一个类对另一个类的依赖应该建立在最小的接口上
/**
* 防盗接口
*/
public interface AntiTheft {
void antiTheft();
}
/**
* 防火接口
*/
public interface Fireproof {
void fireproof();
}
/**
* 防水接口
*/
public interface Waterproof {
void waterproof();
}
public class YourDoor implements AntiTheft,Fireproof,Waterproof{
@Override
public void antiTheft() {
System.out.println("防盗");
}
@Override
public void fireproof() {
System.out.println("防火");
}
@Override
public void waterproof() {
System.out.println("防水");
}
}
public class MyDoor implements Fireproof{
@Override
public void fireproof() {
System.out.println("只能防火");
}
}
public class DoorTest {
public static void main(String[] args) {
//创建安全门对象
YourDoor yourDoor = new YourDoor();
//功能
yourDoor.antiTheft();
yourDoor.fireproof();
yourDoor.waterproof();
System.out.println("---------------");
MyDoor myDoor = new MyDoor();
myDoor.fireproof();
}
}
尽量先使用组合或者聚合等关联关系来实现,其次才考虑继承关系来实现
通常类的复用分为继承复用和合成复用两种
继承复用简单易实现,但有以下缺点:
1.破坏了类的封装性,因为继承会将父类的实现细节暴露给子类,父类对子类是透明的
2.父类与子类的耦合度高,父类的实现的任何改变都会导致子类的实现发生变化,不宜与类的扩展与维护
3.它限制了复用的灵活性,从父类继承而来的实现是静态的,在编译时已经定义,所以在运行时不可能发生变化
组合或聚合复用,可以将已有对象纳入新对象中,使之成为新对象的一部分,新对象可以调用已有对象的功能,
他有以下优点:
1.它维持了类的封装性
2.对象间的耦合度低,可以在类的成员位置声明为抽象
3.复用的灵活性高,这种复用可以在运行时动态进行,新对象可以动态地引用与成员对象类型相同的对象
如果两个软件实体无须直接通信,那么就不应当发生直接的相互调用,可以通过第三方转发该调用。
其目的是降低类之间的耦合度,提高模块的相对独立性
/**
* 明星类
*/
public class Star {
private String name;
public Star(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
/**
* 粉丝类
*/
public class Fans {
private String name;
public Fans(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
/**
* 媒体公司类
*/
public class Company {
private String name;
public Company(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
/**
* 经纪人类
*/
public class Agent {
private Star star;
private Fans fans;
private Company company;
public void setStar(Star star) {
this.star = star;
}
public void setFans(Fans fans) {
this.fans = fans;
}
public void setCompany(Company company) {
this.company = company;
}
//和粉丝见面
public void meeting(){
System.out.println(star.getName() + " 和粉丝 " + fans.getName() + " 见面");
}
//和媒体公司合作
public void business(){
System.out.println(star.getName() + " 和 " + company.getName() + "" + " 合作");
}
}
public class Client {
public static void main(String[] args) {
//创建经纪人类
Agent agent = new Agent();
Star star = new Star("小红");
Fans fans = new Fans("沙雕");
Company company = new Company("巨坑人");
agent.setStar(star);
agent.setFans(fans);
agent.setCompany(company);
agent.meeting();
agent.business();
}
}