|
分類:[VB.NET/VB2005 以降]
こんにちは。
質問するのは初めてです。
是非皆様にご一緒にお考え頂きたく思いますので、
宜しくお願いいたします。
親子関係にあるクラスと、その親子関係をメメントするクラスが
多くあるプロジェクトについて
リファクタリングをしています。
この親子関係についてのコードの重複を避けようとすると、
どうしても「親から見た子」「子から見た親」について、
型の指定が抽象的になってきます。
質問は、
「今のコードよりももう少し厳密な型の指定ができそうな気がする
(そう思う根拠は曖昧です)し、そうしたいのだけれど、
どこまで厳密にできるかがわからないので、方法や妥協点をお教えください」
ということです。
その把握が困難なのは、
継承と包含の関係性がとても複雑な構造があるためです。
現在行っているのは、
http://www.adobe.com/devnet/illustrator/scripting/
ここにあるAdobe Illustrator のスクリプティングリファレンスを参考にした、
Adobe Illustratorの可能な限りの模倣です。
(最近知った言葉では、リバースエンジニアリングと言うらしいです。
法的にどうかという問題は、個人の趣味なので気にしていません)
複雑な構造は、この中の
「Document」
「Layer」
「PageItem」
「PathItem」
「CompoundPathItem」
「GroupItem」
についてです。
まず、この包含関係ですが、
Document => Layer
Layer => Layer,PageItem,GroupItem,PathItem,CompoundPathItem
GroupItem => PageItem,PathItem,CompoundPathItem
CompoundPathItem => PathItem
といった感じに、左のものは右のものを包含しています。
PageItemは抽象クラスで、
GroupItem,PathItem,CompoundPathItemはその派生クラスだろうと
考えています。
このアプリケーションがC++で作られていることから、
VB使いの僕にはこの構造がどのように実現されているか
多重継承などのVBにない機能がわからないために考慮しきれませんが、
自分なりにVBでの実現するための継承関係として、以下のように考えました。
(ApplicationItem)★
Document
(LayerItem)★
Layer
PageItem★
GroupItem
CompoundPathItem
PathItem
(インデントがスーパーとサブの関係を表します)
(括弧で括られたものはリファレンスにはない)
(★は抽象クラス)
次は自分のやりたいことです。
まず、以下のようにコレクションを持たせたいです。
Document =>Layer
Layer =>LayerItem
GroupItem =>PageItem
CompoundPathItem=>PathItem
(左のオブジェクトは右のオブジェクトのコレクションをメンバに持つ)
親子関係は、できれば以下のような感じに
ApplicationItem内に一本化させたいです。
理由は、親子関係とメメントを汎化させたい構造が
今挙げた以外にもたくさんあり、使いまわしたいからです。
(コードはイメージです。実際はもっと長ったらしいです)
MustInherit Class ApplicationItem
Private myParent As 親コレクションの型
Public ReadOnly Property Parent As myParentの親の型
'myParentの親を返したい
End Property
Protected Sub New(ByVal Parent As 親コレクションの型)
Me.myParent = Parent
End Sub
Public Class ApplicationItemCollection(Of C As ApplicationItem)
Inherits CollectionBase
Private myParent As 親の型
Public Sub New(Parent As 親の型)
Me.myParent = Parent
End Sub
Public Class MementOfParent
Private myParent As 親コレクションの型
Private myIndex As integer
Private myTarget As ApplicationItem
End Class
End Class
ApplicationItemのコンストラクタは、こんなイメージで呼び出されます。
Class GroupItem
Inherits PageItem
Public Class GroupItemWrappedCollection
Private myCollection As ApplicationItemCollection(Of PageItem)
Public Sub New(Collection As ApplicationItemCollection(Of PageItem)
Me.myCollection = Collection
End Sub
Public Function Add()As GroupItem
Dim Result As New GroupItem(myCollection)
myCollection.Add(Result)
Return Result
End Function
End Class
End Class
しかし、現状は以下のようなザマです。
MustInherit Class ApplicationItem
Private myParent As ApplicationItemCollection
Public ReadOnly Property Parent As Object
Get
Return myParent.Parent
End Get
End Property
Protected Sub New(ByVal Parent As ApplicationItemCollection)
Me.myParent = Parent
End Sub
Public Class ApplicationItemCollection
Inherits CollectionBase
Private myParent As Object
Public ReadOnly Property Parent As Object
Get
Return myParent
End Get
End Property
Public Sub New(Parent As Object)
If Parent Is Nothing Then Throw New Exception("ダメ")
Me.myParent = Parent
End Sub
Public Class MementOfParent
Private myParent As ApplicationItemCollection
Private myIndex As integer
Private myTarget As ApplicationItem
End Class
End Class
Class GroupItem
Inherits PageItem
Public Class GroupItemWrappedCollection
Private myCollection As ApplicationItemCollection
Public Sub New(Collection As ApplicationItemCollection)
Me.myCollection = Collection
End Sub
Public Function Add()As GroupItem
Dim Result As New GroupItem(myCollection)
myCollection.Add(Result)
Return Result
End Function
End Class
End Class
そして、以下のようにコレクションを持っています
Document =>ApplicationItemCollection
Layer =>ApplicationItemCollection
GroupItem =>ApplicationItemCollection
CompoundPathItem=>ApplicationItemCollection
これらのコレクションをメンバに持つオブジェクトは、
コレクションを外部に直接公開するのでなく
GroupItemWrappedCollectionのように、
ApplicationItemCollectionをラップして公開するので、
コレクションにオブジェクトモデルに即さない型のオブジェクトが
入ることはないとは思うのですが、
現状の抽象的な型指定が腑に落ちません。
なんとかできそうでしょうか?
宜しくお願いいたします。
(返事は遅いので、あらかじめご容赦ください。)
|