题目一:
请在草稿纸上手写一个单例模式的实现代码,拍照提交作业。
作答:
写法比较多,就写两种吧,平时基本上就用这两种。两种都是现成安全的。
1. 双检测写法
这里提一点,有些人会在 instance 变量上加 volatile 修饰符,其实是非必须,synchronized 关键字已经保证了 instance 变量的可见性和 synchronized 代码段中包含代码段的原子性。
如果加上 volatile,保证了 instance 的可见性。避免这样一种情况:某个线程已经为 instance 赋值,而另一个线程因 instance 可见性问题没有看到 instance 最新的值,再次通过了第一次 instance 为空判断的语句。但就像上面所说,及时通过了第一次 instance 为空判断,进入 synchronized 代码段后还有一次为空判断,依然线程安全。
但上面那种情况发生概率不大,即使发生了也没有同步问题。volatile 修饰略显多余。
2.静态内部类写法
Sigleton 类加载的时候,内部的 SigletonHolder 类不会被加载,只有在调用 getInstance 方法的时候 SigletonHolder 才会被加载并初始化,且由 classloader 保证了线程安全。
题目二:
请用组合设计模式编写程序,打印输出图 1 的窗口,窗口组件的树结构如图 2 所示,打印输出示例参考下图。
作答:
1. 类图:
定义一个 Component 接口,Composite 和 Leaf 这个接口。
Composite 表示组合节点,可以包含其他节点的节点,Leaf 表示叶子节点,叶子节点不能包含其他节点了。感觉这样会违反 LSP,但是也没有想到更好的实现。
Composite 有一个 Component 类型的容器成员变量,就是它支持了 Composite 可以包含其他节点的能力。
ComponentType 其实是个枚举,表示节点的类型。不属于组合模式的类。
2. 代码
2.1 Component 接口
public interface Component { void add(Component component); void print();}
复制代码
2.2 ComponentType 枚举类
public enum ComponentType { WinForm,Picture,Button,Frame,Lable,TextBox,PasswordBox,CheckBox,LinkLable}
复制代码
2.3 Composite 组合节点类
public class Composite implements Component { private List<Component> components; private String name; private ComponentType type;
public Composite(String name, ComponentType type) { this.components = new ArrayList<Component>(); this.name = name; this.type = type; }
@Override public void add(Component component) { components.add(component); }
@Override public void print() { System.out.println(String.format("print %s(%s)",type.name(),name)); for (Component component:components) { component.print(); } }}
复制代码
2.4 Leaf 叶子节点类
public class Leaf implements Component { private String name; private ComponentType type;
public Leaf(String name, ComponentType type) { this.name = name; this.type = type; }
@Override public void add(Component component) { throw new UnsupportedOperationException(); } @Override public void print() { System.out.println(String.format("print %s(%s)",type.name(),name)); }}
复制代码
2.5 Client 应用程序类
public class Client { public static void main(String[] args) { Component winForm=new Composite("WINDOW窗口",ComponentType.WinForm); Component picture=new Leaf("LOGO窗口",ComponentType.Picture); Component button1=new Leaf("登录",ComponentType.Button); Component button2=new Leaf("注册",ComponentType.Button); Component frame=new Composite("FRAME1",ComponentType.Frame); Component lable1=new Leaf("用户名",ComponentType.Lable); Component textBox1=new Leaf("文本框",ComponentType.TextBox); Component lable2=new Leaf("密码",ComponentType.Lable); Component passwordBox=new Leaf("密码框",ComponentType.PasswordBox);; Component checkBox=new Leaf("复选框",ComponentType.CheckBox); Component textBox2=new Leaf("记住用户名",ComponentType.TextBox); Component linkLable=new Leaf("忘记密码",ComponentType.LinkLable); frame.add(lable1); frame.add(textBox1); frame.add(lable2); frame.add(passwordBox); frame.add(checkBox); frame.add(textBox2); frame.add(linkLable); winForm.add(picture); winForm.add(button1); winForm.add(button2); winForm.add(frame); winForm.print(); }}
复制代码
评论