Java的设计模式三大类
1.中介者模式(Mediator)
中介者模式也是用来降低类类之间的耦合的,因为如果类类之间有依赖关系的话,不利于功能的拓展和维护,因为只要修改一个对象,其它关联的对象都得进行修改。如果使用中介者模式,只需关心和Mediator类的关系,具体类类之间的关系及调度交给Mediator就行,这有点像spring容器的作用。
User接口:
public abstract class User {
private Mediator mediator;
public Mediator getMediator() {
return mediator;
}
public User(Mediator mediator) {
this.mediator = mediator;
}
public abstract void work();
}
User1:
public class User1 extends User {
public User1(Mediator mediator) {
super(mediator);
}
@Override
public void work() {
System.out.println("user1 exe....");
}
}
User2:
public class User2 extends User {
public User2(Mediator mediator) {
super(mediator);
}
@Override
public void work() {
System.out.println("user2 exe....");
}
}
中介接口:
public interface Mediator {
public void creatMediator();
public void allWorkers();
}
中介实现:
public class myMediator implements Mediator{
private User1 user1;
private User2 user2;
public User2 getUser2() {
return user2;
}
public User1 getUser1() {
return user1;
}
@Override
public void creatMediator() {
user1=new User1(this);
user2=new User2(this);
}
@Override
public void allWorkers() {
user1.work();
user2.work();
}
}
测试:
public class Test {
public static void main(String[] args){
Mediator mediator=new myMediator();
mediator.creatMediator();
mediator.allWorkers();
}
}
结果:
类图如下:
2.解释器模式(Interpreter Pattern)
解释器模式是我们暂时的最后一讲,一般主要应用在OOP开发中的编译器的开发中,所以适用面比较窄。
上下文环境类:
public class Context {
private int num1;
private int num2;
public Context(int num1,int num2) {
this.num1 = num1;
this.num2 = num2;
}
public int getNum2() {
return num2;
}
public void setNum2(int num2) {
this.num2 = num2;
}
public int getNum1() {
return num1;
}
public void setNum1(int num1) {
this.num1 = num1;
}
}
计算接口:
public interface Expression {
public int expression(Context context);
}
实现类:
public class Plus implements Expression{
@Override
public int expression(Context context) {
return context.getNum1()+context.getNum2();
}
}
public class Minus implements Expression{
@Override
public int expression(Context context) {
return context.getNum1()-context.getNum2();
}
}
测试:
public class Test {
public static void main(String[] args){
//21+22-2
int result=new Minus().expression(new Context(new Plus().expression(new Context(21,22)),2));
System.out.println(result);
}
}
结果:41
类图如下:
3.备忘录模式(Memento)
主要目的是保存一个对象的某个状态,以便在适当的时候恢复对象,个人觉得叫备份模式更形象些,通俗的讲下:假设有原始类A,A中有各种属性,A可以决定需要备份的属性,备忘录类B是用来存储A的一些内部状态,类C呢,就是一个用来存储备忘录的,且只能存储,不能修改等操作。
原始类A:
public class A {
private String Value;
private B b;
public A(String value) {
Value = value;
}
public String getValue() {
return Value;
}
public void setValue(String value) {
Value = value;
}
public B creatB(){
return new B(Value);
}
public void restoreB(B b){
this.Value=b.getValue();
}
}
备忘录B:
public class B {
private String value;
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public B(String value) {
this.value = value;
}
}
存储备忘录的类C:
public class C {
private B b;
public B getB() {
return b;
}
public void setB(B b) {
this.b = b;
}
public C(B b) {
this.b = b;
}
}
测试:
public class Test {
public static void main(String[] args){
//创建原始类
A a=new A("water");
//创建备忘录
C c=new C(a.creatB());
//修改原始类的状态
a.setValue("ice");
//恢复原始类的状态
a.restoreB(c.getB());
}
}
结果:
类图如下:
4.享元模式(Flyweight)
我们就拿这幅画来说,里面画了草、树、路、山、天空等等。如果没有用享元模式,我们可能这样子实现。
蜡笔接口。
interface ICrayon {
void draw(String place);
}
蜡笔。
// 蜡笔
class Crayon implements ICrayon {
private String color;
public Crayon(String color) {
System.out.println("---新建【" + color + "】蜡笔" );
this.color = color;
}
@Override
public void draw(String place) {
System.out.println("用" + this.color + "蜡笔画" + place);
}
}
测试代码。这幅画是小明和小红一起画,小明画了草和路,小红画了树和蓝天。
public class NoFlyweightTest {
public static void main(String[] args) {
drawByXiaoMing();
drawByXiaoHong();
}
public static void drawByXiaoMing() {
ICrayon greenCrayon = new Crayon("绿色");
greenCrayon.draw("草");
ICrayon grayCrayon = new Crayon("灰色");
grayCrayon.draw("路");
}
public static void drawByXiaoHong() {
ICrayon blueCrayon = new Crayon("蓝色");
blueCrayon.draw("蓝天");
ICrayon greenCrayon = new Crayon("绿色");
greenCrayon.draw("树");
}
}
打印结果:
---新建【绿色】蜡笔
用绿色蜡笔画草
---新建【灰色】蜡笔
用灰色蜡笔画路
---新建【蓝色】蜡笔
用蓝色蜡笔画蓝天
---新建【绿色】蜡笔
用绿色蜡笔画树
我们发现小明和小红都用了绿色蜡笔,而这里新建了 2 次绿色蜡笔,也就是在整个作画过程中,小明和小红并不是共用一套蜡笔,而是各自用一套蜡笔,在现实中是没什么问题的,但是在软件开发中,如果这种情况出现,其实相当于资源浪费,因为每个蜡笔都会占用内存,可以共用的我们尽量共用,节省一些内存空间,特别是出现很多这种可以共享却没有共享的对象时候。下面我们引入享元模式。享元模式实现方法相当于我们蜡笔都放在了笔袋,小明和小红用完就放到笔袋里面,每一种颜色的蜡笔只有一根,也就是他们共用一套蜡笔。代码如下所示。
笔袋代码。我们用了 Map 作为容器,如果容器里面没有想要颜色的蜡笔,则创建新的蜡笔,并存到容器里。
// 笔袋
class CrayonFactory {
private static Map<String, ICrayon> data = new HashMap<>();
public static ICrayon getCrayon(String color) {
if (data.containsKey(color)) {
return data.get(color);
}
ICrayon crayon = new Crayon(color);
data.put(color, crayon);
return crayon;
}
}
测试代码。
public class FlyweightTest {
public static void main(String[] args) {
drawByXiaoMing();
drawByXiaoHong();
}
public static void drawByXiaoMing() {
ICrayon greenCrayon = CrayonFactory.getCrayon("绿色");
greenCrayon.draw("草");
ICrayon grayCrayon = CrayonFactory.getCrayon("灰色");
grayCrayon.draw("路");
}
public static void drawByXiaoHong() {
ICrayon blueCrayon = CrayonFactory.getCrayon("蓝色");
blueCrayon.draw("蓝天");
ICrayon greenCrayon = CrayonFactory.getCrayon("绿色");
greenCrayon.draw("树");
}
}
打印结果:
---新建【绿色】蜡笔
用绿色蜡笔画草
---新建【灰色】蜡笔
用灰色蜡笔画路
---新建【蓝色】蜡笔
用蓝色蜡笔画蓝天
用绿色蜡笔画树
利用享元模式实现的结果,小红画树所用到的绿色蜡笔跟小明画草的绿色蜡笔一样,小红用到时并没有新建绿色蜡笔。
全部评论