假设我有两个带有下游订阅(订阅者)的类
class A {
SubscriptionManager<A> subscriptionManager; // downstream subscriptions
void addSub(Subscription<A> sub){
subscriptionManager.addSub(sub);
}
}
class B {
SubscriptionManager<B> subscriptionManager; // downstream subscriptions
void addSub(Subscription<B> sub){
subscriptionManager.addSub(sub);
}
}
这是我要处理的问题,也是设计问题。我已经多次听说过通过继承进行构图,在这样的示例中,我可以创建一个抽象类,其中包含订阅管理器并具有添加和删除订阅者的功能。
但是,compoisiton over inheritance
使我不使用抽象类。我想知道这里正确的是什么?显然,您看到A, B
类中的任何一个都与整个add方法存在代码重复(将来可能还会重复)。
答案 0 :(得分:1)
您说对composition over inheritance是要牢记的重要原则,这是正确的;组合通常会更好,因为它可以为您提供更大的灵活性。
尽管如此,在我看来,抽象基类是合理的选择。考虑一下“是一个”问题:当一个类扩展到另一个类时,从子类到超类就会存在一个“是”关系。您的课程function loadRoute(json, map){
var markers = [];
var dd = [];
var color = [];
var jsonParse = JSON.parse(json);
var directionsDisplay = new google.maps.DirectionsRenderer;
var directionsService = new google.maps.DirectionsService;
for (var i = 0; i < jsonParse.length; i++){
var waypts = [];
waypts.push({
location: pos,
stopover: true
});
var posorigin = new google.maps.LatLng(jsonParse[i].latitudemin, jsonParse[i].longitudemin);
var posdestination = new google.maps.LatLng(jsonParse[i].latitude, jsonParse[i].longitude);
var lastupdate = jsonParse[i].ultimaposizione;
var content = jsonParse[i];
var icona = "https://img.icons8.com/color/administrator-male.png";
color[i] = jsonParse[i].color;
var markernew = new google.maps.Marker({
position: new google.maps.LatLng(jsonParse[i].latitude, jsonParse[i].longitude),
icon: icona,
lastupdate: lastupdate,
id: name,
title: name,
name: name,
map: map
});
markers.push(markernew);
directionsService.route({
'origin': parseFloat(jsonParse[i].latitudemin) + ',' + parseFloat(jsonParse[i].longitudemin),
'destination': parseFloat(jsonParse[i].latitude) + ',' + parseFloat(jsonParse[i].longitude),
'waypoints': waypts,
'optimizeWaypoints': true,
'travelMode': 'DRIVING'
},
function(directions, status) {
dd.push(new google.maps.DirectionsRenderer({
suppressInfoWindows: true,
suppressMarkers: true,
polylineOptions: {
strokeOpacity: 0.7,
strokeColor: color[dd.length]
},
map: map,
preserveViewport: true
}));
//dd.setMap(map);
if (status == google.maps.DirectionsStatus.OK) {
directionsDisplay = dd[dd.length - 1];
directionsDisplay.setDirections(directions);
}
}
);
}
var obj = {
markers: markers,
directions: directionsDisplay
};
return obj;
};
和A
都是您可以订阅的东西,因此B
是 A
。
Subscribable
我想知道这里正确吗?
这些是设计选择,几乎没有一个客观上正确的选择-每个设计选择都有其优点和缺点。
某些OO编程语言支持mixins,它可以帮助您通过合成而不是继承来实现类似的功能,但是Java对此的支持不是很好。
答案 1 :(得分:0)
您的示例不违反DRY原理。您只是使用一个承诺处理订阅的对象。它周围的薄层不会重复任何知识,而是在正确委派。
您可以采用的另一种方法是使您的客户(A和B)成为将产生SubscriptionManager的具体工厂。这样,他们的客户就可以直接与管理器进行交互,而您不必编写包装方法。
class A {
SubscriptionManager<A> subscriptionManager; // downstream subscriptions
/**
* There is some tension with Law of Demeter here,
* but these are the decisions you have to make as a designer.
*/
SubscriptionManager<A> subManager() {
//note: SubscriptionManager should be abstract to avoid tight coupling.
return subscriptionManager;
}
}