适配器模式
- 类适配器模式
当希望将一个类转换成满足另一个新接口的类时,可以使用类的适配器模式,创建一个新类,继承原有的类,实现新的接口即可。
class Target01{
public void method01(){
System.out.println("this is Taget01`s method01");
}
}
interface Source{
public void method01();
public void method02();
}
class Taget02 extends Target01 implements Source{
@Override
public void method02() {
System.out.println("this is Source`s method02");
}
}
public class Test{
public static void main(String[] args) {
Taget02 taget02=new Taget02();
taget02.method01();
taget02.method02();
}
}
- 对象适配器模式
当希望将一个对象转换成满足另一个新接口的对象时,可以创建一个类,持有原类的一个实例,在该类的方法中,调用实例的方法就行。
class Target01{
public void method01(){
System.out.println("this is Taget01`s method01");
}
}
interface Source{
public void method01();
public void method02();
}
class Target02 implements Source{
Target01 target01;
Target02(Target01 target01){
this.target01=target01;
}
@Override
public void method01() {
target01.method01();
}
@Override
public void method02() {
System.out.println("this is Source`s method02");
}
}
public class Test{
public static void main(String[] args) {
Target01 target01=new Target01();
Target02 target02=new Target02(target01);
target02.method01();
target02.method02();
}
}
- 接口适配器模式
当不希望实现一个接口中所有的方法时,可以创建一个抽象类,实现所有方法,我们写别的类的时候,继承抽象类即可。
interface Source{
public void method01();
public void method02();
}
abstract class Target01 implements Source{
@Override
public void method01() {
System.out.println();
}
@Override
public void method02() {
System.out.println();
}
}
class Target02 extends Target01{
@Override
public void method01() {
System.out.println("this is Target01`s method01");
}
}
class Target03 extends Target01{
@Override
public void method02() {
System.out.println("this is Target01`s method02");
}
}
public class Test{
public static void main(String[] args) {
Target02 target02=new Target02();
Target03 target03=new Target03();
target02.method01();
target02.method02();
target03.method01();
target03.method02();
}
}
装饰模式
装饰模式就是给一个对象增加一些新的功能,而且是动态的,要求装饰对象和被装饰对象实现同一个接口。装饰对象持有被装饰对象的实例。
interface Source{
public void method();
}
//被装饰类
class Target01 implements Source {
@Override
public void method() {
System.out.println("这是装饰类");
}
}
//装饰类
class Target02 implements Source {
Source source;
Target02(Source source){
super();
this.source=source;
}
@Override
public void method() {
System.out.println("装饰前");
source.method();
System.out.println("装饰后");
}
}
public class Test{
public static void main(String[] args) {
Source target01=new Target01();
Source target02=new Target02(target01);
target02.method();
}
}
装饰器模式的应用场景:
- 需要扩展一个类的功能。
- 动态的为一个对象增加功能,而且还能动态撤销。(继承不能做到这一点,继承的功能是静态的,不能动态增删。)
缺点:产生过多相似的对象,不易排错!
代理者模式
为某对象提供一种代理以控制对该对象的访问。即客户端通过代理间接地访问该对象,从而限制、增强或修改该对象的一些特性。比如我们在租房子的时候会去找中介,为什么呢?因为你对该地区房屋的信息掌握的不够全面,希望找一个更熟悉的人去帮你做,此处的代理就是这个意思。再如我们有的时候打官司,我们需要请律师,因为律师在法律方面有专长,可以替我们进行操作,表达我们的想法。
interface Source{
public void method();
}
//原类
class Target01 implements Source {
@Override
public void method() {
System.out.println("这是我的原类");
}
}
//代理类
class Target02 implements Source {
Target01 target01;
Target02(){
super();
this.target01=new Target01();
}
@Override
public void method() {
before();
target01.method();
after();
}
void before(){
System.out.println("代理前");
}
void after(){
System.out.println("代理后");
}
}
public class Test{
public static void main(String[] args) {
Source source=new Target02();
source.method();
}
}
代理模式的应用场景:
如果已有的方法在使用的时候需要对原有的方法进行改进,此时有两种办法:
- 修改原有的方法来适应。这样违反了“对扩展开放,对修改关闭”的原则。
- 就是采用一个代理类调用原有的方法,且对产生的结果进行控制。这种方法就是代理模式。
使用代理模式,可以将功能划分的更加清晰,有助于后期维护!
外观模式
外观模式是为了解决类与类之间的依赖关系的,像spring一样,可以将类和类之间的关系配置到配置文件中,而外观模式就是将他们的关系放在一个类中,降低了类类之间的耦合度,该模式中没有涉及到接口。
class Cpu{
void startup(){
System.out.println("Cpu Start up");
}
void shutdown(){
System.out.println("Cpu Shut down");
}
}
class Memory{
void startup(){
System.out.println("Memory Start up");
}
void shutdown(){
System.out.println("Memory Shut down");
}
}
class Disk{
void startup(){
System.out.println("Disk Start up");
}
void shutdown(){
System.out.println("Disk Shut down");
}
}
class Computer{
private Cpu cpu;
private Memory memory;
private Disk disk;
Computer(){
this.cpu=new Cpu();
this.memory=new Memory();
this.disk=new Disk();
}
void startup(){
System.out.println("Computer Start up");
cpu.startup();
memory.startup();
disk.startup();
System.out.println("Computer Start Finished");
}
void shutdown(){
System.out.println("Computer Shut down");
cpu.shutdown();
memory.shutdown();
disk.shutdown();
System.out.println("Computer Shut Finished");
}
}
public class Test{
public static void main(String[] args) {
Computer computer=new Computer();
computer.startup();
System.out.println();
System.out.println();
computer.shutdown();
}
}
如果我们没有Computer类,那么,CPU、Memory、Disk他们之间将会相互持有实例,产生关系,这样会造成严重的依赖,修改一个类,可能会带来其他类的修改,这不是我们想要看到的,有了Computer类,他们之间的关系被放在了Computer类里,这样就起到了解耦的作用,这就是外观模式!
桥接模式
桥接模式就是把事物和其具体实现分开,使他们可以各自独立的变化。桥接的用意是:将抽象化与实现化解耦,使得二者可以独立变化,它是用组合关系代替继承关系来实现,从而降低了抽象和实现这两个可变维度的耦合度。像我们常用的JDBC桥DriverManager一样,JDBC进行连接数据库的时候,在各个数据库之间进行切换,基本不需要动太多的代码,甚至丝毫不用动,原因就是JDBC提供统一接口,每个数据库提供各自的实现,用一个叫做数据库驱动的程序来桥接就行了。
interface Source{
void method();
}
class Target01 implements Source{
@Override
public void method() {
System.out.println("this is Target01`s method");
}
}
class Target02 implements Source{
@Override
public void method() {
System.out.println("this is Target02`s method");
}
}
abstract class Bridge {
private Source source;
void method(){
source.method();
}
public Source getSource(){
return this.source;
}
public void setSource(Source source){
this.source=source;
}
}
class Act01 extends Bridge {
@Override
void method() {
getSource().method();
}
}
public class Test{
public static void main(String[] args) {
Bridge action=new Act01();
Source source1=new Target01();
action.setSource(source1);
action.method();
System.out.println();
Source source2=new Target02();
action.setSource(source2);
action.method();
}
}
组合模式
组合模式有时又叫部分-整体模式在处理类似树形结构的问题时比较方便。
class TreeNode{
private String name;
private TreeNode parent;
private Vector<TreeNode> children=new Vector<TreeNode>();
public TreeNode(String name){
this.name=name;
}
public String getName(){
return name;
}
public void setName(String name){
this.name=name;
}
public void setParent(TreeNode parent) {
this.parent = parent;
}
public TreeNode getParent(){
return parent;
}
public void addChildren(TreeNode child){
children.add(child);
System.out.println("增加子节点:"+child.getName());
}
public void removeChildren(TreeNode child){
System.out.println("删除子节点:"+child.getName());
children.remove(child);
}
public String getChildren(){
Iterator iterable= children.iterator();
String names="";
TreeNode treeNode=null;
while (iterable.hasNext()){
treeNode=(TreeNode)iterable.next();
names+=treeNode.getName();
}
return names;
}
}
class Tree{
//根节点
public TreeNode treeNode=null;
public Tree(String name){
treeNode=new TreeNode(name);
}
}
public class Test{
public static void main(String[] args) {
Tree tree=new Tree("A");
TreeNode treeNode01=new TreeNode("B");
TreeNode treeNode02=new TreeNode("C");
tree.treeNode.addChildren(treeNode01);
tree.treeNode.addChildren(treeNode02);
System.out.println(tree.treeNode.getChildren());
tree.treeNode.removeChildren(treeNode02);
System.out.println(tree.treeNode.getChildren());
}
}
使用场景:将多个对象组合在一起进行操作,常用于表示树形结构中,例如二叉树,数等。
享元模式
享元模式的主要目的是实现对象的共享,即共享池,当系统中对象多的时候可以减少内存的开销,通常与工厂模式一起使用。
策略模式
策略(Strategy)模式:定义了一系列算法,并将每个算法封装起来,使它们可以相互替换,且算法的改变不会影响使用算法的客户。需要设计一个接口,为一系列实现类提供统一的方法,多个实现类实现该接口,设计一个抽象类(可有可无,属于辅助类),提供辅助函数。
interface ICalculaor{
public int calculator(String data);
}
abstract class AbstractCalculator{
public int[] replace(String data,String shell){
String[] strlist=data.split(shell);
int[] arrlist= new int[strlist.length];
for(int i=0;i<strlist.length;i++){
arrlist[i]=Integer.parseInt(strlist[i]);
}
return arrlist;
}
}
class Plus extends AbstractCalculator implements ICalculaor{
@Override
public int calculator(String data) {
int[] arraylist=replace(data,"\\+");
int num=0;
for (int i=0;i<arraylist.length;i++){
num+=arraylist[i];
}
return num;
}
}
class Minus extends AbstractCalculator implements ICalculaor{
@Override
public int calculator(String data) {
int[] arraylist=replace(data,"\\-");
int num=arraylist[0];
for (int i=1;i<arraylist.length;i++){
num-=arraylist[i];
}
return num;
}
}
class Multiply extends AbstractCalculator implements ICalculaor{
@Override
public int calculator(String data) {
int[] arraylist=replace(data,"\\*");
int num=1;
for (int i=0;i<arraylist.length;i++){
num*=arraylist[i];
}
return num;
}
}
public class Test{
public static void main(String[] args) {
String a="2+4+1+9";
String b="2-4-1-9";
String c="2*4*1*9";
Plus plus=new Plus();
Minus minus=new Minus();
Multiply multiply=new Multiply();
System.out.println(plus.calculator(a));
System.out.println(minus.calculator(b));
System.out.println(multiply.calculator(c));
}
}
策略模式的决定权在用户,系统本身提供不同算法的实现,新增或者删除算法,对各种算法做封装。因此,策略模式多用在算法决策系统中,外部用户只需要决定用哪个算法即可。
模板方法模式
模板方法(TemplateMethod)模式:定义一个操作中的算法骨架,而将算法的一些步骤延迟到子类中,使得子类可以不改变该算法结构的情况下重定义该算法的某些特定步骤。即:一个抽象类中,有一个主方法,再定义1…n个方法,可以是抽象的,也可以是实际的方法,定义一个类,继承该抽象类,重写抽象方法,通过调用抽象类,实现对子类的调用。
abstract class AbstractCalculator{
public int calculate(String data,String shell){
int array[] = replace(data,shell);
return calculate(array[0],array[1]);
}
abstract public int calculate(int num1,int num2);
public int[] replace(String data,String shell){
String[] strlist=data.split(shell);
int[] arrlist= new int[strlist.length];
for(int i=0;i<strlist.length;i++){
arrlist[i]=Integer.parseInt(strlist[i]);
}
return arrlist;
}
}
class Plus extends AbstractCalculator{
@Override
public int calculate(int num1, int num2) {
return num1+num2;
}
}
public class Test{
public static void main(String[] args) {
String a="2+4";
Plus plus=new Plus();
System.out.println(plus.calculate(a,"\\+"));
}
}
观察者模式
观察者(Observer)模式:多个对象间存在一对多关系,当一个对象发生改变时,会把这种改变通知给其他多个对象,从而影响其他对象的行为。
interface Observer{
public void send();
}
class Observer01 implements Observer{
@Override
public void send() {
System.out.println("observer01 is sent !");
}
}
class Observer02 implements Observer{
@Override
public void send() {
System.out.println("observer02 is sent !");
}
}
interface Subject {
/*增加观察者*/
public void add(Observer observer);
/*删除观察者*/
public void del(Observer observer);
/*通知所有的观察者*/
public void notifyObservers();
/*自身的操作*/
public void operation();
}
abstract class AbSubject01 implements Subject{
private Vector<Observer> vector=new Vector<Observer>();
@Override
public void add(Observer observer) {
vector.add(observer);
}
@Override
public void del(Observer observer) {
vector.remove(observer);
}
@Override
public void notifyObservers() {
Enumeration<Observer> enumeration=vector.elements();
while (enumeration.hasMoreElements()){
enumeration.nextElement().send();
}
}
}
class Subject01 extends AbSubject01{
@Override
public void operation() {
System.out.println("send to myself!");
notifyObservers();
}
}
public class Test{
public static void main(String[] args) {
Subject subject=new Subject01();
Observer01 observer01=new Observer01();
Observer02 observer02=new Observer02();
subject.add(observer01);
subject.add(observer02);
subject.operation();
subject.del(observer01);
subject.del(observer02);
subject.operation();
}
}
单例模式
单例(Singleton)模式:某个类只能生成一个实例,该类提供了一个全局访问点供外部获取该实例,其拓展是有限多例模式。
这样的模式有几个好处:
某些类创建比较频繁,对于一些大型的对象,这是一笔很大的系统开销。
省去了new操作符,降低了系统内存的使用频率,减轻GC压力。
有些类如交易所的核心交易引擎,控制着交易流程,如果该类可以创建多个的话,系统完全乱了。(比如一个军队出现了多个司令员同时指挥,肯定会乱成一团),所以只有使用单例模式,才能保证核心交易服务器独立控制整个流程。
优点:只有一个实例,节约了内存资源,提高了系统性能
缺点:
没有抽象层,不能扩展
职责过重,违背了单一性原则
public class Test {
public static void main(String[] args) {
System.out.println(Singleton.getInstance().hashCode());
System.out.println(Singleton.getInstance().hashCode());
}
}
class Singleton{
private static Singleton singleton=null;
private Singleton(){};
public static Singleton getInstance(){
if (singleton==null){
synchronized (Singleton.class){
if (singleton==null){
singleton=new Singleton();
}
}
}
return singleton;
}
}
PS:多例设计模式
单例设计模式只留下一个类的一个实例化对象,而多例设计模式,会定义出多个对象。
public class Test {
public static void main(String[] args) {
System.out.println(Grade.getInstance(1));
System.out.println(Grade.getInstance(2));
}
}
class Grade{
private String grade;
private static Grade good=new Grade("good");
private static Grade great=new Grade("great");
private static Grade worse=new Grade("worse");
private Grade(String grade){
this.grade=grade;
}
public String toString(){
return this.grade;
}
public static Grade getInstance(int grade){
switch (grade){
case 1:
return worse;
case 2:
return good;
case 3:
return great;
default:
return null;
}
}
}