深入理解享元模式、解释器模式、访问者模式
一,享元模式
池技术都有了解,线程池,数据库连接池。都是通过共享对象的方式来减少内存的压力。享元模式就是通过共享技术来实现对象的共享。之前有了解工厂模式,工厂模式往往更加适用于少对象的,在特定情况下的对象判断调用,假如要去实现一个国家计算机考试的代码,通过工厂模式来创建,那肯定不行的。有多少个考生 ,就会要创建多少个对象出来。往往通过一个共享的对象下嵌入不同对象去获取数据录入即可。下面的这个例子出自《大话设计模式》中对于相同html代码实现不同需求与服务器挂载的共享模拟。这样可以减少服务器的租赁与增强代码的复用性。
public abstract class WebSiteFlyweight {
public abstract void use(User user);
}
public class ConcreteWebSite extends WebSiteFlyweight{
//内部内容
private String instate;
private final String outState;
public ConcreteWebSite(String outState){
this.outState = outState;
}
@Override
public void use(User user) {
System.out.println("use for" + outState);
}
}
public class ConcreteWsFactory {
private Map<String,WebSiteFlyweight> map = new HashMap<String,WebSiteFlyweight>();
public WebSiteFlyweight getConcreteWebSite(String outState){
if(!map.containsKey(outState)){
map.put(outState, new ConcreteWebSite(outState));
}
return map.get(outState);
}
}
public class User {
private String name;
public User(String name){
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
public class Main {
public static void main(String[] args) {
ConcreteWsFactory cwdfactory = new ConcreteWsFactory();
ConcreteWebSite cws = (ConcreteWebSite) cwdfactory.getConcreteWebSite("博客");
cws.use(new User("小明"));
ConcreteWebSite cws2 = (ConcreteWebSite) cwdfactory.getConcreteWebSite("博客");
cws.use(new User("晓东"));
ConcreteWebSite cws3 = (ConcreteWebSite) cwdfactory.getConcreteWebSite("主题");
cws3.use(new User("小红"));
}
}
二,解释器模式
先说一个工作中的实际经历,富文本框表情前后端交互往往只能交换一串类似 “/00010X”之类的字符串,这个时候,在前端需要将这串字符串转换成实际的富文本框中的具体某一表情在页面上显示。这就要求前端需要有一套转换解释这些字符串的“字典”。这个“字典”便是起到一个解释的作用。解释器模式对给定的一门语言,定义它的文法的一个表示方式,定义一个解释器去解释具体的含义。下面的代码就简单模拟一下解释器ABC与阿拉伯数字之间的翻译。
public class PlayerContext {
private String context;
public String getContext() {
return context;
}
public void setContext(String context) {
this.context = context;
}
}
public abstract class Expression {
public PlayerContext interrupt(PlayerContext pc ){
if(pc.getContext().length() <=0){
return null;
}else{
String useContext = pc.getContext().substring(0, 1);
pc.setContext(pc.getContext().substring(1)); //作为新的context存入
excute(useContext);
return pc;
}
}
protected abstract void excute(String useContext);
}
public class MusicExpression extends Expression {
@Override
protected void excute(String useContext) {
String note="";
switch(useContext){
case "A":
note="1";
break;
case "B":
note="2";
break;
case "C":
note="3";
break;
}
System.out.print(note);
}
}
public class Main {
public static void main(String[] args) {
PlayerContext playerContext = new PlayerContext();
playerContext.setContext("ABACCABBACCC");
Expression expression = new MusicExpression();
while(playerContext.getContext().length()!=0){
expression.interrupt(playerContext);
}
}
}
三,访问者模式
《大话设计模式》中对访问者模式是这样解释的,表示一个作用与某对象结构中的各元素的操作,它使你可以在不改变元素的前提下定义作用这些元素的新操作。有些难以理解,我个人归纳了一下,访问者模式通过将被访问对象的行文封装到一起,方便了访问的内容切换,同时也方便增加新的操作。但是却会复杂了数据结构本身,也就是访问者。看下面的代码,对于需要访问的对象,在Acess中声明添加非常的容易,很好的做到了单一原则。但是对于访问者,假如还出现了一个新的性别类型呢?添加的数据结构变化就会很多。实际上对于访问者,代码之间的耦合性是很强很强的。这边就是访问者模式的缺点,所以在使用该模式,需要针对数据结构相对稳定的系统,不容易对数据结构新添加。
public abstract class Person {
protected abstract void Accept(Action action);
}
public class Woman extends Person {
@Override
protected void Accept(Action action) {
action.getWomanConculusion(this);
}
}
public class Man extends Person {
@Override
protected void Accept(Action action) {
action.getManConclusion(this);
}
}
//将被访问操作封装成一个 被访问对象
public abstract class Action {
protected abstract void getManConclusion(Man man);
protected abstract void getWomanConculusion(Woman woman);
}
public class AccessAction extends Action{
@Override
protected void getManConclusion(Man man) {
System.out.println("男人成功时,背后多半有一个伟大的女人");
}
@Override
protected void getWomanConculusion(Woman woman) {
System.out.println("女人成功时,背后多半有一个伟大的男人");
}
}
public class ActionOperation {
List<Person> plist = new ArrayList<Person>();
public void add(Person person){
plist.add(person);
}
public void rm(Person person){
plist.remove(person);
}
//遍历让每个访问者去访问被访问对象
public void itera(Action action){
for(int i=0;i<plist.size();i++){
plist.get(i).Accept(action);
}
}
}
public class Main {
public static void main(String[] args) {
ActionOperation ao = new ActionOperation();
Person man = new Man();
Person woman = new Woman();
ao.add(man);
ao.add(woman);
Action action = new AccessAction();
ao.itera(action);
}
}
还没有评论,来说两句吧...