设计模式之单例模式和组合模式

发布于: 16 小时前

单例模式

什么是单例

一个类只允许创建一个实例,这个类就是单例类,这种设计,则为单例模式。

先上个简单的手写单例:

单例有哪些思考点

注:这里的讨论都是java为例。

1 如何确保一个类只创建一个实例;

单例类的构造函数必须是私有的,然后通过一个静态方法提供单实例。但是这样仍然无法完全避免创建多个实例,因为可以通过反射创建多个实例。这可以通过在构造函数里添加实例是否已创建判断解决。

2 什么时候创建实例;

一种是类加加载初始化时就创建实例;一种是延时创建,使用时再创建。

对于延时加载,可以在getInstance()方法中创建实例。这里需要考虑多线程形式下,有可能会创建多个实例,因而需要加锁,来避免创建冲突。因为单例只需要创建一次,其他的就是读取单例,因此,getInstance()方法中读多写少,如果整个方法都锁住,那代码效率会很低,因而进一步优化,先判断是否已有实例,没有的情况下再加锁,锁内再判断,没有实例时再创建实例。

为了类实例延时创建,又不加锁,可以考虑内部类,或内部枚举类。

组合模式

什么是组合模式

组织模式,是将一组对象组织成树形结构,以表示一种“部分-整体”的层次结构;组合让客户端可以统一单个对象和组合对象的处理逻辑。

组织模式案例

使用组合设计模式编写程序,打印输出图1的窗口。窗口组件的树结构如图2所示,打印输出示例如图3。

代码如下:

Component.java

public abstract class Component {
protected String type;
protected String name;
public Component(String type, String name) {
this.type = type;
this.name = name;
}
public void print() {
StringBuilder builder = new StringBuilder();
builder.append("print ").append(type).append("(").append(name).append(")");
System.out.println(builder.toString());
}
}

Container.java

public abstract class Container extends Component {
private List<Component> components;
public Container(String type, String name) {
super(type, name);
components = new ArrayList<>();
}
public void addComponent(Component component) {
components.add(component);
}
@Override
public void print() {
super.print();
for (Component component : components) {
component.print();
}
}
}

WinForm.java (Frame代码类似)

public class WinForm extends Container {
public WinForm(String name) {
super("WinForm", name);
}
}

Button.java (其他组件的代码类似)

public class Button extends Component {
public Button(String name) {
super("Button", name);
}
}

Main方法如下:

public static void main(String[] args) {
WinForm winForm = new WinForm("WINDOW窗口");
winForm.addComponent(new Picture("LOGO图片"));
winForm.addComponent(new Button("登录"));
winForm.addComponent(new Button("注册"));
Frame frame = new Frame("FRAME1");
frame.addComponent(new Label("用户名"));
frame.addComponent(new TextBox("文本框"));
frame.addComponent(new Label("密码"));
frame.addComponent(new PasswordBox("密码框"));
frame.addComponent(new CheckBox("复选框"));
frame.addComponent(new TextBox("记住用户名"));
frame.addComponent(new LinkLabel("忘记密码"));
winForm.addComponent(frame);
winForm.print();
}

代码输出结果如下:

用户头像

dapaul

关注

还未添加个人签名 2018.09.18 加入

还未添加个人简介

评论

发布
暂无评论
设计模式之单例模式和组合模式