如何用静态工厂方法创建抽象class?
How to create an abstract class with static factory method?
我有一个 "standard" JPanel
,里面有两个面板。我试图创建一种模板 class 然后扩展它并实现内容。问题是关于实现它的方式。
下面的代码是我试图让它工作的代码,但我刚刚开始阅读 Effective Java 一书,我不熟悉静态工厂方法。特意抽象出来。
我特别想遵循的书中的一些提示是
- 考虑静态工厂方法而不是构造函数
- 组合优于继承
- 比抽象更喜欢接口 classes
但我找不到关于这些点的好的解决方案(没有它们:P)。
public abstract class CentralPage {
static JPanel getInstance() {
JPanel container = new JPanel();
container.setBackground(Color.white);
container.setBorder(
BorderFactory.createCompoundBorder(new LineBorder(Color.BLACK), new EmptyBorder(10, 10, 10, 10)));
container.setMinimumSize(new Dimension(960, 400));
container.setPreferredSize(new Dimension(960, 400));
container.setLayout(new BoxLayout(container, BoxLayout.Y_AXIS));
JPanel up = getUp(container);
container.add(up);
JPanel down = getDown(container);
container.add(down);
return container;
}
abstract JPanel getDown(JPanel container);
abstract JPanel getUp(JPanel container);
}
如果您需要有关代码其他部分的更多信息,请随时询问。
一个Java静态方法不能抽象--再讨论here。
现在让我们分解你的构造:你的最终结果应该是一个 JPanel
和两个 children,还有 JPanels
,它们自己的构造取决于 parent JPanel
。您希望在静态工厂方法中完成此构造。
如果这是正确的,这可能是一个解决方案:
public interface UpDown{
public JPanel getUp(JPanel parent);
public JPanel getDown(JPanel parent);
}
public class CentralPage{
static JPanel getInstance(UpDown components){
JPanel container = new JPanel();
container.setBackground(Color.white);
container.setBorder(
BorderFactory.createCompoundBorder(new LineBorder(Color.BLACK), new EmptyBorder(10, 10, 10, 10)));
container.setMinimumSize(new Dimension(960, 400));
container.setPreferredSize(new Dimension(960, 400));
container.setLayout(new BoxLayout(container, BoxLayout.Y_AXIS));
JPanel up = components.getUp(container);
container.add(up);
JPanel down = components.getDown(container);
container.add(down);
return container;
}
}
另一种更接近您最初提议的解决方案是这样的:
public abstract class CentralPage{
private static CentralPage page;
protected JPanel container;
protected CentralPage(){
container = new JPanel();
container.setBackground(Color.white);
container.setBorder(
BorderFactory.createCompoundBorder(new LineBorder(Color.BLACK), new EmptyBorder(10, 10, 10, 10)));
container.setMinimumSize(new Dimension(960, 400));
container.setPreferredSize(new Dimension(960, 400));
container.setLayout(new BoxLayout(container, BoxLayout.Y_AXIS));
JPanel up = getUp(container);
container.add(up);
JPanel down = getDown(container);
container.add(down);
}
static JPanel getInstance(){
if(page==null){
page=new CentralPage();
}
return page.getContainer();
}
abstract JPanel getDown(JPanel container);
abstract JPanel getUp(JPanel container);
protected JPanel getContainer(){
return this.container;
}
}
这种(而不是 anti-pattern)方法的缺点是您需要记住在调用 super()
;
的具体 class 上创建一个构造函数
祝贺您阅读 "Effective Java" 并尝试将其付诸实践。它将为您的代码带来更多的可用性和清晰度。
现在,让我们看看:
1.In首先,如果你的抽象CentralPage
在构造的时候只需要两个Panel对象,最简单的方法就是一个非抽象class 在其构造函数中有两个参数:
public class CentralPage
{
public CentralPage(Panel up, Panel dn)
{
...
}
}
2.If,除了在构造时接收参数外,还有一些行为是 CentralPage
不知道的,必须在对象的生命周期内随时委托给第三方(在构造函数结束后),正确的模式将是 一个抽象 class,每个所需的行为都有一个抽象方法:
public abstract class CentralPage
{
protected CentralPage(...)
{
...
}
protected abstract return-type myBehaviour1(parameters...)
{
...
}
protected abstract return-type myBehaviour2(parameters...)
{
...
}
}
而且,当然,每个非抽象子class 必须提供实现其相应方法所需的每个行为。
3.Static 工厂方法针对非抽象 classes。它的目的是决定是否必须创建一个对象(也许可以重复使用现有对象,就像在单例模式中一样),并最终决定哪个class 必须实例化(可能是所有者 class 本身,或者可能是某个子class)。
我有一个 "standard" JPanel
,里面有两个面板。我试图创建一种模板 class 然后扩展它并实现内容。问题是关于实现它的方式。
下面的代码是我试图让它工作的代码,但我刚刚开始阅读 Effective Java 一书,我不熟悉静态工厂方法。特意抽象出来。
我特别想遵循的书中的一些提示是
- 考虑静态工厂方法而不是构造函数
- 组合优于继承
- 比抽象更喜欢接口 classes
但我找不到关于这些点的好的解决方案(没有它们:P)。
public abstract class CentralPage {
static JPanel getInstance() {
JPanel container = new JPanel();
container.setBackground(Color.white);
container.setBorder(
BorderFactory.createCompoundBorder(new LineBorder(Color.BLACK), new EmptyBorder(10, 10, 10, 10)));
container.setMinimumSize(new Dimension(960, 400));
container.setPreferredSize(new Dimension(960, 400));
container.setLayout(new BoxLayout(container, BoxLayout.Y_AXIS));
JPanel up = getUp(container);
container.add(up);
JPanel down = getDown(container);
container.add(down);
return container;
}
abstract JPanel getDown(JPanel container);
abstract JPanel getUp(JPanel container);
}
如果您需要有关代码其他部分的更多信息,请随时询问。
一个Java静态方法不能抽象--再讨论here。
现在让我们分解你的构造:你的最终结果应该是一个 JPanel
和两个 children,还有 JPanels
,它们自己的构造取决于 parent JPanel
。您希望在静态工厂方法中完成此构造。
如果这是正确的,这可能是一个解决方案:
public interface UpDown{
public JPanel getUp(JPanel parent);
public JPanel getDown(JPanel parent);
}
public class CentralPage{
static JPanel getInstance(UpDown components){
JPanel container = new JPanel();
container.setBackground(Color.white);
container.setBorder(
BorderFactory.createCompoundBorder(new LineBorder(Color.BLACK), new EmptyBorder(10, 10, 10, 10)));
container.setMinimumSize(new Dimension(960, 400));
container.setPreferredSize(new Dimension(960, 400));
container.setLayout(new BoxLayout(container, BoxLayout.Y_AXIS));
JPanel up = components.getUp(container);
container.add(up);
JPanel down = components.getDown(container);
container.add(down);
return container;
}
}
另一种更接近您最初提议的解决方案是这样的:
public abstract class CentralPage{
private static CentralPage page;
protected JPanel container;
protected CentralPage(){
container = new JPanel();
container.setBackground(Color.white);
container.setBorder(
BorderFactory.createCompoundBorder(new LineBorder(Color.BLACK), new EmptyBorder(10, 10, 10, 10)));
container.setMinimumSize(new Dimension(960, 400));
container.setPreferredSize(new Dimension(960, 400));
container.setLayout(new BoxLayout(container, BoxLayout.Y_AXIS));
JPanel up = getUp(container);
container.add(up);
JPanel down = getDown(container);
container.add(down);
}
static JPanel getInstance(){
if(page==null){
page=new CentralPage();
}
return page.getContainer();
}
abstract JPanel getDown(JPanel container);
abstract JPanel getUp(JPanel container);
protected JPanel getContainer(){
return this.container;
}
}
这种(而不是 anti-pattern)方法的缺点是您需要记住在调用 super()
;
祝贺您阅读 "Effective Java" 并尝试将其付诸实践。它将为您的代码带来更多的可用性和清晰度。
现在,让我们看看:
1.In首先,如果你的抽象CentralPage
在构造的时候只需要两个Panel对象,最简单的方法就是一个非抽象class 在其构造函数中有两个参数:
public class CentralPage
{
public CentralPage(Panel up, Panel dn)
{
...
}
}
2.If,除了在构造时接收参数外,还有一些行为是 CentralPage
不知道的,必须在对象的生命周期内随时委托给第三方(在构造函数结束后),正确的模式将是 一个抽象 class,每个所需的行为都有一个抽象方法:
public abstract class CentralPage
{
protected CentralPage(...)
{
...
}
protected abstract return-type myBehaviour1(parameters...)
{
...
}
protected abstract return-type myBehaviour2(parameters...)
{
...
}
}
而且,当然,每个非抽象子class 必须提供实现其相应方法所需的每个行为。
3.Static 工厂方法针对非抽象 classes。它的目的是决定是否必须创建一个对象(也许可以重复使用现有对象,就像在单例模式中一样),并最终决定哪个class 必须实例化(可能是所有者 class 本身,或者可能是某个子class)。