设计原则
设计原则 | 说明 | 解释 | 方案 |
---|---|---|---|
开闭原则 | 对扩展开放,对修改关闭 | 有新功能加入,不改变原有的类 | 多用接口和抽象类 |
里式代换原则 | 基类可以被子类替换 | 子类完全可以替代父类 | 使用抽象类继承,不适用具体类继承 |
合成复用原则 | 依赖于抽象,不要依赖于具体的类 | / | / |
接口隔离原则 | 使用多个隔离的接口比单个接口好 | 所有方法写在一个就口中,不如分而治之 | 建立最小接口 |
迪米特法则 | 一个软件实体尽可能少的和其它实体发生作用 | 尽可能少的直接关联或依赖 | 通过中间类建立关系 |
依赖倒转原则 | 尽可能使用合成聚合,而不是使用继承 | / | 尽量使用合成聚合 |
创建者模式
创建者模式提供创建对象的机制,能够提升已有代码的灵活性和复用性。
工厂方法模式
概要
工厂方法模式定义了一个创建对象的接口,但由子类决定要实例化的对象是哪一个,工厂方法让类把实例化对象推迟到子类。
抽象工厂模式
概要
抽象工厂模式提供一个接口,用于创建相关或依赖对象的家族,而不需要明确指定具体类.
demo
package cn.superstallion;
/**
* 工厂方法demo
*/
public class FactoryPattern {
public static void main(String[] args) {
SportsMeet sportsMeet = new SportsMeetFactory();
sportsMeet.RegisterForSport("athletics");
sportsMeet.RegisterForSport("swimming");
}
}
//运动会
//使用工厂方法模式为奥运会添加一些项目
abstract class SportsMeet {
//抽象方法将具体的实例化下移到子类,
abstract public Sport createSport(String sportName);
public void RegisterForSport(String sportName){
createSport(sportName);
}
}
//运动项目,比如田径,游泳
//使用抽象工厂模式为项目添加子项目
abstract class Sport{
//子项目工厂不需要知道具体的子项目
public SpecificItemsFactory factory;
abstract void prepare();
}
//运动会项目的子项目,比如田径运动会50米,100米
//工厂抽象接口
interface SpecificItemsFactory{
void create50();
void create100();
}
//运动会项目工厂
class SportsMeetFactory extends SportsMeet{
public SportsMeetFactory(){
System.out.println("运动会开启");
}
@Override
public Sport createSport(String sportName) {
if (sportName.equals("athletics")){
return new Athletics(new AthleticsItemsFactory());
}else if(sportName.equals("swimming")){
return new Swimming(new SwimmingItemsFactory());
}
return null;
}
}
//田径子项目工厂
class AthleticsItemsFactory implements SpecificItemsFactory{
@Override
public void create50() {
System.out.println("添加50跑项目");
}
@Override
public void create100() {
System.out.println("添加100米跑项目");
}
}
//游泳子项木工厂
class SwimmingItemsFactory implements SpecificItemsFactory{
@Override
public void create50() {
System.out.println("添加50米游泳项目");
}
@Override
public void create100() {
System.out.println("添加100米游泳项目");
}
}
//田径项目
class Athletics extends Sport{
public Athletics(SpecificItemsFactory specificItemsFactory){
this.factory=specificItemsFactory;
System.out.println("田径项目被创建了");
prepare();
}
@Override
void prepare() {
factory.create50();
factory.create100();
}
}
//游泳项目
class Swimming extends Sport{
public Swimming(SpecificItemsFactory specificItemsFactory){
this.factory=specificItemsFactory;
System.out.println("游泳项目被创建了");
prepare();
}
@Override
void prepare() {
factory.create50();
factory.create100();
}
}
单例模式
概要
单例模式确保一个类只有一个实例,并提供一个全局访问点,单例模式需要注意多线程和多个类加载器分别加载的问题,这都可能导致单例模式失效.
demo
package cn.superstallion;
/**
* 单例模式demo
*/
public class SingletonPattern {
public static void main(String[] args) {
President1 president = President1.getInstance();
}
}
//一个学校只能有一个正校长
class President1 {
private static President1 president1;
private President1(){
}
synchronized static public President1 getInstance(){
if (president1==null){
president1=new President1();
}
return president1;
}
}
//性能优化版1
class President2{
static private President2 president2=new President2();
private President2(){
}
synchronized static public President2 getInstance(){
return president2;
}
}
//性能优化版2
class President3{
static volatile private President3 president3;
private President3(){
}
public static President3 getInstance(){
if (president3==null){
synchronized (President3.class){
if (president3==null){
president3=new President3();
}
}
}
return president3;
}
}
策略模式
概要
策略模式定义了算法族,分别封装起来,让他们之间可以替换,此模式让算法的变化独立于使用算法的客户。
demo
package cn.superstallion;
/**
* 策略模式demo
*/
public class StrategyPattern {
public static void main(String[] args) {
Person person=new Student();
person.swim();
}
}
class Person{
//使用组合的方式添加游泳行为
public SwimBehavior swimBehavior;
public void swim(){
swimBehavior.swim();
}
}
interface SwimBehavior{
public void swim();
}
class Student extends Person{
//指定自己的游泳行为
public Student(){
swimBehavior=new StudentSwimBehavior();
}
}
//不同职业用用行为不同,将这种变化提取出来封装,如果要添加其他职业时只需定义专属的游泳行为而不需要修改已有的代码。
class StudentSwimBehavior implements SwimBehavior{
@Override
public void swim() {
System.out.println("student");
}
}
观察者模式
概要
观察者模式定义了对象之间的一对多依赖,这样一来,当一个对象改变状态时,它的所有依赖者都会收到通知并自动更新。
demo
在java.util
包下也有实现的观察者模式接口,但现在已不建议使用
package cn.superstallion;
import java.util.ArrayList;
import java.util.List;
/**
* 观察者模式demo
*/
//测试
public class ObserverPattern {
public static void main(String[] args) {
Up up = new Up();
Noticer noticer = new Noticer(up);
up.publishMyProduction();
}
}
//被观察者接口
interface Observable{
void registerObserver(Observer observer);
void blacklistObserver(Observer observer);
void informObserver();
}
//观察者接口
interface Observer{
void update(String upProduction);
}
//实现被观察者接口
class Up implements Observable{
//存储关注我的人
private List<Observer> noticers= new ArrayList();
//存储我的作品
private String myProduction;
//通知我谁关注了我
@Override
public void registerObserver(Observer observer) {
noticers.add(observer);
}
//拉黑某关注着
@Override
public void blacklistObserver(Observer observer) {
noticers.remove(observer);
}
//发布新作品后通知每个关注着
@Override
public void informObserver() {
noticers.forEach((noticer)->{
noticer.update(myProduction);
});
}
//发布作品
public void publishMyProduction(){
this.myProduction="我是up主,这是我本次更新的内容的预览,感兴趣请进入观看";
informObserver();
}
}
//实现观察者接口
class Noticer implements Observer{
//保存Up作品
private String upProduction;
//保存关注的Up
private Observable up;
public Noticer(Observable up){
this.up=up;
//通知Up我关注了它
up.registerObserver(this);
}
//更新我的通知
@Override
public void update( String upProduction) {
this.upProduction=upProduction;
displayUpProduction();
}
//展示Up作品
public void displayUpProduction(){
System.out.println(upProduction);
}
}
装饰者模式
概要
装饰模式动态地将责任附加到对象上,若要扩展功能,装饰者模式提供了比继承更有弹性的方案.
demo
package cn.superstallion;
/**
* 装饰着模式demo
*/
//测试
public class DecorativePattern {
public static void main(String[] args) {
ComputerHardwareConfiguration homeComputerConfiguration=new HomeComputerConfiguration();
ComputerHardwareConfiguration gameComputerConfiguration=new GameComputerConfiguration();
homeComputerConfiguration=new OrdinaryKeyboard(homeComputerConfiguration);
gameComputerConfiguration=new MechanicalKeyboard(gameComputerConfiguration);
System.out.println(homeComputerConfiguration.getDescription()+"\n需要花"+homeComputerConfiguration.cost()+"元");
System.out.println(gameComputerConfiguration.getDescription()+"\n需要花"+gameComputerConfiguration.cost()+"元");
}
}
//基本电脑硬件配置(装饰着和被装饰着共同的接口)
abstract class ComputerHardwareConfiguration{
public String description;
public Integer basicCost=1000;
public String getDescription(){
return this.description;
}
abstract Integer cost();
}
//具体电脑硬件(装饰者接口)
abstract class ComputerHardware extends ComputerHardwareConfiguration{
abstract public String getDescription();
}
//家用电脑硬件配置(被装饰者)
class HomeComputerConfiguration extends ComputerHardwareConfiguration{
public HomeComputerConfiguration(){
description="家用电脑配置:基本配置,";
}
@Override
Integer cost() {
return basicCost;
}
}
//游戏电脑硬件配置(被装饰者)
class GameComputerConfiguration extends ComputerHardwareConfiguration{
public GameComputerConfiguration(){
this.description="游戏电脑配置:基本配置,";
}
@Override
Integer cost(){
return basicCost;
};
}
//机械键盘(装饰着)
class MechanicalKeyboard extends ComputerHardware{
//记录被装饰着
private ComputerHardwareConfiguration computerHardwareConfiguration;
public MechanicalKeyboard(ComputerHardwareConfiguration computerHardwareConfiguration)
{
this.computerHardwareConfiguration=computerHardwareConfiguration;
}
@Override
Integer cost() {
return computerHardwareConfiguration.basicCost+200;
}
@Override
public String getDescription() {
return computerHardwareConfiguration.description+"机械键盘";
}
}
//普通键盘(装饰着)
class OrdinaryKeyboard extends ComputerHardware{
//记录被装饰着
private ComputerHardwareConfiguration computerHardwareConfiguration;
public OrdinaryKeyboard(ComputerHardwareConfiguration computerHardwareConfiguration)
{
this.computerHardwareConfiguration=computerHardwareConfiguration;
}
@Override
Integer cost() {
return computerHardwareConfiguration.basicCost+100;
}
@Override
public String getDescription() {
return computerHardwareConfiguration.description+"普通键盘";
}
}
命令模式
概要
命令模式将请求封装成对象,以便使用不同的请求队列或者日志来参数化其他对象,命令模式也支持可撤销模式.
demo
package cn.superstallion;
/**
* 命令模式demo
*/
public class CommandPattern {
public static void main(String[] args) {
//选择mp3要播放的音乐
Song song=new Song("最后的印第安人");
MP3RemoteControl mp3 = new MP3RemoteControl(song);
//分别为两个键设置功能
mp3.setCommend( 0,new BeginCommend());
mp3.setCommend(1,new PauseCommend());
//开始播放音乐
mp3.pressButton(0);
try {
Thread.currentThread().sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
//暂停音乐
mp3.pressButton(1);
}
}
//音乐
class Song{
private String songName;
private String state;
public Song(String songName){
this.songName=songName;
}
public void setState(String state){
this.state=state;
}
public String getState(){
return state;
}
public String getSongName() {
return songName;
}
public void setSongName(String songName) {
this.songName = songName;
}
}
//二键MP3
class MP3RemoteControl{
private Song song;
private commend[] buttons=new commend[2];
public MP3RemoteControl(Song song){
this.song=song;
}
public void pressButton(Integer position){
buttons[position].execute(song);
}
public void setCommend(Integer position,commend commend){
buttons[position]=commend;
}
}
//MP3命令接口
interface commend {
void execute(Song song);
}
//开始播放命令
class BeginCommend implements commend{
@Override
public void execute(Song song){
song.setState("begin");
System.out.println(song.getSongName()+" was "+song.getState());
}
}
//暂停播放命令
class PauseCommend implements commend {
@Override
public void execute(Song song){
song.setState("pause");
System.out.println(song.getSongName()+" was "+song.getState());
}
}
适配器模式
概要
适配器模式将一个类的接口,转换成客户希望的另一个接口,适配器让原本接口不兼容的类做到合作无间.
demo
package cn.superstallion;
/**
* 适配器模式demo
*/
public class AdapterPattern {
public static void main(String[] args) {
}
}
//三线插头
interface ThreeWirePlug {
void threeWirePlugMethod();
}
//二线插头
interface TowWirePlug{
void towWirePlugMethod();
}
//二线转三线
class TowWirePlugAdapter implements ThreeWirePlug{
private TowWirePlug towWirePlug;
public TowWirePlugAdapter(TowWirePlug towWirePlug){
this.towWirePlug=towWirePlug;
}
@Override
public void threeWirePlugMethod() {
}
}
外观模式
概要
外观模式提供了一个统一的接口,用来访问一个子系统中的一群接口,外观定义了一个高级接口,让子系统更容易使用.
demo
package cn.superstallion;
/**
* 外观模式demo
*/
public class FacadePatterns {
public static void main(String[] args) {
}
}
//全自动洗衣机,洗衣服时只需要调用一下方法,此方法将普通洗衣机的行为进行封装
//外观模式
class AutomaticWashingMachine{
private Water water;
private LaundryDetergent laundryDetergent;
private DrainAwayWater drainAwayWater;
public void washClothes(){
water.doIt();
laundryDetergent.doIt();
drainAwayWater.doIt();
}
}
//加水
interface Water{
void doIt();
}
//加洗衣液
interface LaundryDetergent {
void doIt();
}
//排水
interface DrainAwayWater{
void doIt();
}
模板方法模式
概要
模板方法模式在一个方法中定义了一个算法的骨架,而将一些步骤延迟到子类中.模板方法使得子类可以在不改变算法结构的情况下,重新定义算法中的某些步骤.
demo
package cn.superstallion;
public class TemplateMethodPattern {
public static void main(String[] args) {
}
}
abstract class AbstractClass{
//模板方法
final void templateMethods(){
primitiveOperation1();
if (hook()){
primitiveOperation2();
}
concreteOperation();
}
//由具体类实现
abstract void primitiveOperation1();
abstract void primitiveOperation2();
//子类无法覆盖
final void concreteOperation(){
}
//钩子函数,子类可以覆盖,让子类有能力对算法的不同点进行挂钩
boolean hook(){
return true;
}
}
迭代器模式
概要
迭代器模式提供了一种方法顺序访问一个聚合对象中的各个元素,而又不暴漏其内部的表示.
demo
迭代器模式demi即为java中Iterable和Iterator接口的实现.
组合模式
概要
组合模式允许你将对象组合成树型结构来表现"整体/部分"层次结构,组合能让客户以一致的方式处理个别对象以及对象组合.
demo
package cn.superstallion;
import java.util.ArrayList;
/**
* 组合模式demo
*/
public class CompositePattern {
public static void main(String[] args) {
Contents book=new OneLevelContent("book");
Contents chapterOne= new OneLevelContent("第一章");
Contents chapterTwo = new TowLevelContent("第二章");
TowLevelContent firstSegment= new TowLevelContent("第一节");
TowLevelContent secondSegment= new TowLevelContent("第二节");
chapterOne.addContentItem(firstSegment);
chapterOne.addContentItem(secondSegment);
book.addContentItem(chapterOne);
book.addContentItem(chapterTwo);
try {
System.out.println("book---------------");
book.printChild();
System.out.println("chapterOne------------");
chapterOne.printChild();
System.out.println("chapterTow---------");
chapterTwo.printChild();
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
}
//目录接口
interface Contents{
default void addContentItem(Contents content){
throw new UnsupportedOperationException();
}
default void removeContextItem( Contents content){
throw new UnsupportedOperationException();
}
default String getName(){
throw new UnsupportedOperationException();
}
default void printChild(){
throw new UnsupportedOperationException("没有子目录");
}
}
//一级目录
class OneLevelContent implements Contents{
private String name;
private ArrayList<Contents> towLevelContents;
public OneLevelContent(String name){
towLevelContents=new ArrayList<>();
this.name=name;
}
@Override
public void addContentItem(Contents content) {
towLevelContents.add(content);
}
@Override
public void removeContextItem(Contents content) {
towLevelContents.remove(content);
}
@Override
public void printChild() {
for (Contents content:towLevelContents){
System.out.println(content.getName());
}
}
@Override
public String getName() {
return name;
}
}
//二级目录
class TowLevelContent implements Contents{
private String name;
public TowLevelContent(String name){
this.name=name;
}
@Override
public String getName() {
return name;
}
}
状态模式
概要
状态模式允许对象在内部状态改变时改变它的行为,对象看起来好像修改了它的类.
demo
package cn.superstallion;
public class StatePattern {
public static void main(String[] args) {
Switch aSwitch = new Switch();
aSwitch.turnOn();
aSwitch.turnOff();
}
}
//开关
class Switch{
//所有状态
private State turnOnState;
private State turnOffState;
//当前状态
private State state;
public Switch(){
turnOffState=new TurnOffState(this);
turnOnState=new TurnOnState(this);
state=turnOffState;
}
public State getTurnOnState() {
return turnOnState;
}
public State getTurnOffState() {
return turnOffState;
}
public void setState(State state) {
this.state = state;
}
public void turnOn(){
state.turnOn();
}
public void turnOff(){
state.turnOff();
}
}
//状态接口
interface State{
default void turnOff(){
throw new UnsupportedOperationException();
};
default void turnOn(){
throw new UnsupportedOperationException();
};
}
//打开状态
class TurnOnState implements State{
private Switch aSwitch;
public TurnOnState( Switch aSwitch) {
this.aSwitch=aSwitch;
}
@Override
public void turnOff() {
aSwitch.setState(aSwitch.getTurnOffState());
System.out.println("开关已关闭");
}
}
//关闭状态
class TurnOffState implements State{
private Switch aSwitch;
public TurnOffState(Switch aSwitch){
this.aSwitch=aSwitch;
}
@Override
public void turnOn(){
aSwitch.setState(aSwitch.getTurnOnState());
System.out.println("开关已打开");
}
}
动态代理模式
概要
动态代理模式为另一个对象提供一个替身或占位符以控制对这个对象的访问,可以在访问对象的时限制方法调用的权限以及添加一些额外功能.
demo
java反射包下已有代理模式的接口
package cn.superstallion;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
* 代理模式demo
*/
public class DynamicProxyPattern {
public static void main(String[] args) {
File file = new File("核心机密");
FileOptions fileProxy = (FileOptions)Proxy.newProxyInstance(
File.class.getClassLoader(),
File.class.getInterfaces(),
new FileHandler(file));
System.out.println(fileProxy.getName());
fileProxy.read();
fileProxy.write();
}
}
//要想使用代理代理类和被代理类必须实现一个共同接口
interface FileOptions{
String getName();
void read();
void write();
}
//被代理类
class File implements FileOptions{
private String fileName;
public File(String name){
this.fileName=name;
}
@Override
public void read() {
System.out.println("我是文件的内容");
}
@Override
public void write() {
}
@Override
public String getName() {
return fileName;
}
}
//当调用代理类的方法时交给调用处理器处理
class FileHandler implements InvocationHandler{
private File file;
public FileHandler(File file){
this.file=file;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if (method.getName().equals("write")){
System.out.println("您没有写的权限");
}else if(method.getName().equals("read")){
method.invoke(file,null);
}else if(method.getName().equals("getName")){
return method.invoke(file,null);
}
return null;
}
}